UNPKG

react-native-pressable-scale

Version:

A <PressableScale> and a supercharged <NativePressableScale> components for React Native

48 lines (47 loc) 2.22 kB
import React, { useMemo } from 'react'; import { TapGestureHandler } from 'react-native-gesture-handler'; import Reanimated, { cancelAnimation, withDelay, useAnimatedGestureHandler, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated'; import { PRESSABLE_IN_LIST_DELAY } from './Constants'; /** * A Pressable that scales down when pressed. Uses the native responder system from react-native-gesture-handler instead of the JS Pressability API. */ export function NativePressableScale(props) { const { activeScale = 0.95, isInList, damping = 15, weight = 'heavy', stiffness = 150, overshootClamping = true, restSpeedThreshold = 0.001, restDisplacementThreshold = 0.001, disabled = false, ref, style, onPress, ...passThroughProps } = props; const mass = useMemo(() => { switch (weight) { case 'light': return 0.15; case 'medium': return 0.2; case 'heavy': default: return 0.3; } }, [weight]); const scale = useSharedValue(1); const springConfig = useMemo(() => ({ damping, mass, stiffness, overshootClamping, restSpeedThreshold, restDisplacementThreshold, }), [damping, mass, overshootClamping, restDisplacementThreshold, restSpeedThreshold, stiffness]); const animatedStyle = useAnimatedStyle(() => ({ transform: [{ scale: scale.value }] }), [scale]); const onGestureEvent = useAnimatedGestureHandler({ onStart: () => { cancelAnimation(scale); scale.value = isInList ? withDelay(PRESSABLE_IN_LIST_DELAY, withSpring(activeScale, springConfig)) : withSpring(activeScale, springConfig); }, onEnd: () => { onPress(); }, onFinish: () => { cancelAnimation(scale); scale.value = withSpring(1, springConfig); }, }, [scale, isInList, activeScale, springConfig, onPress]); return (<TapGestureHandler ref={ref} onGestureEvent={onGestureEvent} enabled={!disabled} shouldCancelWhenOutside={true}> <Reanimated.View style={[style, animatedStyle]} {...passThroughProps}/> </TapGestureHandler>); }