animate cancel button in

This commit is contained in:
Samuel Newman
2025-01-30 11:52:12 -08:00
parent 8e4a1a9b06
commit b1099d0169
+69 -38
View File
@@ -1,4 +1,4 @@
import React, {useLayoutEffect} from 'react' import React, {useEffect, useLayoutEffect} from 'react'
import { import {
ActivityIndicator, ActivityIndicator,
Image, Image,
@@ -16,6 +16,9 @@ import Animated, {
FadeOut, FadeOut,
LayoutAnimationConfig, LayoutAnimationConfig,
LinearTransition, LinearTransition,
useAnimatedStyle,
useSharedValue,
withTiming,
} from 'react-native-reanimated' } from 'react-native-reanimated'
import {AppBskyActorDefs, AppBskyFeedDefs, moderateProfile} from '@atproto/api' import {AppBskyActorDefs, AppBskyFeedDefs, moderateProfile} from '@atproto/api'
import { import {
@@ -833,6 +836,26 @@ export function SearchScreen(
} }
}, [setShowAutocomplete]) }, [setShowAutocomplete])
const cancelWidth = useSharedValue(70)
const showCancelBtnAnimation = useSharedValue(0)
useEffect(() => {
if (showAutocomplete) {
showCancelBtnAnimation.set(withTiming(1))
} else {
showCancelBtnAnimation.set(withTiming(0))
}
}, [showAutocomplete, showCancelBtnAnimation])
const animatedInputContainerStyle = useAnimatedStyle(() => ({
marginRight: showCancelBtnAnimation.get() * cancelWidth.get(),
}))
const animatedCancelBtnStyle = useAnimatedStyle(() => ({
opacity: showCancelBtnAnimation.get(),
right: cancelWidth.get() * -1,
}))
return ( return (
<Layout.Screen testID="searchScreen"> <Layout.Screen testID="searchScreen">
<View <View
@@ -852,8 +875,8 @@ export function SearchScreen(
<LayoutAnimationConfig skipEntering skipExiting> <LayoutAnimationConfig skipEntering skipExiting>
{!gtMobile && !showAutocomplete && ( {!gtMobile && !showAutocomplete && (
<Animated.View <Animated.View
entering={FadeIn.delay(100).duration(200)} entering={native(FadeIn.delay(100).duration(200))}
exiting={FadeOut.duration(200)} exiting={native(FadeOut.duration(200))}
// HACK: shift up search input. we can't remove the top padding // HACK: shift up search input. we can't remove the top padding
// on the search input because it messes up the layout animation // on the search input because it messes up the layout animation
// if we add it only when the header is hidden // if we add it only when the header is hidden
@@ -881,10 +904,11 @@ export function SearchScreen(
)} )}
</LayoutAnimationConfig> </LayoutAnimationConfig>
<Animated.View <Animated.View
style={[a.px_md, a.pt_sm, a.pb_sm, a.gap_sm]} style={[a.px_md, a.pt_sm, a.pb_sm, a.overflow_hidden]}
layout={native(LinearTransition)}> layout={native(LinearTransition)}>
<View style={[a.flex_row, a.gap_xs]}> <Animated.View
<View style={[a.flex_1]}> style={[a.gap_sm, a.relative, animatedInputContainerStyle]}>
<View style={[a.w_full]}>
<SearchInput <SearchInput
ref={textInput} ref={textInput}
value={searchText} value={searchText}
@@ -896,40 +920,47 @@ export function SearchScreen(
hitSlop={{...HITSLOP_20, top: 0}} hitSlop={{...HITSLOP_20, top: 0}}
/> />
</View> </View>
{showAutocomplete && ( <Animated.View
<Animated.View entering={FadeIn} exiting={FadeOut}>
<Button
label={_(msg`Cancel search`)}
size="large"
variant="ghost"
color="secondary"
style={[a.px_sm]}
onPress={onPressCancelSearch}
hitSlop={HITSLOP_10}>
<ButtonText>
<Trans>Cancel</Trans>
</ButtonText>
</Button>
</Animated.View>
)}
</View>
{showFilters && gtMobile && (
<View
style={[ style={[
a.flex_row, a.absolute,
a.align_center, {top: 0, bottom: 0},
a.justify_between, a.pl_xs,
a.gap_sm, animatedCancelBtnStyle,
]}> !showAutocomplete && a.pointer_events_none,
<View style={[{width: 140}]}> ]}
<SearchLanguageDropdown onLayout={evt => cancelWidth.set(evt.nativeEvent.layout.width)}
value={params.lang} aria-hidden={!showAutocomplete}>
onChange={params.setLang} <Button
/> label={_(msg`Cancel search`)}
size="large"
variant="ghost"
color="secondary"
style={[a.px_sm]}
onPress={onPressCancelSearch}
hitSlop={HITSLOP_10}>
<ButtonText>
<Trans>Cancel</Trans>
</ButtonText>
</Button>
</Animated.View>
{showFilters && gtMobile && (
<View
style={[
a.flex_row,
a.align_center,
a.justify_between,
a.gap_sm,
]}>
<View style={[{width: 140}]}>
<SearchLanguageDropdown
value={params.lang}
onChange={params.setLang}
/>
</View>
</View> </View>
</View> )}
)} </Animated.View>
</Animated.View> </Animated.View>
</Layout.Center> </Layout.Center>
</View> </View>