learning_ai_invt_trdg/mobile/components/PressableScale.tsx

55 lines
1.4 KiB
TypeScript

import React from 'react';
import { Pressable, PressableProps } from 'react-native';
import Animated, {
useAnimatedStyle,
useSharedValue,
withSpring,
} from 'react-native-reanimated';
import { triggerHaptic } from '@/utils/haptics';
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
interface PressableScaleProps extends PressableProps {
haptic?: 'light' | 'medium' | 'selection';
children: React.ReactNode;
}
export default function PressableScale({
haptic = 'light',
children,
style,
onPress,
...props
}: PressableScaleProps) {
const scale = useSharedValue(1);
const translateY = useSharedValue(0);
const animatedStyle = useAnimatedStyle(() => ({
transform: [
{ scale: scale.value },
{ translateY: translateY.value },
],
}));
return (
<AnimatedPressable
onPressIn={() => {
scale.value = withSpring(0.97, { damping: 15, stiffness: 150 });
translateY.value = withSpring(-2, { damping: 15, stiffness: 150 });
}}
onPressOut={() => {
scale.value = withSpring(1, { damping: 15, stiffness: 150 });
translateY.value = withSpring(0, { damping: 15, stiffness: 150 });
}}
onPress={(e) => {
triggerHaptic(haptic);
onPress?.(e);
}}
style={[animatedStyle, style as any]}
{...props}
>
{children}
</AnimatedPressable>
);
}