forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {useEffect, useRef} from 'react'
2import {type TextInput, View} from 'react-native'
3import {useLingui} from '@lingui/react/macro'
4
5import {HITSLOP_10} from '#/lib/constants'
6import {mergeRefs} from '#/lib/merge-refs'
7import {listenFocusSearch} from '#/state/events'
8import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
9import {atoms as a, useTheme} from '#/alf'
10import {Button, ButtonIcon} from '#/components/Button'
11import * as TextField from '#/components/forms/TextField'
12import {MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlassIcon} from '#/components/icons/MagnifyingGlass'
13import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
14import {IS_NATIVE} from '#/env'
15
16type Props = Omit<TextField.InputProps, 'label'> & {
17 label?: TextField.InputProps['label']
18 /**
19 * Called when the user presses the (X) button
20 */
21 onClearText?: () => void
22 hotkey?: boolean
23 ref?: React.Ref<TextInput>
24}
25
26export function SearchInput({
27 value,
28 label,
29 onClearText,
30 hotkey,
31 ref,
32 ...rest
33}: Props) {
34 const t = useTheme()
35 const {t: l} = useLingui()
36 const showClear = value && value.length > 0
37 const internalRef = useRef<TextInput>(null)
38
39 useEffect(() => {
40 if (!hotkey) return
41 return listenFocusSearch(() => {
42 internalRef.current?.focus()
43 })
44 }, [hotkey])
45
46 const enableSquareButtons = useEnableSquareButtons()
47
48 return (
49 <View style={[a.w_full, a.relative]}>
50 <TextField.Root>
51 <TextField.Icon icon={MagnifyingGlassIcon} />
52 <TextField.Input
53 inputRef={mergeRefs([internalRef, ref])}
54 label={label || l`Search`}
55 value={value}
56 placeholder={l`Search`}
57 returnKeyType="search"
58 keyboardAppearance={t.scheme}
59 selectTextOnFocus={IS_NATIVE}
60 autoFocus={false}
61 accessibilityRole="search"
62 autoCorrect={false}
63 autoComplete="off"
64 autoCapitalize="none"
65 style={[
66 showClear
67 ? {
68 paddingRight: 24,
69 }
70 : {},
71 ]}
72 {...rest}
73 />
74 </TextField.Root>
75
76 {showClear && (
77 <View
78 style={[
79 a.absolute,
80 a.z_20,
81 a.my_auto,
82 a.inset_0,
83 a.justify_center,
84 a.pr_sm,
85 {left: 'auto'},
86 ]}>
87 <Button
88 testID="searchTextInputClearBtn"
89 onPress={onClearText}
90 label={l`Clear search query`}
91 hitSlop={HITSLOP_10}
92 size="tiny"
93 shape={enableSquareButtons ? 'square' : 'round'}
94 variant="ghost"
95 color="secondary">
96 <ButtonIcon icon={X} size="xs" />
97 </Button>
98 </View>
99 )}
100 </View>
101 )
102}