react-native-swipe-gestures

 

Re-usable한 Wrapper 컴포넌트 제작

GestureContainer.tsx

import React from 'react'; import GestureRecognizer from 'react-native-swipe-gestures'; import {GestureContainerProps} from './types'; export default function GestureContainer({ children, onSwipeUp = gestureState => console.log('state : ', gestureState), onSwipeDown = gestureState => console.log('state : ', gestureState), onSwipeLeft = gestureState => console.log('state : ', gestureState), onSwipeRight = gestureState => console.log('state : ', gestureState), velocityThreshold = 0.3, directionalOffsetThreshold = 80, }: GestureContainerProps) { // const config = { velocityThreshold, directionalOffsetThreshold, }; return ( <GestureRecognizer onSwipeUp={state => onSwipeUp(state)} onSwipeDown={state => onSwipeDown(state)} onSwipeLeft={state => onSwipeLeft(state)} onSwipeRight={state => onSwipeRight(state)} config={config} style={[]}> {children} </GestureRecognizer> ); }

types.ts

import {ReactElement} from 'react'; import {PanResponderGestureState} from 'react-native'; export type SwipeDirections = | 'SWIPE_UP' | 'SWIPE_DOWN' | 'SWIPE_LEFT' | 'SWIPE_RIGHT'; export type GestureContainerProps = { children: ReactElement; onSwipeUp?: (gestureState?: PanResponderGestureState) => void; onSwipeDown?: (gestureState?: PanResponderGestureState) => void; onSwipeLeft?: (gestureState?: PanResponderGestureState) => void; onSwipeRight?: (gestureState?: PanResponderGestureState) => void; velocityThreshold?: number; directionalOffsetThreshold?: number; }; export type GestureHandler = (gestureState: PanResponderGestureState) => void;
 

커스텀 wrapper 컴포넌트 활용 예시

GestureExm.tsx

import React, {useState} from 'react'; import {View, Text, StyleSheet, Image, Pressable} from 'react-native'; import * as Animatable from 'react-native-animatable'; import GestureContainer from './GestureContainer'; const summary = require('../images/Summary.png'); const editImg = require('../images/Edit.png'); const deleteImg = require('../images/Delete.png'); export default function GestureExm() { const [isLeft, setIsLeft] = useState(false); const onLeft = () => { setIsLeft(true); console.log('left'); }; const onRight = () => { setIsLeft(false); console.log('right'); }; const onEdit = () => { console.log('수정 누름'); }; const onDelete = () => { console.log('삭제 누름'); }; return ( <GestureContainer onSwipeLeft={onLeft} onSwipeRight={onRight}> <View style={{flexDirection: 'row', width: '100%', padding: 10}}> <View style={[styles.summary, isLeft && styles.left]}> <Image source={summary} /> </View> {isLeft && ( <> <Animatable.View animation="fadeInLeft" duration={500} style={{zIndex: 1}}> <Pressable style={styles.edit} onPress={onEdit}> <Image source={editImg} /> <Text style={styles.buttonText}>수정</Text> </Pressable> </Animatable.View> <Animatable.View animation="fadeInLeft" duration={500} delay={100} style={{zIndex: 0}}> <Pressable style={styles.delete} onPress={onDelete}> <Image source={deleteImg} /> <Text style={styles.buttonText}>삭제</Text> </Pressable> </Animatable.View> </> )} </View> </GestureContainer> ); } const styles = StyleSheet.create({ summary: { zIndex: 3, backgroundColor: 'white', borderRadius: 10, overflow: 'hidden', }, edit: { backgroundColor: '#A8A7B5', marginLeft: -8, zIndex: 1, padding: 10, paddingLeft: 15, borderTopRightRadius: 10, borderBottomRightRadius: 10, justifyContent: 'center', }, delete: { backgroundColor: '#E00C3E', marginLeft: -8, zIndex: 0, padding: 10, paddingLeft: 15, borderTopRightRadius: 10, borderBottomRightRadius: 10, justifyContent: 'center', }, left: {marginLeft: -40}, buttonText: {color: 'white', fontSize: 14, fontWeight: '600', marginTop: 6}, });