mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {Pressable, PressableProps, StyleProp, ViewStyle} from 'react-native'
2import Animated, {
3 cancelAnimation,
4 useAnimatedStyle,
5 useReducedMotion,
6 useSharedValue,
7 withTiming,
8} from 'react-native-reanimated'
9
10import {isTouchDevice} from '#/lib/browser'
11import {isNative} from '#/platform/detection'
12
13const DEFAULT_TARGET_SCALE = isNative || isTouchDevice ? 0.98 : 1
14
15const AnimatedPressable = Animated.createAnimatedComponent(Pressable)
16
17export function PressableScale({
18 targetScale = DEFAULT_TARGET_SCALE,
19 children,
20 style,
21 onPressIn,
22 onPressOut,
23 ...rest
24}: {
25 targetScale?: number
26 style?: StyleProp<ViewStyle>
27} & Exclude<PressableProps, 'onPressIn' | 'onPressOut' | 'style'>) {
28 const reducedMotion = useReducedMotion()
29
30 const scale = useSharedValue(1)
31
32 const animatedStyle = useAnimatedStyle(() => ({
33 transform: [{scale: scale.get()}],
34 }))
35
36 return (
37 <AnimatedPressable
38 accessibilityRole="button"
39 onPressIn={e => {
40 if (onPressIn) {
41 onPressIn(e)
42 }
43 cancelAnimation(scale)
44 scale.set(() => withTiming(targetScale, {duration: 100}))
45 }}
46 onPressOut={e => {
47 if (onPressOut) {
48 onPressOut(e)
49 }
50 cancelAnimation(scale)
51 scale.set(() => withTiming(1, {duration: 100}))
52 }}
53 style={[!reducedMotion && animatedStyle, style]}
54 {...rest}>
55 {children}
56 </AnimatedPressable>
57 )
58}