diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx
index 410cc654e9..d28700df95 100644
--- a/src/components/forms/TextField.tsx
+++ b/src/components/forms/TextField.tsx
@@ -226,6 +226,7 @@ export function createInput(Component: typeof TextInput) {
<>
diff --git a/src/view/screens/Search/Search.tsx b/src/view/screens/Search/Search.tsx
index 801381a036..cf51f52ff5 100644
--- a/src/view/screens/Search/Search.tsx
+++ b/src/view/screens/Search/Search.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, {useLayoutEffect} from 'react'
import {
ActivityIndicator,
Image,
@@ -11,6 +11,10 @@ import {
} from 'react-native'
import {ScrollView as RNGHScrollView} from 'react-native-gesture-handler'
import RNPickerSelect from 'react-native-picker-select'
+import Animated, {
+ FadingTransition,
+ LinearTransition,
+} from 'react-native-reanimated'
import {AppBskyActorDefs, AppBskyFeedDefs, moderateProfile} from '@atproto/api'
import {
FontAwesomeIcon,
@@ -22,7 +26,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage'
import {useFocusEffect, useNavigation} from '@react-navigation/native'
import {APP_LANGUAGES, LANGUAGES} from '#/lib/../locale/languages'
-import {createHitslop} from '#/lib/constants'
+import {createHitslop, HITSLOP_20} from '#/lib/constants'
import {HITSLOP_10} from '#/lib/constants'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
import {usePalette} from '#/lib/hooks/usePalette'
@@ -47,7 +51,6 @@ import {useActorSearch} from '#/state/queries/actor-search'
import {usePopularFeedsSearch} from '#/state/queries/feed'
import {useSearchPostsQuery} from '#/state/queries/search-posts'
import {useSession} from '#/state/session'
-import {useSetDrawerOpen} from '#/state/shell'
import {useSetMinimalShellMode} from '#/state/shell'
import {Pager} from '#/view/com/pager/Pager'
import {TabBar} from '#/view/com/pager/TabBar'
@@ -61,16 +64,16 @@ import {SearchLinkCard, SearchProfileCard} from '#/view/shell/desktop/Search'
import {makeSearchQuery, parseSearchQuery} from '#/screens/Search/utils'
import {
atoms as a,
+ native,
tokens,
useBreakpoints,
useTheme as useThemeNew,
web,
} from '#/alf'
-import {Button, ButtonIcon, ButtonText} from '#/components/Button'
+import {Button, ButtonText} from '#/components/Button'
import * as FeedCard from '#/components/FeedCard'
import {SearchInput} from '#/components/forms/SearchInput'
import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDown} from '#/components/icons/Chevron'
-import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
import * as Layout from '#/components/Layout'
function Loader() {
@@ -602,7 +605,6 @@ export function SearchScreen(
const navigation = useNavigation()
const textInput = React.useRef(null)
const {_} = useLingui()
- const setDrawerOpen = useSetDrawerOpen()
const setMinimalShellMode = useSetMinimalShellMode()
// Query terms
@@ -621,11 +623,17 @@ export function SearchScreen(
initialQuery: queryParam,
})
const showFilters = Boolean(queryWithParams && !showAutocomplete)
- /*
- * Arbitrary sizing, so guess and check, used for sticky header alignment and
- * sizing.
- */
- const headerHeight = 60 + (showFilters ? 40 : 0)
+
+ // web only - measure header height for sticky positioning
+ const [headerHeight, setHeaderHeight] = React.useState(0)
+ const headerRef = React.useRef(null)
+ useLayoutEffect(() => {
+ if (isWeb) {
+ if (!headerRef.current) return
+ const measurement = (headerRef.current as Element).getBoundingClientRect()
+ setHeaderHeight(measurement.height)
+ }
+ }, [])
useFocusEffect(
useNonReactiveCallback(() => {
@@ -654,11 +662,6 @@ export function SearchScreen(
loadSearchHistory()
}, [])
- const onPressMenu = React.useCallback(() => {
- textInput.current?.blur()
- setDrawerOpen(true)
- }, [setDrawerOpen])
-
const onPressClearQuery = React.useCallback(() => {
scrollToTopWeb()
setSearchText('')
@@ -843,33 +846,51 @@ export function SearchScreen(
return (
{
+ if (isWeb) setHeaderHeight(evt.nativeEvent.layout.height)
+ }}
style={[
+ t.atoms.bg,
web({
- height: headerHeight,
position: 'sticky',
top: 0,
zIndex: 1,
}),
]}>
-
+ {!gtMobile && !showAutocomplete && (
+
+
+
+
+
+ Search
+
+
+ {showFilters ? (
+
+
+
+ ) : (
+
+ )}
+
+
+ )}
+
- {!gtMobile && !showAutocomplete && (
-
- )}
{showAutocomplete && (
@@ -895,24 +918,7 @@ export function SearchScreen(
)}
-
- {showFilters && (
-
-
-
-
-
- )}
-
+