forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {
2 Pressable,
3 type PressableProps,
4 type StyleProp,
5 type ViewStyle,
6} from 'react-native'
7import Animated, {
8 cancelAnimation,
9 useAnimatedStyle,
10 useReducedMotion,
11 useSharedValue,
12 withTiming,
13} from 'react-native-reanimated'
14
15import {IS_NATIVE, IS_WEB_TOUCH_DEVICE} from '#/env'
16
17const DEFAULT_TARGET_SCALE = IS_NATIVE || IS_WEB_TOUCH_DEVICE ? 0.98 : 1
18
19const AnimatedPressable = Animated.createAnimatedComponent(Pressable)
20
21export function PressableScale({
22 targetScale = DEFAULT_TARGET_SCALE,
23 children,
24 style,
25 onPressIn,
26 onPressOut,
27 ...rest
28}: {
29 targetScale?: number
30 style?: StyleProp<ViewStyle>
31} & Exclude<PressableProps, 'onPressIn' | 'onPressOut' | 'style'>) {
32 const reducedMotion = useReducedMotion()
33
34 const scale = useSharedValue(1)
35
36 const animatedStyle = useAnimatedStyle(() => ({
37 transform: [{scale: scale.get()}],
38 }))
39
40 return (
41 <AnimatedPressable
42 accessibilityRole="button"
43 onPressIn={e => {
44 if (onPressIn) {
45 onPressIn(e)
46 }
47 cancelAnimation(scale)
48 scale.set(() => withTiming(targetScale, {duration: 100}))
49 }}
50 onPressOut={e => {
51 if (onPressOut) {
52 onPressOut(e)
53 }
54 cancelAnimation(scale)
55 scale.set(() => withTiming(1, {duration: 100}))
56 }}
57 style={[!reducedMotion && animatedStyle, style]}
58 {...rest}>
59 {children}
60 </AnimatedPressable>
61 )
62}