mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import React from 'react'
2import {
3 StyleProp,
4 StyleSheet,
5 TextInput,
6 TouchableOpacity,
7 View,
8 ViewStyle,
9} from 'react-native'
10import {
11 FontAwesomeIcon,
12 FontAwesomeIconStyle,
13} from '@fortawesome/react-native-fontawesome'
14import {HITSLOP_10} from 'lib/constants'
15import {MagnifyingGlassIcon} from 'lib/icons'
16import {useTheme} from 'lib/ThemeContext'
17import {usePalette} from 'lib/hooks/usePalette'
18import {useLingui} from '@lingui/react'
19import {msg} from '@lingui/macro'
20
21interface Props {
22 query: string
23 setIsInputFocused?: (v: boolean) => void
24 onChangeQuery: (v: string) => void
25 onPressCancelSearch: () => void
26 onSubmitQuery: () => void
27 style?: StyleProp<ViewStyle>
28}
29
30export interface SearchInputRef {
31 focus?: () => void
32}
33
34export const SearchInput = React.forwardRef<SearchInputRef, Props>(
35 function SearchInput(
36 {
37 query,
38 setIsInputFocused,
39 onChangeQuery,
40 onPressCancelSearch,
41 onSubmitQuery,
42 style,
43 },
44 ref,
45 ) {
46 const theme = useTheme()
47 const pal = usePalette('default')
48 const {_} = useLingui()
49 const textInput = React.useRef<TextInput>(null)
50
51 const onPressCancelSearchInner = React.useCallback(() => {
52 onPressCancelSearch()
53 textInput.current?.blur()
54 }, [onPressCancelSearch, textInput])
55
56 React.useImperativeHandle(ref, () => ({
57 focus: () => textInput.current?.focus(),
58 blur: () => textInput.current?.blur(),
59 }))
60
61 return (
62 <View style={[pal.viewLight, styles.container, style]}>
63 <MagnifyingGlassIcon style={[pal.icon, styles.icon]} size={21} />
64 <TextInput
65 testID="searchTextInput"
66 ref={textInput}
67 placeholder={_(msg`Search`)}
68 placeholderTextColor={pal.colors.textLight}
69 selectTextOnFocus
70 returnKeyType="search"
71 value={query}
72 style={[pal.text, styles.input]}
73 keyboardAppearance={theme.colorScheme}
74 onFocus={() => setIsInputFocused?.(true)}
75 onBlur={() => setIsInputFocused?.(false)}
76 onChangeText={onChangeQuery}
77 onSubmitEditing={onSubmitQuery}
78 accessibilityRole="search"
79 accessibilityLabel={_(msg`Search`)}
80 accessibilityHint=""
81 autoCorrect={false}
82 autoCapitalize="none"
83 />
84 {query ? (
85 <TouchableOpacity
86 onPress={onPressCancelSearchInner}
87 accessibilityRole="button"
88 accessibilityLabel={_(msg`Clear search query`)}
89 accessibilityHint=""
90 hitSlop={HITSLOP_10}>
91 <FontAwesomeIcon
92 icon="xmark"
93 size={16}
94 style={pal.textLight as FontAwesomeIconStyle}
95 />
96 </TouchableOpacity>
97 ) : undefined}
98 </View>
99 )
100 },
101)
102
103const styles = StyleSheet.create({
104 container: {
105 flex: 1,
106 flexDirection: 'row',
107 alignItems: 'center',
108 borderRadius: 30,
109 paddingHorizontal: 12,
110 paddingVertical: 8,
111 },
112 icon: {
113 marginRight: 6,
114 alignSelf: 'center',
115 },
116 input: {
117 flex: 1,
118 fontSize: 17,
119 minWidth: 0, // overflow mitigation for firefox
120 },
121 cancelBtn: {
122 paddingLeft: 10,
123 },
124})