@@ -41,6 +41,11 @@ type SwipeableExcludes = Exclude<
41
41
'onGestureEvent' | 'onHandlerStateChange'
42
42
> ;
43
43
44
+ enum SwipeDirection {
45
+ LEFT = 'left' ,
46
+ RIGHT = 'right' ,
47
+ }
48
+
44
49
export interface SwipeableProps
45
50
extends Pick < PanGestureHandlerProps , SwipeableExcludes > {
46
51
/**
@@ -110,37 +115,45 @@ export interface SwipeableProps
110
115
* Called when action panel gets open (either right or left).
111
116
*/
112
117
onSwipeableOpen ?: (
113
- direction : 'left' | 'right' ,
118
+ direction : SwipeDirection . LEFT | SwipeDirection . RIGHT ,
114
119
swipeable : SwipeableMethods
115
120
) => void ;
116
121
117
122
/**
118
123
* Called when action panel is closed.
119
124
*/
120
125
onSwipeableClose ?: (
121
- direction : 'left' | 'right' ,
126
+ direction : SwipeDirection . LEFT | SwipeDirection . RIGHT ,
122
127
swipeable : SwipeableMethods
123
128
) => void ;
124
129
125
130
/**
126
131
* Called when action panel starts animating on open (either right or left).
127
132
*/
128
- onSwipeableWillOpen ?: ( direction : 'left' | 'right' ) => void ;
133
+ onSwipeableWillOpen ?: (
134
+ direction : SwipeDirection . LEFT | SwipeDirection . RIGHT
135
+ ) => void ;
129
136
130
137
/**
131
138
* Called when action panel starts animating on close.
132
139
*/
133
- onSwipeableWillClose ?: ( direction : 'left' | 'right' ) => void ;
140
+ onSwipeableWillClose ?: (
141
+ direction : SwipeDirection . LEFT | SwipeDirection . RIGHT
142
+ ) => void ;
134
143
135
144
/**
136
145
* Called when action panel starts being shown on dragging to open.
137
146
*/
138
- onSwipeableOpenStartDrag ?: ( direction : 'left' | 'right' ) => void ;
147
+ onSwipeableOpenStartDrag ?: (
148
+ direction : SwipeDirection . LEFT | SwipeDirection . RIGHT
149
+ ) => void ;
139
150
140
151
/**
141
152
* Called when action panel starts being shown on dragging to close.
142
153
*/
143
- onSwipeableCloseStartDrag ?: ( direction : 'left' | 'right' ) => void ;
154
+ onSwipeableCloseStartDrag ?: (
155
+ direction : SwipeDirection . LEFT | SwipeDirection . RIGHT
156
+ ) => void ;
144
157
145
158
/**
146
159
* `progress`: Equals `0` when `swipeable` is closed, `1` when `swipeable` is opened.
@@ -270,16 +283,6 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
270
283
rightWidth . value = Math . max ( 0 , rowWidth . value - rightOffset . value ) ;
271
284
} ;
272
285
273
- const calculateCurrentOffset = useCallback ( ( ) => {
274
- 'worklet' ;
275
- updateRightElementWidth ( ) ;
276
- return rowState . value === 1
277
- ? leftWidth . value
278
- : rowState . value === - 1
279
- ? - rowWidth . value - rightOffset . value !
280
- : 0 ;
281
- } , [ leftWidth , rightOffset , rowState , rowWidth ] ) ;
282
-
283
286
const updateAnimatedEvent = ( ) => {
284
287
'worklet' ;
285
288
@@ -334,27 +337,30 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
334
337
335
338
const dispatchImmediateEvents = useCallback (
336
339
( fromValue : number , toValue : number ) => {
337
- if ( toValue > 0 && onSwipeableWillOpen ) {
338
- onSwipeableWillOpen ( 'left' ) ;
339
- } else if ( toValue < 0 && onSwipeableWillOpen ) {
340
- onSwipeableWillOpen ( 'right' ) ;
341
- } else if ( onSwipeableWillClose ) {
342
- const closingDirection = fromValue > 0 ? 'left' : 'right' ;
343
- onSwipeableWillClose ( closingDirection ) ;
340
+ if ( toValue > 0 ) {
341
+ onSwipeableWillOpen ?.( SwipeDirection . RIGHT ) ;
342
+ } else if ( toValue < 0 ) {
343
+ onSwipeableWillOpen ?.( SwipeDirection . LEFT ) ;
344
+ } else {
345
+ onSwipeableWillClose ?.(
346
+ fromValue > 0 ? SwipeDirection . LEFT : SwipeDirection . RIGHT
347
+ ) ;
344
348
}
345
349
} ,
346
350
[ onSwipeableWillClose , onSwipeableWillOpen ]
347
351
) ;
348
352
349
353
const dispatchEndEvents = useCallback (
350
354
( fromValue : number , toValue : number ) => {
351
- if ( toValue > 0 && onSwipeableOpen ) {
352
- onSwipeableOpen ( 'left' , swipeableMethods . current ) ;
353
- } else if ( toValue < 0 && onSwipeableOpen ) {
354
- onSwipeableOpen ( 'right' , swipeableMethods . current ) ;
355
- } else if ( onSwipeableClose ) {
356
- const closingDirection = fromValue > 0 ? 'left' : 'right' ;
357
- onSwipeableClose ( closingDirection , swipeableMethods . current ) ;
355
+ if ( toValue > 0 ) {
356
+ onSwipeableOpen ?.( SwipeDirection . RIGHT , swipeableMethods . current ) ;
357
+ } else if ( toValue < 0 ) {
358
+ onSwipeableOpen ?.( SwipeDirection . LEFT , swipeableMethods . current ) ;
359
+ } else {
360
+ onSwipeableClose ?.(
361
+ fromValue > 0 ? SwipeDirection . LEFT : SwipeDirection . RIGHT ,
362
+ swipeableMethods . current
363
+ ) ;
358
364
}
359
365
} ,
360
366
[ onSwipeableClose , onSwipeableOpen ]
@@ -363,9 +369,8 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
363
369
const animationOptionsProp = animationOptions ;
364
370
365
371
const animateRow = useCallback (
366
- ( fromValue : number , toValue : number , velocityX ?: number ) => {
372
+ ( toValue : number , velocityX ?: number ) => {
367
373
'worklet' ;
368
- rowState . value = Math . sign ( toValue ) ;
369
374
370
375
const translationSpringConfig = {
371
376
duration : 1000 ,
@@ -376,17 +381,34 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
376
381
...animationOptionsProp ,
377
382
} ;
378
383
384
+ const isClosing = toValue === 0 ;
385
+ const moveToRight = isClosing ? rowState . value < 0 : toValue > 0 ;
386
+
387
+ const usedWidth = isClosing
388
+ ? moveToRight
389
+ ? rightWidth . value
390
+ : leftWidth . value
391
+ : moveToRight
392
+ ? leftWidth . value
393
+ : rightWidth . value ;
394
+
379
395
const progressSpringConfig = {
380
396
...translationSpringConfig ,
381
- velocity : 0 ,
397
+ restDisplacementThreshold : 0.01 ,
398
+ restSpeedThreshold : 0.01 ,
399
+ velocity :
400
+ velocityX &&
401
+ interpolate ( velocityX , [ - usedWidth , usedWidth ] , [ - 1 , 1 ] ) ,
382
402
} ;
383
403
404
+ const frozenRowState = rowState . value ;
405
+
384
406
appliedTranslation . value = withSpring (
385
407
toValue ,
386
408
translationSpringConfig ,
387
409
( isFinished ) => {
388
410
if ( isFinished ) {
389
- runOnJS ( dispatchEndEvents ) ( fromValue , toValue ) ;
411
+ runOnJS ( dispatchEndEvents ) ( frozenRowState , toValue ) ;
390
412
}
391
413
}
392
414
) ;
@@ -402,7 +424,9 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
402
424
? withSpring ( progressTarget , progressSpringConfig )
403
425
: 0 ;
404
426
405
- runOnJS ( dispatchImmediateEvents ) ( fromValue , toValue ) ;
427
+ runOnJS ( dispatchImmediateEvents ) ( frozenRowState , toValue ) ;
428
+
429
+ rowState . value = Math . sign ( toValue ) ;
406
430
} ,
407
431
[
408
432
rowState ,
@@ -432,15 +456,15 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
432
456
swipeableMethods . current = {
433
457
close ( ) {
434
458
'worklet' ;
435
- animateRow ( calculateCurrentOffset ( ) , 0 ) ;
459
+ animateRow ( 0 ) ;
436
460
} ,
437
461
openLeft ( ) {
438
462
'worklet' ;
439
- animateRow ( calculateCurrentOffset ( ) , leftWidth . value ) ;
463
+ animateRow ( leftWidth . value ) ;
440
464
} ,
441
465
openRight ( ) {
442
466
'worklet' ;
443
- animateRow ( calculateCurrentOffset ( ) , - rightWidth . value ) ;
467
+ animateRow ( - rightWidth . value ) ;
444
468
} ,
445
469
reset ( ) {
446
470
'worklet' ;
@@ -496,7 +520,6 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
496
520
const leftThreshold = leftThresholdProp ?? leftWidth . value / 2 ;
497
521
const rightThreshold = rightThresholdProp ?? rightWidth . value / 2 ;
498
522
499
- const startOffsetX = calculateCurrentOffset ( ) + userDrag . value / friction ;
500
523
const translationX = ( userDrag . value + DRAG_TOSS * velocityX ) / friction ;
501
524
502
525
let toValue = 0 ;
@@ -519,12 +542,12 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
519
542
}
520
543
}
521
544
522
- animateRow ( startOffsetX , toValue , velocityX / friction ) ;
545
+ animateRow ( toValue , velocityX / friction ) ;
523
546
} ;
524
547
525
548
const close = ( ) => {
526
549
'worklet' ;
527
- animateRow ( calculateCurrentOffset ( ) , 0 ) ;
550
+ animateRow ( 0 ) ;
528
551
} ;
529
552
530
553
const tapGesture = Gesture . Tap ( ) . onStart ( ( ) => {
@@ -541,12 +564,12 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
541
564
542
565
const direction =
543
566
rowState . value === - 1
544
- ? 'right'
567
+ ? SwipeDirection . RIGHT
545
568
: rowState . value === 1
546
- ? 'left'
569
+ ? SwipeDirection . LEFT
547
570
: event . translationX > 0
548
- ? 'left'
549
- : 'right' ;
571
+ ? SwipeDirection . RIGHT
572
+ : SwipeDirection . LEFT ;
550
573
551
574
if ( ! dragStarted . value ) {
552
575
dragStarted . value = true ;
0 commit comments