react-native-gesture-handler 2.22.0 → 2.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,9 +18,13 @@ import {
18
18
  import type { PanGestureHandlerProps } from '../handlers/PanGestureHandler';
19
19
  import type { PanGestureHandlerEventPayload } from '../handlers/GestureHandlerEventPayload';
20
20
  import Animated, {
21
+ ReduceMotion,
21
22
  SharedValue,
22
23
  interpolate,
24
+ measure,
23
25
  runOnJS,
26
+ runOnUI,
27
+ useAnimatedRef,
24
28
  useAnimatedStyle,
25
29
  useSharedValue,
26
30
  withSpring,
@@ -256,20 +260,9 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
256
260
  const leftWidth = useSharedValue<number>(0);
257
261
  const rightWidth = useSharedValue<number>(0);
258
262
 
259
- // used for synchronizing layout measurements between JS and UI
260
- const rightOffset = useSharedValue<number | null>(null);
261
-
262
263
  const showLeftProgress = useSharedValue<number>(0);
263
264
  const showRightProgress = useSharedValue<number>(0);
264
265
 
265
- const updateRightElementWidth = useCallback(() => {
266
- 'worklet';
267
- if (rightOffset.value === null) {
268
- rightOffset.value = rowWidth.value;
269
- }
270
- rightWidth.value = Math.max(0, rowWidth.value - rightOffset.value);
271
- }, [rightOffset, rightWidth, rowWidth]);
272
-
273
266
  const updateAnimatedEvent = useCallback(() => {
274
267
  'worklet';
275
268
 
@@ -371,11 +364,12 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
371
364
  'worklet';
372
365
 
373
366
  const translationSpringConfig = {
374
- duration: 1000,
375
- dampingRatio: 0.9,
376
- stiffness: 500,
367
+ mass: 2,
368
+ damping: 1000,
369
+ stiffness: 700,
377
370
  velocity: velocityX,
378
371
  overshootClamping: true,
372
+ reduceMotion: ReduceMotion.System,
379
373
  ...animationOptions,
380
374
  };
381
375
 
@@ -411,16 +405,17 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
411
405
  }
412
406
  );
413
407
 
414
- const progressTarget = toValue === 0 ? 0 : 1;
408
+ const progressTarget = toValue === 0 ? 0 : 1 * Math.sign(toValue);
409
+
410
+ showLeftProgress.value = withSpring(
411
+ Math.max(progressTarget, 0),
412
+ progressSpringConfig
413
+ );
415
414
 
416
- showLeftProgress.value =
417
- leftWidth.value > 0
418
- ? withSpring(progressTarget, progressSpringConfig)
419
- : 0;
420
- showRightProgress.value =
421
- rightWidth.value > 0
422
- ? withSpring(progressTarget, progressSpringConfig)
423
- : 0;
415
+ showRightProgress.value = withSpring(
416
+ Math.max(-progressTarget, 0),
417
+ progressSpringConfig
418
+ );
424
419
 
425
420
  dispatchImmediateEvents(frozenRowState, toValue);
426
421
 
@@ -439,20 +434,66 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
439
434
  ]
440
435
  );
441
436
 
