11import React , { useImperativeHandle , forwardRef , useRef } from 'react' ;
2- import { Animated , StyleSheet , View , Text , I18nManager , StyleProp , ViewStyle } from 'react-native' ;
2+ import { Animated , StyleSheet , View , Text , I18nManager , StyleProp , ViewStyle , Dimensions } from 'react-native' ;
33import { RectButton } from 'react-native-gesture-handler' ;
44import Swipeable from 'react-native-gesture-handler/Swipeable' ;
55
66export interface SwipeActionProps {
7- right : Array < {
7+ right ? : Array < {
88 text : string ;
99 color : string ;
1010 x ?: number ;
1111 onPress ?: ( ) => void ;
1212 } > ;
13+ left ?: Array < {
14+ text : string ;
15+ color : string ;
16+ onPress ?: ( ) => void ;
17+ } > ;
1318 enableTrackpadTwoFingerGesture ?: boolean ;
1419 friction ?: number ;
1520 leftThreshold ?: number ;
@@ -41,11 +46,10 @@ export interface SwipeActionProps {
4146}
4247
4348const SwipeAction = ( props : SwipeActionProps , ref : any ) => {
44- const { children, right = [ ] , ...others } = props ;
45- const swipeableRef : any = useRef ( null ) ;
46-
47- const close = ( ) => swipeableRef ?. current ?. close ( ) ;
49+ const { children, right = [ ] , left = [ ] , ...others } = props ;
50+ const swipeableRef : React . MutableRefObject < null > = useRef ( null ) ;
4851
52+ // 右侧滑出
4953 const renderRightAction = ( progress : Animated . AnimatedInterpolation ) => {
5054 return (
5155 right &&
@@ -58,7 +62,40 @@ const SwipeAction = (props: SwipeActionProps, ref: any) => {
5862 return (
5963 < View
6064 style = { {
61- width : 60 ,
65+ width : '20%' ,
66+ flexDirection : I18nManager . isRTL ? 'row-reverse' : 'row' ,
67+ } }
68+ >
69+ < Animated . View style = { { flex : 1 , transform : [ { translateX : trans } ] } } key = { idx } >
70+ < RectButton
71+ style = { [ styles . rightAction , { backgroundColor : color } ] }
72+ onPress = { ( ) => {
73+ onPress && onPress ( ) ;
74+ } }
75+ >
76+ < Text style = { styles . actionText } > { text } </ Text >
77+ </ RectButton >
78+ </ Animated . View >
79+ </ View >
80+ ) ;
81+ } )
82+ ) ;
83+ } ;
84+ // 左侧滑出
85+ const renderLeftAction = ( progress : Animated . AnimatedInterpolation , dragX : any ) => {
86+ return (
87+ left &&
88+ left . length > 0 &&
89+ left . map ( ( { text, color, onPress } , idx ) => {
90+ const trans = dragX . interpolate ( {
91+ inputRange : [ 0 , 50 , 100 , 101 ] ,
92+ outputRange : [ - 20 , 0 , 0 , 1 ] ,
93+ extrapolate : 'clamp' ,
94+ } ) ;
95+ return (
96+ < View
97+ style = { {
98+ width : '20%' ,
6299 flexDirection : I18nManager . isRTL ? 'row-reverse' : 'row' ,
63100 } }
64101 >
@@ -67,7 +104,6 @@ const SwipeAction = (props: SwipeActionProps, ref: any) => {
67104 style = { [ styles . rightAction , { backgroundColor : color } ] }
68105 onPress = { ( ) => {
69106 onPress && onPress ( ) ;
70- close ( ) ;
71107 } }
72108 >
73109 < Text style = { styles . actionText } > { text } </ Text >
@@ -79,9 +115,9 @@ const SwipeAction = (props: SwipeActionProps, ref: any) => {
79115 ) ;
80116 } ;
81117
82- // 暴露给父组件调用的方法
83- useImperativeHandle ( ref , ( ) : any => ( {
84- close : close ,
118+ // 暴露给父组件调用 Swipeable上的方法
119+ useImperativeHandle ( ref , ( ) => ( {
120+ swipeable : swipeableRef . current ,
85121 } ) ) ;
86122
87123 return (
@@ -90,8 +126,10 @@ const SwipeAction = (props: SwipeActionProps, ref: any) => {
90126 friction = { 2 }
91127 enableTrackpadTwoFingerGesture
92128 rightThreshold = { 50 }
129+ leftThreshold = { 50 }
93130 overshootRight = { false }
94131 renderRightActions = { renderRightAction }
132+ renderLeftActions = { renderLeftAction }
95133 { ...others }
96134 >
97135 { children && children }
0 commit comments