react-native-pressable-scale
Version:
A <PressableScale> and a supercharged <NativePressableScale> components for React Native
48 lines (47 loc) • 2.22 kB
JavaScript
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>);
}