Fix search typeahead performance with absolute overlay
Instead of toggling display:none/flex on the typeahead and content panels (which causes heavy unmount/remount cycles), the content (SearchScreenInner) now stays always mounted and the typeahead overlay is absolutely positioned on top with conditional rendering. Added reanimated FadeInUp/FadeOutDown animations (native only via native() wrapper) for a smooth transition. Added accessibility props (accessibilityViewIsModal, aria-modal, accessibilityRole) so screen readers properly treat the overlay as a modal list. https://claude.ai/code/session_01BhE3QBg6XZwXTwgTbQP9L9
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
|||||||
View,
|
View,
|
||||||
type ViewStyle,
|
type ViewStyle,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
|
import Animated, {FadeInUp, FadeOutDown} from 'react-native-reanimated'
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
import {useFocusEffect, useNavigation, useRoute} from '@react-navigation/native'
|
import {useFocusEffect, useNavigation, useRoute} from '@react-navigation/native'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
@@ -32,7 +33,7 @@ import {
|
|||||||
type Params,
|
type Params,
|
||||||
parseSearchQuery,
|
parseSearchQuery,
|
||||||
} from '#/screens/Search/utils'
|
} from '#/screens/Search/utils'
|
||||||
import {atoms as a, tokens, useBreakpoints, useTheme, web} from '#/alf'
|
import {atoms as a, native, tokens, useBreakpoints, useTheme, web} from '#/alf'
|
||||||
import {Button, ButtonText} from '#/components/Button'
|
import {Button, ButtonText} from '#/components/Button'
|
||||||
import {SearchInput} from '#/components/forms/SearchInput'
|
import {SearchInput} from '#/components/forms/SearchInput'
|
||||||
import * as Layout from '#/components/Layout'
|
import * as Layout from '#/components/Layout'
|
||||||
@@ -418,36 +419,7 @@ export function SearchScreenShell({
|
|||||||
</Layout.Center>
|
</Layout.Center>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View
|
<View style={[a.flex_1, a.relative]}>
|
||||||
style={{
|
|
||||||
display: showAutocomplete && !fixedParams ? 'flex' : 'none',
|
|
||||||
flex: 1,
|
|
||||||
}}>
|
|
||||||
{searchText.length > 0 ? (
|
|
||||||
<AutocompleteResults
|
|
||||||
isAutocompleteFetching={isAutocompleteFetching}
|
|
||||||
autocompleteData={autocompleteData}
|
|
||||||
searchText={searchText}
|
|
||||||
onSubmit={onSubmit('autocomplete')}
|
|
||||||
onResultPress={onAutocompleteResultPress}
|
|
||||||
onProfileClick={handleProfileClick}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<SearchHistory
|
|
||||||
searchHistory={termHistory}
|
|
||||||
selectedProfiles={accountHistoryProfiles?.profiles || []}
|
|
||||||
onItemClick={handleHistoryItemClick}
|
|
||||||
onProfileClick={handleProfileClick}
|
|
||||||
onRemoveItemClick={deleteSearchHistoryItem}
|
|
||||||
onRemoveProfileClick={deleteProfileHistoryItem}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
display: showAutocomplete ? 'none' : 'flex',
|
|
||||||
flex: 1,
|
|
||||||
}}>
|
|
||||||
<SearchScreenInner
|
<SearchScreenInner
|
||||||
key={params.lang}
|
key={params.lang}
|
||||||
activeTab={activeTab}
|
activeTab={activeTab}
|
||||||
@@ -457,6 +429,36 @@ export function SearchScreenShell({
|
|||||||
headerHeight={headerHeight}
|
headerHeight={headerHeight}
|
||||||
focusSearchInput={focusSearchInput}
|
focusSearchInput={focusSearchInput}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{showAutocomplete && !fixedParams && (
|
||||||
|
<Animated.View
|
||||||
|
entering={native(FadeInUp.duration(200))}
|
||||||
|
exiting={native(FadeOutDown.duration(150))}
|
||||||
|
style={[a.absolute, a.inset_0, t.atoms.bg]}
|
||||||
|
accessibilityViewIsModal
|
||||||
|
accessibilityRole="list"
|
||||||
|
aria-modal>
|
||||||
|
{searchText.length > 0 ? (
|
||||||
|
<AutocompleteResults
|
||||||
|
isAutocompleteFetching={isAutocompleteFetching}
|
||||||
|
autocompleteData={autocompleteData}
|
||||||
|
searchText={searchText}
|
||||||
|
onSubmit={onSubmit('autocomplete')}
|
||||||
|
onResultPress={onAutocompleteResultPress}
|
||||||
|
onProfileClick={handleProfileClick}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<SearchHistory
|
||||||
|
searchHistory={termHistory}
|
||||||
|
selectedProfiles={accountHistoryProfiles?.profiles || []}
|
||||||
|
onItemClick={handleHistoryItemClick}
|
||||||
|
onProfileClick={handleProfileClick}
|
||||||
|
onRemoveItemClick={deleteSearchHistoryItem}
|
||||||
|
onRemoveProfileClick={deleteProfileHistoryItem}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Animated.View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
</Layout.Screen>
|
</Layout.Screen>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user