Skip to content

Instantly share code, notes, and snippets.

@savayer
Created August 18, 2023 11:29
Show Gist options
  • Save savayer/0f83aa07c12a59acf7898f9f61e5b25d to your computer and use it in GitHub Desktop.
Save savayer/0f83aa07c12a59acf7898f9f61e5b25d to your computer and use it in GitHub Desktop.
import React, { ReactNode } from 'react';
import { StyleProp, ViewStyle } from 'react-native';
import {
Gesture,
GestureDetector,
gestureHandlerRootHOC,
} from 'react-native-gesture-handler';
import Reanimated, {
runOnJS,
useAnimatedStyle,
useSharedValue,
withTiming,
} from 'react-native-reanimated';
type GestureUpDownWrapperProps = {
className?: string;
style?: StyleProp<ViewStyle>;
callback?: () => {};
onChangeTranslationY?: (translationY: number) => {};
children: ReactNode;
};
const GestureUpDownWrapper = gestureHandlerRootHOC(
({
style,
callback,
onChangeTranslationY,
children,
}: GestureUpDownWrapperProps) => {
const position = useSharedValue(0);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateY: position.value }],
}));
const panGesture = Gesture.Pan()
.failOffsetX([-2, 2])
.activeOffsetX([-10, 10])
.activeOffsetY([-10, 10])
.onUpdate((e) => {
position.value = e.translationY;
runOnJS(onChangeTranslationY)(Math.abs(position.value));
})
.onEnd(() => {
if (Math.abs(position.value) >= 200 && callback) {
runOnJS(callback)();
return;
}
position.value = withTiming(0);
runOnJS(onChangeTranslationY)(0);
});
return (
<GestureDetector gesture={panGesture}>
<Reanimated.View style={[style, animatedStyle]}>
{children}
</Reanimated.View>
</GestureDetector>
);
},
);
export default GestureUpDownWrapper;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment