ALF text input for generic search input (#5511)
* alf text input for generic search input * clearer ref naming * Adjust props and definition * Migrate props * Migrate props * Migrate props * Replace on search screen * rm old props --------- Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
@@ -0,0 +1,75 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {TextInput, View} from 'react-native'
|
||||||
|
import {msg} from '@lingui/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
|
import {HITSLOP_10} from '#/lib/constants'
|
||||||
|
import {isNative} from '#/platform/detection'
|
||||||
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
|
import {Button, ButtonIcon} from '#/components/Button'
|
||||||
|
import * as TextField from '#/components/forms/TextField'
|
||||||
|
import {MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlassIcon} from '#/components/icons/MagnifyingGlass2'
|
||||||
|
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
||||||
|
|
||||||
|
type SearchInputProps = Omit<TextField.InputProps, 'label'> & {
|
||||||
|
label?: TextField.InputProps['label']
|
||||||
|
/**
|
||||||
|
* Called when the user presses the (X) button
|
||||||
|
*/
|
||||||
|
onClearText?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SearchInput = React.forwardRef<TextInput, SearchInputProps>(
|
||||||
|
function SearchInput({value, label, onClearText, ...rest}, ref) {
|
||||||
|
const t = useTheme()
|
||||||
|
const {_} = useLingui()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[a.w_full, a.relative]}>
|
||||||
|
<TextField.Root>
|
||||||
|
<TextField.Icon icon={MagnifyingGlassIcon} />
|
||||||
|
<TextField.Input
|
||||||
|
inputRef={ref}
|
||||||
|
label={label || _(msg`Search`)}
|
||||||
|
value={value}
|
||||||
|
placeholder={_(msg`Search`)}
|
||||||
|
returnKeyType="search"
|
||||||
|
keyboardAppearance={t.scheme}
|
||||||
|
selectTextOnFocus={isNative}
|
||||||
|
autoFocus={false}
|
||||||
|
accessibilityRole="search"
|
||||||
|
autoCorrect={false}
|
||||||
|
autoComplete="off"
|
||||||
|
autoCapitalize="none"
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
</TextField.Root>
|
||||||
|
|
||||||
|
{value && value.length > 0 && (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.absolute,
|
||||||
|
a.z_10,
|
||||||
|
a.my_auto,
|
||||||
|
a.inset_0,
|
||||||
|
a.justify_center,
|
||||||
|
a.pr_sm,
|
||||||
|
{left: 'auto'},
|
||||||
|
]}>
|
||||||
|
<Button
|
||||||
|
testID="searchTextInputClearBtn"
|
||||||
|
onPress={onClearText}
|
||||||
|
label={_(msg`Clear search query`)}
|
||||||
|
hitSlop={HITSLOP_10}
|
||||||
|
size="tiny"
|
||||||
|
shape="round"
|
||||||
|
variant="ghost"
|
||||||
|
color="secondary">
|
||||||
|
<ButtonIcon icon={X} size="xs" />
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
@@ -126,7 +126,7 @@ export type InputProps = Omit<TextInputProps, 'value' | 'onChangeText'> & {
|
|||||||
value?: string
|
value?: string
|
||||||
onChangeText?: (value: string) => void
|
onChangeText?: (value: string) => void
|
||||||
isInvalid?: boolean
|
isInvalid?: boolean
|
||||||
inputRef?: React.RefObject<TextInput>
|
inputRef?: React.RefObject<TextInput> | React.ForwardedRef<TextInput>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createInput(Component: typeof TextInput) {
|
export function createInput(Component: typeof TextInput) {
|
||||||
|
|||||||
@@ -4,17 +4,17 @@ import {KeyboardAwareScrollView} from 'react-native-keyboard-controller'
|
|||||||
import {AppBskyFeedDefs, ModerationOpts} from '@atproto/api'
|
import {AppBskyFeedDefs, ModerationOpts} from '@atproto/api'
|
||||||
import {Trans} from '@lingui/macro'
|
import {Trans} from '@lingui/macro'
|
||||||
|
|
||||||
|
import {DISCOVER_FEED_URI} from '#/lib/constants'
|
||||||
import {useA11y} from '#/state/a11y'
|
import {useA11y} from '#/state/a11y'
|
||||||
import {DISCOVER_FEED_URI} from 'lib/constants'
|
|
||||||
import {
|
import {
|
||||||
useGetPopularFeedsQuery,
|
useGetPopularFeedsQuery,
|
||||||
usePopularFeedsSearch,
|
usePopularFeedsSearch,
|
||||||
useSavedFeeds,
|
useSavedFeeds,
|
||||||
} from 'state/queries/feed'
|
} from '#/state/queries/feed'
|
||||||
import {SearchInput} from 'view/com/util/forms/SearchInput'
|
import {List} from '#/view/com/util/List'
|
||||||
import {List} from 'view/com/util/List'
|
|
||||||
import {useWizardState} from '#/screens/StarterPack/Wizard/State'
|
import {useWizardState} from '#/screens/StarterPack/Wizard/State'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
|
import {SearchInput} from '#/components/forms/SearchInput'
|
||||||
import {useThrottledValue} from '#/components/hooks/useThrottledValue'
|
import {useThrottledValue} from '#/components/hooks/useThrottledValue'
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import {ScreenTransition} from '#/components/StarterPack/Wizard/ScreenTransition'
|
import {ScreenTransition} from '#/components/StarterPack/Wizard/ScreenTransition'
|
||||||
@@ -81,12 +81,11 @@ export function StepFeeds({moderationOpts}: {moderationOpts: ModerationOpts}) {
|
|||||||
return (
|
return (
|
||||||
<ScreenTransition style={[a.flex_1]} direction={state.transitionDirection}>
|
<ScreenTransition style={[a.flex_1]} direction={state.transitionDirection}>
|
||||||
<View style={[a.border_b, t.atoms.border_contrast_medium]}>
|
<View style={[a.border_b, t.atoms.border_contrast_medium]}>
|
||||||
<View style={[a.my_sm, a.px_md, {height: 40}]}>
|
<View style={[a.py_sm, a.px_md, {height: 60}]}>
|
||||||
<SearchInput
|
<SearchInput
|
||||||
query={query}
|
value={query}
|
||||||
onChangeQuery={t => setQuery(t)}
|
onChangeText={t => setQuery(t)}
|
||||||
onPressCancelSearch={() => setQuery('')}
|
onClearText={() => setQuery('')}
|
||||||
onSubmitQuery={() => {}}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@@ -94,7 +93,6 @@ export function StepFeeds({moderationOpts}: {moderationOpts: ModerationOpts}) {
|
|||||||
data={query ? searchedFeeds : suggestedFeeds}
|
data={query ? searchedFeeds : suggestedFeeds}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
keyExtractor={keyExtractor}
|
keyExtractor={keyExtractor}
|
||||||
contentContainerStyle={{paddingTop: 6}}
|
|
||||||
onEndReached={
|
onEndReached={
|
||||||
!query && !screenReaderEnabled ? () => fetchNextPage() : undefined
|
!query && !screenReaderEnabled ? () => fetchNextPage() : undefined
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ import {KeyboardAwareScrollView} from 'react-native-keyboard-controller'
|
|||||||
import {AppBskyActorDefs, ModerationOpts} from '@atproto/api'
|
import {AppBskyActorDefs, ModerationOpts} from '@atproto/api'
|
||||||
import {Trans} from '@lingui/macro'
|
import {Trans} from '@lingui/macro'
|
||||||
|
|
||||||
|
import {isNative} from '#/platform/detection'
|
||||||
import {useA11y} from '#/state/a11y'
|
import {useA11y} from '#/state/a11y'
|
||||||
import {isNative} from 'platform/detection'
|
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
||||||
import {useActorAutocompleteQuery} from 'state/queries/actor-autocomplete'
|
import {useActorSearchPaginated} from '#/state/queries/actor-search'
|
||||||
import {useActorSearchPaginated} from 'state/queries/actor-search'
|
import {List} from '#/view/com/util/List'
|
||||||
import {SearchInput} from 'view/com/util/forms/SearchInput'
|
|
||||||
import {List} from 'view/com/util/List'
|
|
||||||
import {useWizardState} from '#/screens/StarterPack/Wizard/State'
|
import {useWizardState} from '#/screens/StarterPack/Wizard/State'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
|
import {SearchInput} from '#/components/forms/SearchInput'
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import {ScreenTransition} from '#/components/StarterPack/Wizard/ScreenTransition'
|
import {ScreenTransition} from '#/components/StarterPack/Wizard/ScreenTransition'
|
||||||
import {WizardProfileCard} from '#/components/StarterPack/Wizard/WizardListCard'
|
import {WizardProfileCard} from '#/components/StarterPack/Wizard/WizardListCard'
|
||||||
@@ -65,12 +65,11 @@ export function StepProfiles({
|
|||||||
return (
|
return (
|
||||||
<ScreenTransition style={[a.flex_1]} direction={state.transitionDirection}>
|
<ScreenTransition style={[a.flex_1]} direction={state.transitionDirection}>
|
||||||
<View style={[a.border_b, t.atoms.border_contrast_medium]}>
|
<View style={[a.border_b, t.atoms.border_contrast_medium]}>
|
||||||
<View style={[a.my_sm, a.px_md, {height: 40}]}>
|
<View style={[a.py_sm, a.px_md, {height: 60}]}>
|
||||||
<SearchInput
|
<SearchInput
|
||||||
query={query}
|
value={query}
|
||||||
onChangeQuery={setQuery}
|
onChangeText={setQuery}
|
||||||
onPressCancelSearch={() => setQuery('')}
|
onClearText={() => setQuery('')}
|
||||||
onSubmitQuery={() => {}}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {
|
|
||||||
StyleProp,
|
|
||||||
StyleSheet,
|
|
||||||
TextInput,
|
|
||||||
TouchableOpacity,
|
|
||||||
View,
|
|
||||||
ViewStyle,
|
|
||||||
} from 'react-native'
|
|
||||||
import {
|
|
||||||
FontAwesomeIcon,
|
|
||||||
FontAwesomeIconStyle,
|
|
||||||
} from '@fortawesome/react-native-fontawesome'
|
|
||||||
import {HITSLOP_10} from 'lib/constants'
|
|
||||||
import {MagnifyingGlassIcon} from 'lib/icons'
|
|
||||||
import {useTheme} from 'lib/ThemeContext'
|
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {useLingui} from '@lingui/react'
|
|
||||||
import {msg} from '@lingui/macro'
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
query: string
|
|
||||||
setIsInputFocused?: (v: boolean) => void
|
|
||||||
onChangeQuery: (v: string) => void
|
|
||||||
onPressCancelSearch: () => void
|
|
||||||
onSubmitQuery: () => void
|
|
||||||
style?: StyleProp<ViewStyle>
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchInputRef {
|
|
||||||
focus?: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SearchInput = React.forwardRef<SearchInputRef, Props>(
|
|
||||||
function SearchInput(
|
|
||||||
{
|
|
||||||
query,
|
|
||||||
setIsInputFocused,
|
|
||||||
onChangeQuery,
|
|
||||||
onPressCancelSearch,
|
|
||||||
onSubmitQuery,
|
|
||||||
style,
|
|
||||||
},
|
|
||||||
ref,
|
|
||||||
) {
|
|
||||||
const theme = useTheme()
|
|
||||||
const pal = usePalette('default')
|
|
||||||
const {_} = useLingui()
|
|
||||||
const textInput = React.useRef<TextInput>(null)
|
|
||||||
|
|
||||||
const onPressCancelSearchInner = React.useCallback(() => {
|
|
||||||
onPressCancelSearch()
|
|
||||||
textInput.current?.blur()
|
|
||||||
}, [onPressCancelSearch, textInput])
|
|
||||||
|
|
||||||
React.useImperativeHandle(ref, () => ({
|
|
||||||
focus: () => textInput.current?.focus(),
|
|
||||||
blur: () => textInput.current?.blur(),
|
|
||||||
}))
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={[pal.viewLight, styles.container, style]}>
|
|
||||||
<MagnifyingGlassIcon style={[pal.icon, styles.icon]} size={21} />
|
|
||||||
<TextInput
|
|
||||||
testID="searchTextInput"
|
|
||||||
ref={textInput}
|
|
||||||
placeholder={_(msg`Search`)}
|
|
||||||
placeholderTextColor={pal.colors.textLight}
|
|
||||||
selectTextOnFocus
|
|
||||||
returnKeyType="search"
|
|
||||||
value={query}
|
|
||||||
style={[pal.text, styles.input]}
|
|
||||||
keyboardAppearance={theme.colorScheme}
|
|
||||||
onFocus={() => setIsInputFocused?.(true)}
|
|
||||||
onBlur={() => setIsInputFocused?.(false)}
|
|
||||||
onChangeText={onChangeQuery}
|
|
||||||
onSubmitEditing={onSubmitQuery}
|
|
||||||
accessibilityRole="search"
|
|
||||||
accessibilityLabel={_(msg`Search`)}
|
|
||||||
accessibilityHint=""
|
|
||||||
autoCorrect={false}
|
|
||||||
autoCapitalize="none"
|
|
||||||
/>
|
|
||||||
{query ? (
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={onPressCancelSearchInner}
|
|
||||||
accessibilityRole="button"
|
|
||||||
accessibilityLabel={_(msg`Clear search query`)}
|
|
||||||
accessibilityHint=""
|
|
||||||
hitSlop={HITSLOP_10}>
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon="xmark"
|
|
||||||
size={16}
|
|
||||||
style={pal.textLight as FontAwesomeIconStyle}
|
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
|
||||||
) : undefined}
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
borderRadius: 30,
|
|
||||||
paddingHorizontal: 12,
|
|
||||||
paddingVertical: 8,
|
|
||||||
},
|
|
||||||
icon: {
|
|
||||||
marginRight: 6,
|
|
||||||
alignSelf: 'center',
|
|
||||||
},
|
|
||||||
input: {
|
|
||||||
flex: 1,
|
|
||||||
fontSize: 17,
|
|
||||||
minWidth: 0, // overflow mitigation for firefox
|
|
||||||
},
|
|
||||||
cancelBtn: {
|
|
||||||
paddingLeft: 10,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
+20
-19
@@ -6,6 +6,12 @@ import {useLingui} from '@lingui/react'
|
|||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
import debounce from 'lodash.debounce'
|
import debounce from 'lodash.debounce'
|
||||||
|
|
||||||
|
import {usePalette} from '#/lib/hooks/usePalette'
|
||||||
|
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||||
|
import {ComposeIcon2} from '#/lib/icons'
|
||||||
|
import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
|
||||||
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
|
import {s} from '#/lib/styles'
|
||||||
import {isNative, isWeb} from '#/platform/detection'
|
import {isNative, isWeb} from '#/platform/detection'
|
||||||
import {
|
import {
|
||||||
SavedFeedItem,
|
SavedFeedItem,
|
||||||
@@ -16,25 +22,19 @@ import {
|
|||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {useSetMinimalShellMode} from '#/state/shell'
|
import {useSetMinimalShellMode} from '#/state/shell'
|
||||||
import {useComposerControls} from '#/state/shell/composer'
|
import {useComposerControls} from '#/state/shell/composer'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
|
||||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
import {FAB} from '#/view/com/util/fab/FAB'
|
||||||
import {ComposeIcon2} from 'lib/icons'
|
import {TextLink} from '#/view/com/util/Link'
|
||||||
import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
|
import {List} from '#/view/com/util/List'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {FeedFeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
|
||||||
import {s} from 'lib/styles'
|
import {Text} from '#/view/com/util/text/Text'
|
||||||
import {ErrorMessage} from 'view/com/util/error/ErrorMessage'
|
import {ViewHeader} from '#/view/com/util/ViewHeader'
|
||||||
import {FAB} from 'view/com/util/fab/FAB'
|
|
||||||
import {SearchInput} from 'view/com/util/forms/SearchInput'
|
|
||||||
import {TextLink} from 'view/com/util/Link'
|
|
||||||
import {List} from 'view/com/util/List'
|
|
||||||
import {FeedFeedLoadingPlaceholder} from 'view/com/util/LoadingPlaceholder'
|
|
||||||
import {Text} from 'view/com/util/text/Text'
|
|
||||||
import {ViewHeader} from 'view/com/util/ViewHeader'
|
|
||||||
import {NoFollowingFeed} from '#/screens/Feeds/NoFollowingFeed'
|
import {NoFollowingFeed} from '#/screens/Feeds/NoFollowingFeed'
|
||||||
import {NoSavedFeedsOfAnyType} from '#/screens/Feeds/NoSavedFeedsOfAnyType'
|
import {NoSavedFeedsOfAnyType} from '#/screens/Feeds/NoSavedFeedsOfAnyType'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {Divider} from '#/components/Divider'
|
import {Divider} from '#/components/Divider'
|
||||||
import * as FeedCard from '#/components/FeedCard'
|
import * as FeedCard from '#/components/FeedCard'
|
||||||
|
import {SearchInput} from '#/components/forms/SearchInput'
|
||||||
import {IconCircle} from '#/components/IconCircle'
|
import {IconCircle} from '#/components/IconCircle'
|
||||||
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron'
|
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron'
|
||||||
import {FilterTimeline_Stroke2_Corner0_Rounded as FilterTimeline} from '#/components/icons/FilterTimeline'
|
import {FilterTimeline_Stroke2_Corner0_Rounded as FilterTimeline} from '#/components/icons/FilterTimeline'
|
||||||
@@ -481,11 +481,12 @@ export function FeedsScreen(_props: Props) {
|
|||||||
<FeedsAboutHeader />
|
<FeedsAboutHeader />
|
||||||
<View style={{paddingHorizontal: 12, paddingBottom: 4}}>
|
<View style={{paddingHorizontal: 12, paddingBottom: 4}}>
|
||||||
<SearchInput
|
<SearchInput
|
||||||
query={query}
|
value={query}
|
||||||
onChangeQuery={onChangeQuery}
|
onChangeText={onChangeQuery}
|
||||||
onPressCancelSearch={onPressCancelSearch}
|
onClearText={onPressCancelSearch}
|
||||||
onSubmitQuery={onSubmitQuery}
|
onSubmitEditing={onSubmitQuery}
|
||||||
setIsInputFocused={onChangeSearchFocus}
|
onFocus={() => onChangeSearchFocus(true)}
|
||||||
|
onBlur={() => onChangeSearchFocus(false)}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -62,12 +62,10 @@ import {makeSearchQuery, parseSearchQuery} from '#/screens/Search/utils'
|
|||||||
import {atoms as a, useBreakpoints, useTheme as useThemeNew, web} from '#/alf'
|
import {atoms as a, useBreakpoints, useTheme as useThemeNew, web} from '#/alf'
|
||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import * as FeedCard from '#/components/FeedCard'
|
import * as FeedCard from '#/components/FeedCard'
|
||||||
import * as TextField from '#/components/forms/TextField'
|
import {SearchInput} from '#/components/forms/SearchInput'
|
||||||
import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDown} from '#/components/icons/Chevron'
|
import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDown} from '#/components/icons/Chevron'
|
||||||
import {MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass2'
|
|
||||||
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
|
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
|
||||||
import {SettingsGear2_Stroke2_Corner0_Rounded as Gear} from '#/components/icons/SettingsGear2'
|
import {SettingsGear2_Stroke2_Corner0_Rounded as Gear} from '#/components/icons/SettingsGear2'
|
||||||
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
|
||||||
|
|
||||||
function Loader() {
|
function Loader() {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
@@ -864,15 +862,16 @@ export function SearchScreen(
|
|||||||
<ButtonIcon icon={Menu} size="lg" />
|
<ButtonIcon icon={Menu} size="lg" />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<SearchInputBox
|
<View style={[a.flex_1]}>
|
||||||
textInput={textInput}
|
<SearchInput
|
||||||
searchText={searchText}
|
ref={textInput}
|
||||||
showAutocomplete={showAutocomplete}
|
value={searchText}
|
||||||
onFocus={onSearchInputFocus}
|
onFocus={onSearchInputFocus}
|
||||||
onChangeText={onChangeText}
|
onChangeText={onChangeText}
|
||||||
onSubmit={onSubmit}
|
onClearText={onPressClearQuery}
|
||||||
onPressClearQuery={onPressClearQuery}
|
onSubmitEditing={onSubmit}
|
||||||
/>
|
/>
|
||||||
|
</View>
|
||||||
{showFiltersButton && (
|
{showFiltersButton && (
|
||||||
<Button
|
<Button
|
||||||
onPress={() => setShowFilters(!showFilters)}
|
onPress={() => setShowFilters(!showFilters)}
|
||||||
@@ -961,78 +960,6 @@ export function SearchScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let SearchInputBox = ({
|
|
||||||
textInput,
|
|
||||||
searchText,
|
|
||||||
showAutocomplete,
|
|
||||||
onFocus,
|
|
||||||
onChangeText,
|
|
||||||
onSubmit,
|
|
||||||
onPressClearQuery,
|
|
||||||
}: {
|
|
||||||
textInput: React.RefObject<TextInput>
|
|
||||||
searchText: string
|
|
||||||
showAutocomplete: boolean
|
|
||||||
onFocus: () => void
|
|
||||||
onChangeText: (text: string) => void
|
|
||||||
onSubmit: () => void
|
|
||||||
onPressClearQuery: () => void
|
|
||||||
}): React.ReactNode => {
|
|
||||||
const {_} = useLingui()
|
|
||||||
const t = useThemeNew()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={[a.flex_1]}>
|
|
||||||
<TextField.Root>
|
|
||||||
<TextField.Icon icon={MagnifyingGlass} />
|
|
||||||
<TextField.Input
|
|
||||||
inputRef={textInput}
|
|
||||||
label={_(msg`Search`)}
|
|
||||||
value={searchText}
|
|
||||||
placeholder={_(msg`Search`)}
|
|
||||||
returnKeyType="search"
|
|
||||||
onChangeText={onChangeText}
|
|
||||||
onSubmitEditing={onSubmit}
|
|
||||||
onFocus={onFocus}
|
|
||||||
keyboardAppearance={t.scheme}
|
|
||||||
selectTextOnFocus={isNative}
|
|
||||||
autoFocus={false}
|
|
||||||
accessibilityRole="search"
|
|
||||||
autoCorrect={false}
|
|
||||||
autoComplete="off"
|
|
||||||
autoCapitalize="none"
|
|
||||||
/>
|
|
||||||
</TextField.Root>
|
|
||||||
|
|
||||||
{showAutocomplete && searchText.length > 0 && (
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
a.absolute,
|
|
||||||
a.z_10,
|
|
||||||
a.my_auto,
|
|
||||||
a.inset_0,
|
|
||||||
a.justify_center,
|
|
||||||
a.pr_sm,
|
|
||||||
{left: 'auto'},
|
|
||||||
]}>
|
|
||||||
<Button
|
|
||||||
testID="searchTextInputClearBtn"
|
|
||||||
onPress={onPressClearQuery}
|
|
||||||
label={_(msg`Clear search query`)}
|
|
||||||
hitSlop={HITSLOP_10}
|
|
||||||
size="tiny"
|
|
||||||
shape="round"
|
|
||||||
variant="ghost"
|
|
||||||
color="secondary">
|
|
||||||
<ButtonIcon icon={X} size="sm" />
|
|
||||||
</Button>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
SearchInputBox = React.memo(SearchInputBox)
|
|
||||||
|
|
||||||
let AutocompleteResults = ({
|
let AutocompleteResults = ({
|
||||||
isAutocompleteFetching,
|
isAutocompleteFetching,
|
||||||
autocompleteData,
|
autocompleteData,
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ import {s} from '#/lib/styles'
|
|||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
||||||
import {precacheProfile} from '#/state/queries/profile'
|
import {precacheProfile} from '#/state/queries/profile'
|
||||||
import {SearchInput} from '#/view/com/util/forms/SearchInput'
|
|
||||||
import {Link} from '#/view/com/util/Link'
|
import {Link} from '#/view/com/util/Link'
|
||||||
import {Text} from '#/view/com/util/text/Text'
|
import {Text} from '#/view/com/util/text/Text'
|
||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} from '#/alf'
|
||||||
|
import {SearchInput} from '#/components/forms/SearchInput'
|
||||||
|
|
||||||
let SearchLinkCard = ({
|
let SearchLinkCard = ({
|
||||||
label,
|
label,
|
||||||
@@ -184,10 +184,10 @@ export function DesktopSearch() {
|
|||||||
return (
|
return (
|
||||||
<View style={[styles.container, pal.view]}>
|
<View style={[styles.container, pal.view]}>
|
||||||
<SearchInput
|
<SearchInput
|
||||||
query={query}
|
value={query}
|
||||||
onChangeQuery={onChangeText}
|
onChangeText={onChangeText}
|
||||||
onPressCancelSearch={onPressCancelSearch}
|
onClearText={onPressCancelSearch}
|
||||||
onSubmitQuery={onSubmit}
|
onSubmitEditing={onSubmit}
|
||||||
/>
|
/>
|
||||||
{query !== '' && isActive && moderationOpts && (
|
{query !== '' && isActive && moderationOpts && (
|
||||||
<View style={[pal.view, pal.borderDark, styles.resultsContainer]}>
|
<View style={[pal.view, pal.borderDark, styles.resultsContainer]}>
|
||||||
|
|||||||
Reference in New Issue
Block a user