437
+ const leftLayoutRef = useAnimatedRef();
438
+ const leftWrapperLayoutRef = useAnimatedRef();
439
+ const rightLayoutRef = useAnimatedRef();
440
+
441
+ const updateElementWidths = useCallback(() => {
442
+ 'worklet';
443
+ const leftLayout = measure(leftLayoutRef);
444
+ const leftWrapperLayout = measure(leftWrapperLayoutRef);
445
+ const rightLayout = measure(rightLayoutRef);
446
+ leftWidth.value =
447
+ (leftLayout?.pageX ?? 0) - (leftWrapperLayout?.pageX ?? 0);
448
+
449
+ rightWidth.value =
450
+ rowWidth.value -
451
+ (rightLayout?.pageX ?? rowWidth.value) +
452
+ (leftWrapperLayout?.pageX ?? 0);
453
+ }, [
454
+ leftLayoutRef,
455
+ leftWrapperLayoutRef,
456
+ rightLayoutRef,
457
+ leftWidth,
458
+ rightWidth,
459
+ rowWidth.value,
460
+ ]);
461
+
442
462
  const swipeableMethods = useMemo<SwipeableMethods>(
443
463
  () => ({
444
464
  close() {
445
465
  'worklet';
446
- animateRow(0);
466
+ if (_WORKLET) {
467
+ animateRow(0);
468
+ return;
469
+ }
470
+ runOnUI(() => {
471
+ animateRow(0);
472
+ })();
447
473
  },
448
474
  openLeft() {
449
475
  'worklet';
450
- animateRow(leftWidth.value);
476
+ if (_WORKLET) {
477
+ updateElementWidths();
478
+ animateRow(leftWidth.value);
479
+ return;
480
+ }
481
+ runOnUI(() => {
482
+ updateElementWidths();
483
+ animateRow(leftWidth.value);
484
+ })();
451
485
  },
452
486
  openRight() {
453
487
  'worklet';
454
- // rightOffset and rowWidth are already much sooner than rightWidth
455
- animateRow((rightOffset.value ?? 0) - rowWidth.value);
488
+ if (_WORKLET) {
489
+ updateElementWidths();
490
+ animateRow(-rightWidth.value);
491
+ return;
492
+ }
493
+ runOnUI(() => {
494
+ updateElementWidths();
495
+ animateRow(-rightWidth.value);
496
+ })();
456
497
  },
457
498
  reset() {
458
499
  'worklet';
@@ -463,14 +504,14 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
463
504
  },
464
505
  }),
465
506
  [
507
+ animateRow,
508
+ updateElementWidths,
466
509
  leftWidth,
467
- rightOffset,
468
- rowWidth,
510
+ rightWidth,
469
511
  userDrag,
470
512
  showLeftProgress,
471
513
  appliedTranslation,
472
514
  rowState,
473
- animateRow,
474
515
  ]
475
516
  );
476
517
 
@@ -481,49 +522,61 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
481
522
  [rowWidth]
482
523
  );
483
524
 
525
+ // As stated in `Dimensions.get` docstring, this function should be called on every render
526
+ // since dimensions may change (e.g. orientation change)
527
+
528
+ const leftActionAnimation = useAnimatedStyle(() => {
529
+ return {
530
+ opacity: showLeftProgress.value === 0 ? 0 : 1,
531
+ };
532
+ });
533
+
484
534
  const leftElement = useCallback(
485
535
  () => (
486
- <Animated.View style={[styles.leftActions]}>
536
+ <Animated.View
537
+ ref={leftWrapperLayoutRef}
538
+ style={[styles.leftActions, leftActionAnimation]}>
487
539
  {renderLeftActions?.(
488
540
  showLeftProgress,
489
541
  appliedTranslation,
490
542
  swipeableMethods
491
543
  )}
492
- <View
493
- onLayout={({ nativeEvent }) =>
494
- (leftWidth.value = nativeEvent.layout.x)
495
- }
496
- />
544
+ <Animated.View ref={leftLayoutRef} />
497
545
  </Animated.View>
498
546
  ),
499
547
  [
500
548
  appliedTranslation,
501
- leftWidth,
549
+ leftActionAnimation,
550
+ leftLayoutRef,
551
+ leftWrapperLayoutRef,
502
552
  renderLeftActions,
503
553
  showLeftProgress,
504
554
  swipeableMethods,
505
555
  ]
506
556
  );
507
557
 
