1+ import type { ViewStyle } from 'react-native' ;
12import { Gesture } from 'react-native-gesture-handler' ;
23import {
3- Easing ,
44 interpolate ,
55 useAnimatedStyle ,
66 useSharedValue ,
77 withTiming ,
88} from 'react-native-reanimated' ;
99import { useUniwind } from 'uniwind' ;
10- import { colorKit , useThemeColor } from '../../helpers/theme' ;
1110import { createContext } from '../../helpers/utils' ;
1211import {
1312 getAnimationState ,
1413 getAnimationValueMergedConfig ,
1514 getAnimationValueProperty ,
15+ getStyleTransform ,
1616} from '../../helpers/utils/animation' ;
1717import type {
18+ PressableFeedbackAnimation ,
1819 PressableFeedbackAnimationContextValue ,
19- PressableFeedbackHighlightAnimation ,
20+ PressableFeedbackHighlightRootAnimation ,
21+ PressableFeedbackVariant ,
2022} from './pressable-feedback.types' ;
2123
2224const [ PressableFeedbackAnimationProvider , usePressableFeedbackAnimation ] =
@@ -30,9 +32,31 @@ export { PressableFeedbackAnimationProvider, usePressableFeedbackAnimation };
3032
3133/**
3234 * Animation hook for PressableFeedback root component
33- * Handles ripple gesture and shared values
35+ * Handles gesture, shared values, and scale animation
3436 */
35- export function usePressableFeedbackRootAnimation ( ) {
37+ export function usePressableFeedbackRootAnimation ( options : {
38+ variant : PressableFeedbackVariant ;
39+ animation : PressableFeedbackAnimation | undefined ;
40+ style : ViewStyle | undefined ;
41+ } ) {
42+ const { variant, animation, style } = options ;
43+
44+ const { animationConfig, isAnimationDisabled } = getAnimationState ( animation ) ;
45+
46+ // Scale animation values
47+ const scaleValue = getAnimationValueProperty ( {
48+ animationValue : animationConfig ?. scale ,
49+ property : 'value' ,
50+ defaultValue : 0.99 ,
51+ } ) ;
52+
53+ const scaleTimingConfig = getAnimationValueMergedConfig ( {
54+ animationValue : animationConfig ?. scale ,
55+ property : 'timingConfig' ,
56+ defaultValue : { duration : 200 } ,
57+ } ) ;
58+
59+ // Shared values
3660 const isPressed = useSharedValue ( false ) ;
3761 const scale = useSharedValue ( 0 ) ;
3862 const pressedCenterX = useSharedValue ( 0 ) ;
@@ -41,34 +65,55 @@ export function usePressableFeedbackRootAnimation() {
4165 const containerHeight = useSharedValue ( 0 ) ;
4266 const rippleProgress = useSharedValue ( 0 ) ;
4367
68+ // Gesture handling
4469 const gesture = Gesture . Pan ( )
4570 . onBegin ( ( event ) => {
71+ isPressed . set ( true ) ;
72+ scale . set ( withTiming ( 1 , scaleTimingConfig ) ) ;
73+
74+ if ( variant === 'highlight' ) return ;
75+
4676 rippleProgress . set ( 0 ) ;
4777 pressedCenterX . set ( event . x ) ;
4878 pressedCenterY . set ( event . y ) ;
49- isPressed . set ( true ) ;
50- scale . set ( withTiming ( 1 , { duration : 250 } ) ) ;
5179 if ( rippleProgress . get ( ) === 0 ) {
5280 rippleProgress . set ( withTiming ( 1 , { duration : 250 } ) ) ;
5381 }
5482 } )
5583 . onFinalize ( ( ) => {
5684 isPressed . set ( false ) ;
57- scale . set ( withTiming ( 0 , { duration : 250 } ) ) ;
85+ scale . set ( withTiming ( 0 , scaleTimingConfig ) ) ;
86+
87+ if ( variant === 'ripple' ) return ;
88+
5889 rippleProgress . set ( withTiming ( 2 , { duration : 400 } ) ) ;
5990 } ) ;
6091
92+ const styleTransform = getStyleTransform ( style ) ;
93+
6194 const rContainerStyle = useAnimatedStyle ( ( ) => {
6295 const baseWidth = 300 ;
6396 const coefficient =
6497 containerWidth . get ( ) > 0 ? baseWidth / containerWidth . get ( ) : 1 ;
65- const adjustedScaleValue = 1 - ( 1 - 0.99 ) * coefficient ;
98+ const adjustedScaleValue = 1 - ( 1 - scaleValue ) * coefficient ;
99+
100+ if ( isAnimationDisabled ) {
101+ return {
102+ transform : [
103+ {
104+ scale : 1 ,
105+ } ,
106+ ...styleTransform ,
107+ ] ,
108+ } ;
109+ }
66110
67111 return {
68112 transform : [
69113 {
70114 scale : interpolate ( scale . get ( ) , [ 0 , 1 ] , [ 1 , adjustedScaleValue ] ) ,
71115 } ,
116+ ...styleTransform ,
72117 ] ,
73118 } ;
74119 } ) ;
@@ -92,40 +137,36 @@ export function usePressableFeedbackRootAnimation() {
92137 * Handles opacity and background color animations for the highlight effect
93138 */
94139export function usePressableFeedbackHighlightAnimation ( options : {
95- animation : PressableFeedbackHighlightAnimation | undefined ;
140+ animation : PressableFeedbackHighlightRootAnimation | undefined ;
96141} ) {
97142 const { animation } = options ;
98143
99144 const { theme } = useUniwind ( ) ;
100- const themeColorBackground = useThemeColor ( 'background' ) ;
101145
102146 const { isPressed } = usePressableFeedbackAnimation ( ) ;
103147
104148 const { animationConfig, isAnimationDisabled } = getAnimationState ( animation ) ;
105149
150+ // Background color
151+ const defaultColor = theme === 'dark' ? 'white' : 'gray' ;
152+
153+ const backgroundColor = getAnimationValueProperty ( {
154+ animationValue : animationConfig ?. highlight ?. backgroundColor ,
155+ property : 'value' ,
156+ defaultValue : defaultColor ,
157+ } ) ;
158+
106159 // Opacity animation
107160 const opacityValue = getAnimationValueProperty ( {
108- animationValue : animationConfig ?. opacity ,
161+ animationValue : animationConfig ?. highlight ?. opacity ,
109162 property : 'value' ,
110- defaultValue : [ 0 , 0.1 ] as [ number , number ] ,
163+ defaultValue : [ 0 , 0.05 ] as [ number , number ] ,
111164 } ) ;
112165
113166 const opacityTimingConfig = getAnimationValueMergedConfig ( {
114- animationValue : animationConfig ?. opacity ,
167+ animationValue : animationConfig ?. highlight ?. opacity ,
115168 property : 'timingConfig' ,
116- defaultValue : { duration : 200 , easing : Easing . inOut ( Easing . quad ) } ,
117- } ) ;
118-
119- // Background color
120- const defaultColor =
121- theme === 'dark'
122- ? colorKit . brighten ( themeColorBackground , 0.05 ) . hex ( )
123- : colorKit . darken ( themeColorBackground , 0.05 ) . hex ( ) ;
124-
125- const backgroundColor = getAnimationValueProperty ( {
126- animationValue : animationConfig ?. backgroundColor ,
127- property : 'value' ,
128- defaultValue : defaultColor ,
169+ defaultValue : { duration : 200 } ,
129170 } ) ;
130171
131172 const rContainerStyle = useAnimatedStyle ( ( ) => {
0 commit comments