Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add basic search bar for search screen #96

Merged
merged 16 commits into from
Dec 30, 2020
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -408,4 +408,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 6e9396fa3f617dd06d3083a586de30fc1336a5cf

COCOAPODS: 1.9.3
COCOAPODS: 1.10.0
7 changes: 4 additions & 3 deletions src/components/BackButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type BackButtonProps = {
/**
* Value back button should display
*/
label?: string,
label?: string | JSX.Element,
} & Omit<TouchableOpacityProps, 'onPress' | 'children'>

const styles = StyleSheet.create( {
Expand All @@ -19,14 +19,15 @@ const styles = StyleSheet.create( {
},
} )

const BackButton = ( { label = 'Cancel', ...props }: BackButtonProps ) => {
const BackButton = ( { label: Label = 'Cancel', ...props }: BackButtonProps ) => {
const navigation = useNavigation()

const goBack = () => navigation.goBack()

return (
<TouchableOpacity onPress={goBack} {...props}>
<Text style={styles.label}>{label}</Text>
{Label && <Text style={styles.label}>{Label}</Text>}
{!Label && <Label />}
saihaj marked this conversation as resolved.
Show resolved Hide resolved
</TouchableOpacity>
)
}
Expand Down
45 changes: 0 additions & 45 deletions src/components/Search.spec.tsx

This file was deleted.

74 changes: 0 additions & 74 deletions src/components/Search.tsx

This file was deleted.

19 changes: 19 additions & 0 deletions src/components/Search/Bar.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'react-native'
import React from 'react'
import { render, fireEvent } from '@testing-library/react-native'

import SearchBar from './Bar'

describe( '<Search />', () => {
it( 'should handle user text input', () => {
const onEventMock = jest.fn()

const { getByPlaceholderText } = render(
<SearchBar onChangeText={onEventMock} />,
)

fireEvent.changeText( getByPlaceholderText( 'Search' ), 'Test Input' )

expect( onEventMock ).toHaveBeenCalledWith( 'Test Input' )
} )
} )
52 changes: 52 additions & 0 deletions src/components/Search/Bar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { forwardRef } from 'react'
import { View, StyleSheet, TextInput } from 'react-native'
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'

import { OS } from '../../lib/consts'
import Colours from '../../themes/colours'
import { my } from '../../themes/utils'

const styles = StyleSheet.create( {
searchBar: {
...( OS.android && { paddingLeft: 10 } ),
...( OS.ios && { padding: 10 } ),
flexDirection: 'row',
borderRadius: 10,
backgroundColor: Colours.DarkGray,
},
searchIcon: {
...my,
},
searchInputBox: {
flex: 1,
fontSize: 22,
marginLeft: 5,
...my,
},
} )

type SearchBarProps = {
onChangeText: ( t: string ) => void,
}

const SearchBar = forwardRef<TextInput, SearchBarProps>(
( { onChangeText }: SearchBarProps, ref ) => (
saihaj marked this conversation as resolved.
Show resolved Hide resolved
<View style={styles.searchBar}>

<Icon name="magnify" size={25} style={styles.searchIcon} />

<TextInput
ref={ref}
placeholder="Search"
style={styles.searchInputBox}
clearButtonMode="always"
autoCorrect={false}
autoCapitalize="none"
onChangeText={onChangeText}
/>

</View>
),
)

export default SearchBar
1 change: 1 addition & 0 deletions src/components/Search/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as SearchBar } from './Bar'
51 changes: 41 additions & 10 deletions src/screens/SearchScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
import React, { useState } from 'react'
import { StyleSheet, View } from 'react-native'
import React, { useRef, useState } from 'react'
import { StyleSheet, View, TextInput } from 'react-native'
import AntIcon from 'react-native-vector-icons/AntDesign'
import EntypoIcon from 'react-native-vector-icons/Entypo'
import { TouchableOpacity } from 'react-native-gesture-handler'

import SearchBar from '../components/Search'
import { SearchBar } from '../components/Search'
saihaj marked this conversation as resolved.
Show resolved Hide resolved
import BackButton from '../components/BackButton'
import Container from '../components/Container'
import Colours from '../themes/colours'
import { mx } from '../themes/utils'
import { my } from '../themes/utils'
import { OS } from '../lib/consts'

const styles = StyleSheet.create( {
backButton: {
...mx,
...my,
},
clearButton: {
...my,
marginLeft: -30,
},
searchBar: {
flex: 0.95,
},
searchInput: {
flex: 1,
flexDirection: 'row',
},
searchStrip: {
paddingTop: 15,
paddingBottom: 25,
Expand All @@ -24,21 +36,40 @@ const styles = StyleSheet.create( {
} )

const SearchScreen = () => {
const [ , setSearch ] = useState( '' )
const [ searchValue, setSearch ] = useState( '' )
const [ , setPageCount ] = useState( 0 )
const searchInputRef = useRef<TextInput>( null )

const handleTextChange = ( v: string ) => {
setSearch( v )
setPageCount( 0 )
}

const clearInput = () => {
saihaj marked this conversation as resolved.
Show resolved Hide resolved
searchInputRef.current?.clear()
setSearch( '' )
}
return (
<Container statusBarColor={Colours.MediumGray}>
<View style={styles.searchStrip}>
<View style={styles.searchBar}>
<SearchBar onChangeText={handleTextChange} />

<BackButton label={<AntIcon name="arrowleft" size={24} />} style={styles.backButton} />

<View style={styles.searchInput}>

<View style={styles.searchBar}>
<SearchBar ref={searchInputRef} onChangeText={handleTextChange} />
</View>

{OS.android && ( searchValue.length > 1 ) && (
saihaj marked this conversation as resolved.
Show resolved Hide resolved
<View style={styles.clearButton}>
<TouchableOpacity onPress={clearInput}>
<EntypoIcon name="circle-with-cross" size={17} />
</TouchableOpacity>
</View>
Harjot1Singh marked this conversation as resolved.
Show resolved Hide resolved
)}

</View>
<BackButton style={styles.backButton} />

</View>
</Container>
)
Expand Down
19 changes: 19 additions & 0 deletions src/themes/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { px, py } from './utils'

describe( 'Styling Utilities', () => {
it( 'should have paddingBottom and paddingTop set to auto', () => {
expect( py() ).toStrictEqual( { paddingTop: 'auto', paddingBottom: 'auto' } )
saihaj marked this conversation as resolved.
Show resolved Hide resolved
} )

it( 'should have paddingBottom and paddingTop set to 10', () => {
expect( py( 10 ) ).toStrictEqual( { paddingTop: 10, paddingBottom: 10 } )
} )

it( 'should have paddingLeft and paddingRight set to auto', () => {
expect( px() ).toStrictEqual( { paddingLeft: 'auto', paddingRight: 'auto' } )
} )

it( 'should have paddingLeft and paddingRight set to 10', () => {
expect( px( 10 ) ).toStrictEqual( { paddingLeft: 10, paddingRight: 10 } )
} )
} )
28 changes: 27 additions & 1 deletion src/themes/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
/**
* Set Top and Bottom margin to auto
*/
export const mx = {
export const my = {
marginTop: 'auto',
marginBottom: 'auto',
}

/**
* Set Left and Right padding to given value.
* Default: 'auto'
*/
export const px = ( value: number|string = 'auto' ) => ( {
paddingLeft: value,
paddingRight: value,
} )

/**
* Set Top and Bottom padding to given value.
* Default: 'auto'
*/
export const py = ( value: number|string = 'auto' ) => ( {
paddingTop: value,
paddingBottom: value,
} )

/**
* Only for development purposes
*/
export const debugBorder = {
borderWidth: 2,
borderColor: 'black',
}