Skip to content

Instantly share code, notes, and snippets.

@barunprasad
Created August 2, 2020 17:41
Show Gist options
  • Save barunprasad/a738d944fa9abf4e6993f719b13827ad to your computer and use it in GitHub Desktop.
Save barunprasad/a738d944fa9abf4e6993f719b13827ad to your computer and use it in GitHub Desktop.
React Native Gesture Handler Swipe inside tabs (react-navigation)
<SwipeProvider isFocusedScreen={isFocused}>
<FlatList
data={data}
refreshing={refreshing}
onRefresh={_loadData}
renderItem={({ item }) => (
<SwipeableRow
rightButtons={[
{
text: 'Delete',
iconName: 'delete',
color: '#dd2c00',
x: 64,
onPress: () => onDeleteAction(item),
},
]}
itemKey={item.id}>
<Surface
pointerEvents="box-none"
accessibilityLiveRegion="polite"
style={[styles.surfaceContainer]}>
<TouchableOpacity
style={styles.row}
onPress={() => onNavigateToDetail(item)}>
<ImageItem item={item} />
<Text style={styles.memo}>{item.memo}</Text>
</TouchableOpacity>
</Surface>
</SwipeableRow>
)}
keyExtractor={(item) => item.id}
/>
</SwipeProvider>
import React, { useRef, useContext, useCallback, useEffect } from 'react';
import { Animated, StyleSheet, Text, View, I18nManager } from 'react-native';
import MdIcon from 'react-native-vector-icons/MaterialIcons';
import { RectButton } from 'react-native-gesture-handler';
import Swipeable from 'react-native-gesture-handler/Swipeable';
import { SwipeContext } from './SwipeProvider';
const AnimatedIcon = Animated.createAnimatedComponent(MdIcon);
export default function SwipeableRow({ children, rightButtons = [], itemKey }) {
const _swipeableRow = useRef(null);
const { openedItemKey, setOpenedItemKey, isFocusedScreen } = useContext(
SwipeContext,
);
const close = () => {
if (_swipeableRow.current) {
_swipeableRow.current.close();
}
};
const handleSwipe = () => {
setOpenedItemKey(itemKey);
};
useEffect(() => {
// If another item is opened, close this one
if (openedItemKey && itemKey !== openedItemKey) {
close();
}
}, [itemKey, openedItemKey]);
useEffect(() => {
close();
}, [isFocusedScreen]);
const renderButtons = useCallback((buttons, progress) => {
return (
<View
style={{
width: 64 * buttons.length,
flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row',
}}>
{buttons.map(({ text, color, iconName, x, onPress }) => {
const trans = progress.interpolate({
inputRange: [0, 1],
outputRange: [x, 0],
});
const pressHandler = () => {
close();
if (onPress) {
onPress(text);
}
};
return (
<Animated.View
key={text}
style={{
flex: 1,
marginTop: 10,
marginBottom: 10,
transform: [{ translateX: trans }],
}}>
<RectButton
style={[styles.rightAction, { backgroundColor: color }]}
onPress={pressHandler}>
<AnimatedIcon name={iconName} size={20} color="#fff" />
<Text style={styles.actionText}>{text}</Text>
</RectButton>
</Animated.View>
);
})}
</View>
);
}, []);
const renderRightButtons = useCallback(
(progress) => {
return renderButtons(rightButtons, progress);
},
[rightButtons],
);
return (
<Swipeable
ref={_swipeableRow}
friction={2}
leftThreshold={30}
rightThreshold={40}
onSwipeableWillOpen={handleSwipe}
renderRightActions={renderRightButtons}>
{children}
</Swipeable>
);
}
const styles = StyleSheet.create({
leftAction: {
flex: 1,
backgroundColor: '#497AFC',
justifyContent: 'center',
},
actionText: {
color: 'white',
fontSize: 14,
backgroundColor: 'transparent',
padding: 10,
},
rightAction: {
alignItems: 'center',
flex: 1,
justifyContent: 'center',
},
});
import React, { createContext, useMemo, useState } from 'react';
const swipeContextValues = {
openedItemKey: '',
setOpenedItemKey: () => {},
isFocusedScreen: false,
};
export const SwipeContext = createContext(swipeContextValues);
export function SwipeProvider({
initialOpenedItemKey = '',
children,
isFocusedScreen,
}) {
const [openedItemKey, setOpenedItemKey] = useState(initialOpenedItemKey);
const value = useMemo(() => {
return {
openedItemKey,
setOpenedItemKey,
isFocusedScreen,
};
}, [openedItemKey, isFocusedScreen]);
return (
<SwipeContext.Provider value={value}>{children}</SwipeContext.Provider>
);
}
SwipeProvider.Context = SwipeContext;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment