Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
119
fork

Configure Feed

Select the types of activity you want to include in your feed.

at a876aae44ea07494ebea9727350aa060b81f317b 102 lines 2.8 kB view raw
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}