1- import React , { useImperativeHandle , forwardRef , useRef , useCallback } from 'react' ;
1+ import React , { useImperativeHandle , forwardRef , useRef } from 'react' ;
22import { Animated , StyleSheet , View , Text , I18nManager , StyleProp , ViewStyle } from 'react-native' ;
33import { RectButton } from 'react-native-gesture-handler' ;
44import Swipeable from 'react-native-gesture-handler/Swipeable' ;
@@ -8,10 +8,10 @@ export interface Column {
88 text : string ;
99 /** 背景色 */
1010 color : string ;
11- /** 滑动距离多少出现 */
12- x ?: number ;
1311 /** 点击元素触发 */
1412 onPress ?: ( ) => void ;
13+ /** 是否禁用 */
14+ disabled ?: boolean ;
1515 /** 自定义元素 */
1616 render ?: ( text : string , record : Column , index : number ) => React . ReactNode ;
1717}
@@ -21,7 +21,8 @@ export interface SwipeActionProps {
2121 right ?: Array < Column > ;
2222 /** 左边滑动出来的元素 */
2323 left ?: Array < Column > ;
24- swipeWidth ?: string | number ;
24+ /** 按钮宽度 默认60 */
25+ buttonWidth ?: number ;
2526 enableTrackpadTwoFingerGesture ?: boolean ;
2627 friction ?: number ;
2728 leftThreshold ?: number ;
@@ -53,68 +54,49 @@ export interface SwipeActionProps {
5354}
5455
5556const SwipeAction = ( props : SwipeActionProps , ref : any ) => {
56- const { children, right = [ ] , left = [ ] , swipeWidth = '20%' , ...others } = props ;
57+ const { children, right = [ ] , left = [ ] , buttonWidth = 60 , ...others } = props ;
5758 const swipeableRef : React . MutableRefObject < null > = useRef ( null ) ;
5859
59- const renderRight = useCallback ( ( ) => {
60- return renderRightAction ;
61- } , [ right , swipeWidth ] ) ;
62-
63- const renderLeft = useCallback ( ( ) => {
64- return renderLeftAction ;
65- } , [ left , swipeWidth ] ) ;
66-
67- // 右侧滑出
68- const renderRightAction = ( progress : Animated . AnimatedInterpolation ) => {
69- return (
70- right &&
71- right . map ( ( { x = 1 , text, color, onPress, render } , idx ) => {
72- const trans = progress . interpolate ( {
73- inputRange : [ 0 , 1 ] ,
74- outputRange : [ x , 0 ] ,
75- } ) ;
76- return (
77- < View key = { idx } style = { [ styles . viewActions , { width : swipeWidth } ] } >
78- < Animated . View style = { { flex : 1 , transform : [ { translateX : trans } ] } } >
79- < RectButton
80- style = { [ styles . rightAction , { backgroundColor : color } ] }
81- onPress = { ( ) => {
82- onPress && onPress ( ) ;
83- } }
84- >
85- { render ? render ( text , right [ idx ] , idx ) : < Text style = { styles . actionText } > { text } </ Text > }
86- </ RectButton >
87- </ Animated . View >
88- </ View >
89- ) ;
90- } )
91- ) ;
92- } ;
93- // 左侧滑出
94- const renderLeftAction = ( progress : Animated . AnimatedInterpolation , dragX : any ) => {
60+ // 滑出
61+ const renderRightAction = ( progress : Animated . AnimatedInterpolation , dragX : any , isLeft = true ) => {
62+ const buttons = isLeft ? left : right ;
63+ if ( ! buttons ) {
64+ return null ;
65+ }
66+ const length = buttons . length ;
67+ const width = buttonWidth * length ;
9568 return (
96- left &&
97- left . map ( ( { text, color, onPress, render } , idx ) => {
98- const trans = dragX . interpolate ( {
99- inputRange : [ 0 , 50 , 100 , 101 ] ,
100- outputRange : [ - 20 , 0 , 0 , 1 ] ,
101- extrapolate : 'clamp' ,
102- } ) ;
103- return (
104- < View style = { [ styles . viewActions , { width : swipeWidth } ] } key = { idx } >
105- < Animated . View style = { [ { flex : 1 , transform : [ { translateX : trans } ] } ] } >
106- < RectButton
107- style = { [ styles . rightAction , { backgroundColor : color } ] }
108- onPress = { ( ) => {
109- onPress && onPress ( ) ;
110- } }
111- >
112- { render ? render ( text , left [ idx ] , idx ) : < Text style = { styles . actionText } > { text } </ Text > }
113- </ RectButton >
114- </ Animated . View >
115- </ View >
116- ) ;
117- } )
69+ < View style = { [ styles . viewActions , { width : width } ] } >
70+ { buttons &&
71+ buttons . map ( ( { text, color, onPress, disabled, render } , idx ) => {
72+ const x = isLeft ? - idx * buttonWidth : ( length - idx ) * buttonWidth ;
73+ const trans = progress . interpolate ( {
74+ inputRange : [ 0 , 1 ] ,
75+ outputRange : [ x , 0 ] ,
76+ extrapolate : 'clamp' ,
77+ } ) ;
78+ return (
79+ < Animated . View style = { { flex : 1 , transform : [ { translateX : trans } ] } } >
80+ < RectButton
81+ style = { [ styles . rightAction , { backgroundColor : color } ] }
82+ onPress = { ( ) => {
83+ if ( disabled && disabled ) {
84+ return ;
85+ } else {
86+ onPress && onPress ( ) ;
87+ }
88+ } }
89+ >
90+ { React . isValidElement ( render ) ? (
91+ render ( text , right [ idx ] , idx )
92+ ) : (
93+ < Text style = { [ styles . actionText ] } > { text } </ Text >
94+ ) }
95+ </ RectButton >
96+ </ Animated . View >
97+ ) ;
98+ } ) }
99+ </ View >
118100 ) ;
119101 } ;
120102
@@ -128,11 +110,10 @@ const SwipeAction = (props: SwipeActionProps, ref: any) => {
128110 ref = { swipeableRef }
129111 friction = { 2 }
130112 enableTrackpadTwoFingerGesture
131- rightThreshold = { 50 }
132- leftThreshold = { 50 }
133- overshootRight = { false }
134- renderRightActions = { renderRight ( ) }
135- renderLeftActions = { renderLeft ( ) }
113+ leftThreshold = { 30 }
114+ rightThreshold = { 40 }
115+ renderRightActions = { ( progress , dragX ) => renderRightAction ( progress , dragX , false ) }
116+ renderLeftActions = { ( progress , dragX ) => renderRightAction ( progress , dragX , true ) }
136117 { ...others }
137118 >
138119 { children && children }
@@ -141,13 +122,9 @@ const SwipeAction = (props: SwipeActionProps, ref: any) => {
141122} ;
142123
143124const styles = StyleSheet . create ( {
144- leftAction : {
145- alignItems : 'center' ,
146- flex : 1 ,
147- justifyContent : 'center' ,
148- } ,
149125 actionText : {
150126 color : 'white' ,
127+ fontSize : 16 ,
151128 backgroundColor : 'transparent' ,
152129 textAlign : 'center' ,
153130 } ,
0 commit comments