558
+ const rightActionAnimation = useAnimatedStyle(() => {
559
+ return {
560
+ opacity: showRightProgress.value === 0 ? 0 : 1,
561
+ };
562
+ });
563
+
508
564
  const rightElement = useCallback(
509
565
  () => (
510
- <Animated.View style={[styles.rightActions]}>
566
+ <Animated.View style={[styles.rightActions, rightActionAnimation]}>
511
567
  {renderRightActions?.(
512
568
  showRightProgress,
513
569
  appliedTranslation,
514
570
  swipeableMethods
515
571
  )}
516
- <View
517
- onLayout={({ nativeEvent }) => {
518
- rightOffset.value = nativeEvent.layout.x;
519
- }}
520
- />
572
+ <Animated.View ref={rightLayoutRef} />
521
573
  </Animated.View>
522
574
  ),
523
575
  [
524
576
  appliedTranslation,
525
577
  renderRightActions,
526
- rightOffset,
578
+ rightActionAnimation,
579
+ rightLayoutRef,
527
580
  showRightProgress,
528
581
  swipeableMethods,
529
582
  ]
@@ -535,8 +588,6 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
535
588
  const { velocityX } = event;
536
589
  userDrag.value = event.translationX;
537
590
 
538
- updateRightElementWidth();
539
-
540
591
  const leftThresholdProp = leftThreshold ?? leftWidth.value / 2;
541
592
  const rightThresholdProp = rightThreshold ?? rightWidth.value / 2;
542
593
 
@@ -574,7 +625,6 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
574
625
  rightWidth,
575
626
  rowState,
576
627
  userDrag,
577
- updateRightElementWidth,
578
628
  ]
579
629
  );
580
630
 
@@ -603,9 +653,7 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
603
653
  .enabled(enabled !== false)
604
654
  .enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture)
605
655
  .activeOffsetX([-dragOffsetFromRightEdge, dragOffsetFromLeftEdge])
606
- .onStart(() => {
607
- updateRightElementWidth();
608
- })
656
+ .onStart(updateElementWidths)
609
657
  .onUpdate(
610
658
  (event: GestureUpdateEvent<PanGestureHandlerEventPayload>) => {
611
659
  userDrag.value = event.translationX;
@@ -650,7 +698,7 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
650
698
  onSwipeableOpenStartDrag,
651
699
  rowState,
652
700
  updateAnimatedEvent,
653
- updateRightElementWidth,
701
+ updateElementWidths,
654
702
  userDrag,
655
703
  ]
656
704
  );
@@ -700,9 +748,11 @@ const styles = StyleSheet.create({
700
748
  leftActions: {
701
749
  ...StyleSheet.absoluteFillObject,
702
750
  flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row',
751
+ overflow: 'hidden',
703
752
  },
704
753
  rightActions: {
705
754
  ...StyleSheet.absoluteFillObject,
706
755
  flexDirection: I18nManager.isRTL ? 'row' : 'row-reverse',
756
+ overflow: 'hidden',
707
757
  },
708
758
  });
@@ -29,17 +29,23 @@ export default function createNativeWrapper<P>(
29
29
  P & NativeViewGestureHandlerProps
30
30
  >((props, ref) => {
31
31
  // Filter out props that should be passed to gesture handler wrapper
32
- const gestureHandlerProps = Object.keys(props).reduce(
32
+ const { gestureHandlerProps, childProps } = Object.keys(props).reduce(
33
33
  (res, key) => {
34
34
  // TS being overly protective with it's types, see https://github.com/microsoft/TypeScript/issues/26255#issuecomment-458013731 for more info
35
35
  const allowedKeys: readonly string[] = NATIVE_WRAPPER_PROPS_FILTER;
36
36
  if (allowedKeys.includes(key)) {
37
37
  // @ts-ignore FIXME(TS)
38
- res[key] = props[key];
38
+ res.gestureHandlerProps[key] = props[key];
39
+ } else {
40
+ // @ts-ignore FIXME(TS)
41
+ res.childProps[key] = props[key];
39
42
  }
40
43
  return res;
41
44
  },
42
- { ...config } // Watch out not to modify config
45
+ {
46
+ gestureHandlerProps: { ...config }, // Watch out not to modify config
47
+ childProps: { enabled: props.enabled } as P,
48
+ }
43
49
  );
44
50
  const _ref = useRef<React.ComponentType<P>>();
45
51
  const _gestureHandlerRef = useRef<React.ComponentType<P>>();
@@ -63,7 +69,7 @@ export default function createNativeWrapper<P>(
63
69
  {...gestureHandlerProps}
64
70
  // @ts-ignore TODO(TS)
65
71
  ref={_gestureHandlerRef}>
66
- <Component {...props} ref={_ref} />
72
+ <Component {...childProps} ref={_ref} />
67
73
  </NativeViewGestureHandler>
68
74
  );
69
75
  });