import React , { memo , PropsWithChildren } from 'react' ; import { Dimensions } from 'react-native' ; import Animated , { runOnJS , useAnimatedGestureHandler , useAnimatedStyle , useSharedValue , withTiming , } from 'react-native-reanimated' ; import { PanGestureHandler , PanGestureHandlerGestureEvent , } from 'react-native-gesture-handler' ; import type { ContextType } from '../../typings' ; import type { SwipeableProps } from './typings' ; const { width : SCREEN_WIDTH } = Dimensions . get ( 'window' ) ; export const Swipeable = memo ( ( { onSwipe , disabled = false , children , } ) => { const translateX = useSharedValue ( 0 ) ; const panGesture = useAnimatedGestureHandler < PanGestureHandlerGestureEvent , ContextType > ( { onStart : ( _ , context ) => { context . startX = translateX . value ; } , onActive : ( event , context ) => { translateX . value = context . startX + event . translationX ; } , onEnd : ( ) => { const willDisappear = translateX . value > SCREEN_WIDTH / 3 || translateX . value < - SCREEN_WIDTH / 3 ; const direction = Math . sign ( translateX . value ) ; const position = willDisappear ? direction * 800 : 0 ; translateX . value = withTiming ( position , undefined , ( finished ) => { if ( finished && willDisappear ) { runOnJS ( onSwipe ) ( ) ; } } ) ; } , } ) ; const swipeableStyle = useAnimatedStyle ( ( ) => ( { transform : [ { translateX : translateX . value , } , ] , } ) ) ; return ( < PanGestureHandler enabled = { ! disabled } activeOffsetX = { [ - 10 , 10 ] } onGestureEvent = { panGesture } > < Animated . View style = { swipeableStyle } > { children } < /Animated.View> < /PanGestureHandler>); } ) ;