@uiw/react-native
Version:
UIW for React Native
94 lines (93 loc) • 2.72 kB
JavaScript
import React, { useImperativeHandle, forwardRef, useRef } from 'react';
import { Animated, StyleSheet, View, Text, I18nManager } from 'react-native';
import { RectButton } from 'react-native-gesture-handler';
import Swipeable from 'react-native-gesture-handler/Swipeable';
const SwipeAction = (props, ref) => {
const {
right = [],
left = [],
buttonWidth = 60,
children,
actionViewStyle,
rectButtonStyle,
...others
} = props;
const swipeableRef = useRef(null);
useImperativeHandle(ref, () => ({
swipeable: swipeableRef.current
}));
// 滑出
const renderRightAction = (progress, dragX, isLeft = true) => {
const buttons = isLeft ? left : right;
if (!buttons) {
return null;
}
const length = buttons.length;
const width = buttonWidth * length;
return <View style={[styles.viewActions, {
width: width,
...actionViewStyle
}]}>
{buttons && buttons.map(({
text,
color,
onPress,
disabled,
render
}, idx) => {
const x = isLeft ? -idx * buttonWidth : (length - idx) * buttonWidth;
const trans = progress.interpolate({
inputRange: [0, 1],
outputRange: [x, 0],
extrapolate: 'clamp'
});
return <Animated.View key={idx} style={{
flex: 1,
transform: [{
translateX: trans
}]
}}>
<RectButton style={[styles.rightAction, {
backgroundColor: color,
...rectButtonStyle
}]} onPress={() => {
if (disabled && disabled) {
return;
} else {
onPress && onPress();
}
}}>
{React.isValidElement(render) ? render(text, right[idx], idx) : <Text style={[styles.actionText]}>{text}</Text>}
</RectButton>
</Animated.View>;
})}
</View>;
};
const commonProps = {
ref: swipeableRef,
friction: 2,
enableTrackpadTwoFingerGesture: true,
rightThreshold: 40,
renderRightActions: (progress, dragX) => renderRightAction(progress, dragX, false),
renderLeftActions: (progress, dragX) => renderRightAction(progress, dragX, true),
...others
};
return <Swipeable {...commonProps}>{children && children}</Swipeable>;
};
const styles = StyleSheet.create({
actionText: {
color: 'white',
fontSize: 16,
backgroundColor: 'transparent',
textAlign: 'center'
},
rightAction: {
alignItems: 'center',
flex: 1,
justifyContent: 'center'
},
viewActions: {
flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row'
}
});
export default forwardRef(SwipeAction);