From b3e67c9e0d553674e5fe85d2ed98006e8e089f9c Mon Sep 17 00:00:00 2001 From: Sultan Date: Fri, 10 Jan 2025 17:49:27 +0100 Subject: [PATCH 01/11] feat: Add `simultaneousGesture` to ReanimatedSwipable --- src/components/ReanimatedSwipeable.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/ReanimatedSwipeable.tsx b/src/components/ReanimatedSwipeable.tsx index 08e241b101..1b9e1bbbfa 100644 --- a/src/components/ReanimatedSwipeable.tsx +++ b/src/components/ReanimatedSwipeable.tsx @@ -9,6 +9,7 @@ import React, { useImperativeHandle, useMemo, } from 'react'; +import { GestureType } from '../handlers/gestures/gesture'; import { GestureObjects as Gesture } from '../handlers/gestures/gestureObjects'; import { GestureDetector } from '../handlers/gestures/GestureDetector'; import { @@ -202,6 +203,12 @@ export interface SwipeableProps * apply `flex: 1` */ childrenContainerStyle?: StyleProp; + + /** + * A base gesture object containing the configuration and callbacks to be + * used simultaneously with `Swipeable`'s gesture object. + */ + simultaneousGesture?: GestureType; } export interface SwipeableMethods { @@ -247,6 +254,7 @@ const Swipeable = forwardRef( onSwipeableClose, renderLeftActions, renderRightActions, + simultaneousGesture, ...remainingProps } = props; @@ -713,8 +721,12 @@ const Swipeable = forwardRef( [appliedTranslation, rowState] ); + const swipeableGesture = simultaneousGesture + ? Gesture.Simultaneous(panGesture, simultaneousGesture) + : panGesture; + const swipeableComponent = ( - + Date: Fri, 10 Jan 2025 18:27:51 +0100 Subject: [PATCH 02/11] update docs --- docs/docs/components/reanimated_swipeable.md | 4 ++++ src/components/ReanimatedSwipeable.tsx | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/docs/components/reanimated_swipeable.md b/docs/docs/components/reanimated_swipeable.md index 2c545a2b93..9e0753a7c4 100644 --- a/docs/docs/components/reanimated_swipeable.md +++ b/docs/docs/components/reanimated_swipeable.md @@ -128,6 +128,10 @@ style object for the container (`Animated.View`), for example to override `overf style object for the children container (`Animated.View`), for example to apply `flex: 1`. +### `simultaneousGesture` + +An optional gesture configuration that allows another gesture to be recognized simultaneously with the swipeable gesture. This can be useful for implementing complex gesture interactions where multiple gestures need to be detected at the same time. + ### `enableTrackpadTwoFingerGesture` (iOS only) Enables two-finger gestures on supported devices, for example iPads with trackpads. diff --git a/src/components/ReanimatedSwipeable.tsx b/src/components/ReanimatedSwipeable.tsx index 1b9e1bbbfa..7a761d76e5 100644 --- a/src/components/ReanimatedSwipeable.tsx +++ b/src/components/ReanimatedSwipeable.tsx @@ -206,7 +206,7 @@ export interface SwipeableProps /** * A base gesture object containing the configuration and callbacks to be - * used simultaneously with `Swipeable`'s gesture object. + * used with the swipeable's gesture handler. */ simultaneousGesture?: GestureType; } From c5721f0b174d61ddb67579f2df055dd5d41c7456 Mon Sep 17 00:00:00 2001 From: Sultan Date: Fri, 17 Jan 2025 15:58:56 +0100 Subject: [PATCH 03/11] refactor to use `simultaneousWithExternalGesture` + updating docs with example --- docs/docs/components/reanimated_swipeable.md | 16 ++- src/components/ReanimatedSwipeable.tsx | 126 ++++++++++--------- 2 files changed, 79 insertions(+), 63 deletions(-) diff --git a/docs/docs/components/reanimated_swipeable.md b/docs/docs/components/reanimated_swipeable.md index 9e0753a7c4..8c8b9c630a 100644 --- a/docs/docs/components/reanimated_swipeable.md +++ b/docs/docs/components/reanimated_swipeable.md @@ -128,9 +128,21 @@ style object for the container (`Animated.View`), for example to override `overf style object for the children container (`Animated.View`), for example to apply `flex: 1`. -### `simultaneousGesture` +### `simultaneousWithExternalGesture` -An optional gesture configuration that allows another gesture to be recognized simultaneously with the swipeable gesture. This can be useful for implementing complex gesture interactions where multiple gestures need to be detected at the same time. +An optional gesture configuration that enables another gesture to be recognized simultaneously with the swipeable gesture. This is useful for allowing swipeable gestures to work simultaneously with other gestures. + +For example, to enable a pan gesture alongside the swipeable gesture: + +```jsx +const panGesture = Gesture.Pan(); + + + + +``` + +More details can be found in the [gesture composition documentation](../fundamentals/gesture-composition.md#simultaneouswithexternalgesture). ### `enableTrackpadTwoFingerGesture` (iOS only) diff --git a/src/components/ReanimatedSwipeable.tsx b/src/components/ReanimatedSwipeable.tsx index 7a761d76e5..7ce3b02cb4 100644 --- a/src/components/ReanimatedSwipeable.tsx +++ b/src/components/ReanimatedSwipeable.tsx @@ -205,10 +205,10 @@ export interface SwipeableProps childrenContainerStyle?: StyleProp; /** - * A base gesture object containing the configuration and callbacks to be + * A gesture object containing the configuration and callbacks to be * used with the swipeable's gesture handler. */ - simultaneousGesture?: GestureType; + simultaneousWithExternalGesture?: GestureType; } export interface SwipeableMethods { @@ -254,7 +254,7 @@ const Swipeable = forwardRef( onSwipeableClose, renderLeftActions, renderRightActions, - simultaneousGesture, + simultaneousWithExternalGesture, ...remainingProps } = props; @@ -655,61 +655,69 @@ const Swipeable = forwardRef( [close, rowState] ); - const panGesture = useMemo( - () => - Gesture.Pan() - .enabled(enabled !== false) - .enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture) - .activeOffsetX([-dragOffsetFromRightEdge, dragOffsetFromLeftEdge]) - .onStart(updateElementWidths) - .onUpdate( - (event: GestureUpdateEvent) => { - userDrag.value = event.translationX; - - const direction = - rowState.value === -1 - ? SwipeDirection.RIGHT - : rowState.value === 1 - ? SwipeDirection.LEFT - : event.translationX > 0 - ? SwipeDirection.RIGHT - : SwipeDirection.LEFT; - - if (!dragStarted.value) { - dragStarted.value = true; - if (rowState.value === 0 && onSwipeableOpenStartDrag) { - runOnJS(onSwipeableOpenStartDrag)(direction); - } else if (onSwipeableCloseStartDrag) { - runOnJS(onSwipeableCloseStartDrag)(direction); - } + const panGesture = useMemo(() => { + const gesture = Gesture.Pan() + .enabled(enabled !== false) + .enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture) + .activeOffsetX([-dragOffsetFromRightEdge, dragOffsetFromLeftEdge]) + .onStart(updateElementWidths) + .onUpdate( + (event: GestureUpdateEvent) => { + userDrag.value = event.translationX; + + const direction = + rowState.value === -1 + ? SwipeDirection.RIGHT + : rowState.value === 1 + ? SwipeDirection.LEFT + : event.translationX > 0 + ? SwipeDirection.RIGHT + : SwipeDirection.LEFT; + + if (!dragStarted.value) { + dragStarted.value = true; + if (rowState.value === 0 && onSwipeableOpenStartDrag) { + runOnJS(onSwipeableOpenStartDrag)(direction); + } else if (onSwipeableCloseStartDrag) { + runOnJS(onSwipeableCloseStartDrag)(direction); } - - updateAnimatedEvent(); - } - ) - .onEnd( - (event: GestureStateChangeEvent) => { - handleRelease(event); } - ) - .onFinalize(() => { - dragStarted.value = false; - }), - [ - dragOffsetFromLeftEdge, - dragOffsetFromRightEdge, - dragStarted, - enableTrackpadTwoFingerGesture, - enabled, - handleRelease, - onSwipeableCloseStartDrag, - onSwipeableOpenStartDrag, - rowState, - updateAnimatedEvent, - updateElementWidths, - userDrag, - ] - ); + + updateAnimatedEvent(); + } + ) + .onEnd( + (event: GestureStateChangeEvent) => { + handleRelease(event); + } + ) + .onFinalize(() => { + dragStarted.value = false; + }); + + // Add simultaneousWithExternalGesture only if it has a value + if (simultaneousWithExternalGesture) { + gesture.simultaneousWithExternalGesture( + simultaneousWithExternalGesture + ); + } + + return gesture; + }, [ + dragOffsetFromLeftEdge, + dragOffsetFromRightEdge, + dragStarted, + enableTrackpadTwoFingerGesture, + enabled, + handleRelease, + onSwipeableCloseStartDrag, + onSwipeableOpenStartDrag, + rowState, + updateAnimatedEvent, + updateElementWidths, + userDrag, + simultaneousWithExternalGesture, + ]); useImperativeHandle(ref, () => swipeableMethods, [swipeableMethods]); @@ -721,12 +729,8 @@ const Swipeable = forwardRef( [appliedTranslation, rowState] ); - const swipeableGesture = simultaneousGesture - ? Gesture.Simultaneous(panGesture, simultaneousGesture) - : panGesture; - const swipeableComponent = ( - + Date: Mon, 27 Jan 2025 10:35:08 +0100 Subject: [PATCH 04/11] update example app tsconfig --- example/tsconfig.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/example/tsconfig.json b/example/tsconfig.json index 9b85006f51..bf0d3c670c 100644 --- a/example/tsconfig.json +++ b/example/tsconfig.json @@ -5,6 +5,9 @@ "baseUrl": ".", "paths": { "react-native-gesture-handler": ["../src/index.ts"], + "react-native-gesture-handler/ReanimatedSwipeable": [ + "../src/components/ReanimatedSwipeable.tsx" + ], "react-native-gesture-handler/jest-utils": ["../src/jestUtils/index.ts"] } }, From 633b18d345b23bb66fdc9d8d0ecb4152f0a9deba Mon Sep 17 00:00:00 2001 From: Sultan Date: Mon, 27 Jan 2025 11:27:33 +0100 Subject: [PATCH 05/11] refactor implementation --- docs/docs/components/reanimated_swipeable.md | 6 +- src/components/ReanimatedSwipeable.tsx | 124 +++++++++---------- 2 files changed, 63 insertions(+), 67 deletions(-) diff --git a/docs/docs/components/reanimated_swipeable.md b/docs/docs/components/reanimated_swipeable.md index 8c8b9c630a..205635ea44 100644 --- a/docs/docs/components/reanimated_swipeable.md +++ b/docs/docs/components/reanimated_swipeable.md @@ -128,9 +128,9 @@ style object for the container (`Animated.View`), for example to override `overf style object for the children container (`Animated.View`), for example to apply `flex: 1`. -### `simultaneousWithExternalGesture` +### `simultaneousWithExternalGestures` -An optional gesture configuration that enables another gesture to be recognized simultaneously with the swipeable gesture. This is useful for allowing swipeable gestures to work simultaneously with other gestures. +An optional gesture configuration that enable other gestures to be recognized simultaneously with the swipeable gesture. This is useful for allowing swipeable gestures to work simultaneously with other gestures. For example, to enable a pan gesture alongside the swipeable gesture: @@ -138,7 +138,7 @@ For example, to enable a pan gesture alongside the swipeable gesture: const panGesture = Gesture.Pan(); - + ``` diff --git a/src/components/ReanimatedSwipeable.tsx b/src/components/ReanimatedSwipeable.tsx index 7ce3b02cb4..5311faa496 100644 --- a/src/components/ReanimatedSwipeable.tsx +++ b/src/components/ReanimatedSwipeable.tsx @@ -9,7 +9,7 @@ import React, { useImperativeHandle, useMemo, } from 'react'; -import { GestureType } from '../handlers/gestures/gesture'; +import { GestureRef } from '../handlers/gestures/gesture'; import { GestureObjects as Gesture } from '../handlers/gestures/gestureObjects'; import { GestureDetector } from '../handlers/gestures/GestureDetector'; import { @@ -208,7 +208,7 @@ export interface SwipeableProps * A gesture object containing the configuration and callbacks to be * used with the swipeable's gesture handler. */ - simultaneousWithExternalGesture?: GestureType; + simultaneousWithExternalGestures?: Exclude[]; } export interface SwipeableMethods { @@ -254,7 +254,7 @@ const Swipeable = forwardRef( onSwipeableClose, renderLeftActions, renderRightActions, - simultaneousWithExternalGesture, + simultaneousWithExternalGestures, ...remainingProps } = props; @@ -655,69 +655,65 @@ const Swipeable = forwardRef( [close, rowState] ); - const panGesture = useMemo(() => { - const gesture = Gesture.Pan() - .enabled(enabled !== false) - .enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture) - .activeOffsetX([-dragOffsetFromRightEdge, dragOffsetFromLeftEdge]) - .onStart(updateElementWidths) - .onUpdate( - (event: GestureUpdateEvent) => { - userDrag.value = event.translationX; - - const direction = - rowState.value === -1 - ? SwipeDirection.RIGHT - : rowState.value === 1 - ? SwipeDirection.LEFT - : event.translationX > 0 - ? SwipeDirection.RIGHT - : SwipeDirection.LEFT; - - if (!dragStarted.value) { - dragStarted.value = true; - if (rowState.value === 0 && onSwipeableOpenStartDrag) { - runOnJS(onSwipeableOpenStartDrag)(direction); - } else if (onSwipeableCloseStartDrag) { - runOnJS(onSwipeableCloseStartDrag)(direction); + const panGesture = useMemo( + () => + Gesture.Pan() + .enabled(enabled !== false) + .enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture) + .activeOffsetX([-dragOffsetFromRightEdge, dragOffsetFromLeftEdge]) + .simultaneousWithExternalGesture( + ...(simultaneousWithExternalGestures ?? []) + ) + .onStart(updateElementWidths) + .onUpdate( + (event: GestureUpdateEvent) => { + userDrag.value = event.translationX; + + const direction = + rowState.value === -1 + ? SwipeDirection.RIGHT + : rowState.value === 1 + ? SwipeDirection.LEFT + : event.translationX > 0 + ? SwipeDirection.RIGHT + : SwipeDirection.LEFT; + + if (!dragStarted.value) { + dragStarted.value = true; + if (rowState.value === 0 && onSwipeableOpenStartDrag) { + runOnJS(onSwipeableOpenStartDrag)(direction); + } else if (onSwipeableCloseStartDrag) { + runOnJS(onSwipeableCloseStartDrag)(direction); + } } - } - updateAnimatedEvent(); - } - ) - .onEnd( - (event: GestureStateChangeEvent) => { - handleRelease(event); - } - ) - .onFinalize(() => { - dragStarted.value = false; - }); - - // Add simultaneousWithExternalGesture only if it has a value - if (simultaneousWithExternalGesture) { - gesture.simultaneousWithExternalGesture( - simultaneousWithExternalGesture - ); - } - - return gesture; - }, [ - dragOffsetFromLeftEdge, - dragOffsetFromRightEdge, - dragStarted, - enableTrackpadTwoFingerGesture, - enabled, - handleRelease, - onSwipeableCloseStartDrag, - onSwipeableOpenStartDrag, - rowState, - updateAnimatedEvent, - updateElementWidths, - userDrag, - simultaneousWithExternalGesture, - ]); + updateAnimatedEvent(); + } + ) + .onEnd( + (event: GestureStateChangeEvent) => { + handleRelease(event); + } + ) + .onFinalize(() => { + dragStarted.value = false; + }), + [ + dragOffsetFromLeftEdge, + dragOffsetFromRightEdge, + dragStarted, + enableTrackpadTwoFingerGesture, + enabled, + handleRelease, + onSwipeableCloseStartDrag, + onSwipeableOpenStartDrag, + rowState, + updateAnimatedEvent, + updateElementWidths, + userDrag, + simultaneousWithExternalGestures, + ] + ); useImperativeHandle(ref, () => swipeableMethods, [swipeableMethods]); From aea0c1f2f074d8804e1cb405c409d3603d69c3ab Mon Sep 17 00:00:00 2001 From: Sultan Date: Mon, 27 Jan 2025 12:35:54 +0100 Subject: [PATCH 06/11] move `simultaneousWithExternalGesture` to the end of the swipeable's gesture --- src/components/ReanimatedSwipeable.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/ReanimatedSwipeable.tsx b/src/components/ReanimatedSwipeable.tsx index 5311faa496..8efd3d5ad8 100644 --- a/src/components/ReanimatedSwipeable.tsx +++ b/src/components/ReanimatedSwipeable.tsx @@ -661,9 +661,6 @@ const Swipeable = forwardRef( .enabled(enabled !== false) .enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture) .activeOffsetX([-dragOffsetFromRightEdge, dragOffsetFromLeftEdge]) - .simultaneousWithExternalGesture( - ...(simultaneousWithExternalGestures ?? []) - ) .onStart(updateElementWidths) .onUpdate( (event: GestureUpdateEvent) => { @@ -697,7 +694,10 @@ const Swipeable = forwardRef( ) .onFinalize(() => { dragStarted.value = false; - }), + }) + .simultaneousWithExternalGesture( + ...(simultaneousWithExternalGestures ?? []) + ), [ dragOffsetFromLeftEdge, dragOffsetFromRightEdge, From 846295d8fd05451212ab1ed8840efa9fa51ebc11 Mon Sep 17 00:00:00 2001 From: Sultan Date: Mon, 27 Jan 2025 13:24:49 +0100 Subject: [PATCH 07/11] update docs --- docs/docs/components/reanimated_swipeable.md | 2 +- src/components/ReanimatedSwipeable.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/components/reanimated_swipeable.md b/docs/docs/components/reanimated_swipeable.md index 205635ea44..01bb579584 100644 --- a/docs/docs/components/reanimated_swipeable.md +++ b/docs/docs/components/reanimated_swipeable.md @@ -130,7 +130,7 @@ style object for the children container (`Animated.View`), for example to apply ### `simultaneousWithExternalGestures` -An optional gesture configuration that enable other gestures to be recognized simultaneously with the swipeable gesture. This is useful for allowing swipeable gestures to work simultaneously with other gestures. +An array of gesture configurations to be recognized simultaneously with the swipeable gesture. This is useful for allowing other gestures to work simultaneously with swipeable gesture handler. For example, to enable a pan gesture alongside the swipeable gesture: diff --git a/src/components/ReanimatedSwipeable.tsx b/src/components/ReanimatedSwipeable.tsx index 8efd3d5ad8..b6e6bfcc13 100644 --- a/src/components/ReanimatedSwipeable.tsx +++ b/src/components/ReanimatedSwipeable.tsx @@ -205,7 +205,7 @@ export interface SwipeableProps childrenContainerStyle?: StyleProp; /** - * A gesture object containing the configuration and callbacks to be + * An array of gesture objects containing the configuration and callbacks to be * used with the swipeable's gesture handler. */ simultaneousWithExternalGestures?: Exclude[]; From a105431c31c3797b22259ad7966d4b74da466b17 Mon Sep 17 00:00:00 2001 From: Sultan Date: Mon, 27 Jan 2025 15:04:49 +0100 Subject: [PATCH 08/11] rename `simultaneousWithExternalGesture` and update `panGesture` --- src/components/ReanimatedSwipeable.tsx | 129 +++++++++++++------------ 1 file changed, 69 insertions(+), 60 deletions(-) diff --git a/src/components/ReanimatedSwipeable.tsx b/src/components/ReanimatedSwipeable.tsx index b6e6bfcc13..0af0c9ab01 100644 --- a/src/components/ReanimatedSwipeable.tsx +++ b/src/components/ReanimatedSwipeable.tsx @@ -205,10 +205,12 @@ export interface SwipeableProps childrenContainerStyle?: StyleProp; /** - * An array of gesture objects containing the configuration and callbacks to be + * A gesture object or an array of gesture objects containing the configuration and callbacks to be * used with the swipeable's gesture handler. */ - simultaneousWithExternalGestures?: Exclude[]; + simultaneousWithExternalGesture?: + | Exclude + | Exclude[]; } export interface SwipeableMethods { @@ -254,7 +256,7 @@ const Swipeable = forwardRef( onSwipeableClose, renderLeftActions, renderRightActions, - simultaneousWithExternalGestures, + simultaneousWithExternalGesture, ...remainingProps } = props; @@ -655,65 +657,72 @@ const Swipeable = forwardRef( [close, rowState] ); - const panGesture = useMemo( - () => - Gesture.Pan() - .enabled(enabled !== false) - .enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture) - .activeOffsetX([-dragOffsetFromRightEdge, dragOffsetFromLeftEdge]) - .onStart(updateElementWidths) - .onUpdate( - (event: GestureUpdateEvent) => { - userDrag.value = event.translationX; - - const direction = - rowState.value === -1 - ? SwipeDirection.RIGHT - : rowState.value === 1 - ? SwipeDirection.LEFT - : event.translationX > 0 - ? SwipeDirection.RIGHT - : SwipeDirection.LEFT; - - if (!dragStarted.value) { - dragStarted.value = true; - if (rowState.value === 0 && onSwipeableOpenStartDrag) { - runOnJS(onSwipeableOpenStartDrag)(direction); - } else if (onSwipeableCloseStartDrag) { - runOnJS(onSwipeableCloseStartDrag)(direction); - } + const panGesture = useMemo(() => { + const pan = Gesture.Pan() + .enabled(enabled !== false) + .enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture) + .activeOffsetX([-dragOffsetFromRightEdge, dragOffsetFromLeftEdge]) + .onStart(updateElementWidths) + .onUpdate( + (event: GestureUpdateEvent) => { + userDrag.value = event.translationX; + + const direction = + rowState.value === -1 + ? SwipeDirection.RIGHT + : rowState.value === 1 + ? SwipeDirection.LEFT + : event.translationX > 0 + ? SwipeDirection.RIGHT + : SwipeDirection.LEFT; + + if (!dragStarted.value) { + dragStarted.value = true; + if (rowState.value === 0 && onSwipeableOpenStartDrag) { + runOnJS(onSwipeableOpenStartDrag)(direction); + } else if (onSwipeableCloseStartDrag) { + runOnJS(onSwipeableCloseStartDrag)(direction); } - - updateAnimatedEvent(); - } - ) - .onEnd( - (event: GestureStateChangeEvent) => { - handleRelease(event); } - ) - .onFinalize(() => { - dragStarted.value = false; - }) - .simultaneousWithExternalGesture( - ...(simultaneousWithExternalGestures ?? []) - ), - [ - dragOffsetFromLeftEdge, - dragOffsetFromRightEdge, - dragStarted, - enableTrackpadTwoFingerGesture, - enabled, - handleRelease, - onSwipeableCloseStartDrag, - onSwipeableOpenStartDrag, - rowState, - updateAnimatedEvent, - updateElementWidths, - userDrag, - simultaneousWithExternalGestures, - ] - ); + + updateAnimatedEvent(); + } + ) + .onEnd( + (event: GestureStateChangeEvent) => { + handleRelease(event); + } + ) + .onFinalize(() => { + dragStarted.value = false; + }); + + if (!simultaneousWithExternalGesture) { + return pan; + } + + if (Array.isArray(simultaneousWithExternalGesture)) { + pan.simultaneousWithExternalGesture(...simultaneousWithExternalGesture); + } else { + pan.simultaneousWithExternalGesture(simultaneousWithExternalGesture); + } + + return pan; + }, [ + dragOffsetFromLeftEdge, + dragOffsetFromRightEdge, + dragStarted, + enableTrackpadTwoFingerGesture, + enabled, + handleRelease, + onSwipeableCloseStartDrag, + onSwipeableOpenStartDrag, + rowState, + updateAnimatedEvent, + updateElementWidths, + userDrag, + simultaneousWithExternalGesture, + ]); useImperativeHandle(ref, () => swipeableMethods, [swipeableMethods]); From 313cc4bc1d5a5ea0092435c89578fe286d562c1a Mon Sep 17 00:00:00 2001 From: Sultan Date: Mon, 27 Jan 2025 15:05:09 +0100 Subject: [PATCH 09/11] update `tapGesture` --- src/components/ReanimatedSwipeable.tsx | 31 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/components/ReanimatedSwipeable.tsx b/src/components/ReanimatedSwipeable.tsx index 0af0c9ab01..ccecc8dd5e 100644 --- a/src/components/ReanimatedSwipeable.tsx +++ b/src/components/ReanimatedSwipeable.tsx @@ -645,18 +645,27 @@ const Swipeable = forwardRef( const dragStarted = useSharedValue(false); - const tapGesture = useMemo( - () => - Gesture.Tap() - .shouldCancelWhenOutside(true) - .onStart(() => { - if (rowState.value !== 0) { - close(); - } - }), - [close, rowState] - ); + const tapGesture = useMemo(() => { + const tap = Gesture.Tap() + .shouldCancelWhenOutside(true) + .onStart(() => { + if (rowState.value !== 0) { + close(); + } + }); + + if (!simultaneousWithExternalGesture) { + return tap; + } + + if (Array.isArray(simultaneousWithExternalGesture)) { + tap.simultaneousWithExternalGesture(...simultaneousWithExternalGesture); + } else { + tap.simultaneousWithExternalGesture(simultaneousWithExternalGesture); + } + return tap; + }, [close, rowState, simultaneousWithExternalGesture]); const panGesture = useMemo(() => { const pan = Gesture.Pan() .enabled(enabled !== false) From ce2eed26f060c86ddf20173abb7af5feb0291ec9 Mon Sep 17 00:00:00 2001 From: Sultan Date: Mon, 27 Jan 2025 15:22:52 +0100 Subject: [PATCH 10/11] update docs --- docs/docs/components/reanimated_swipeable.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs/components/reanimated_swipeable.md b/docs/docs/components/reanimated_swipeable.md index 01bb579584..a6a7aa2e26 100644 --- a/docs/docs/components/reanimated_swipeable.md +++ b/docs/docs/components/reanimated_swipeable.md @@ -128,9 +128,9 @@ style object for the container (`Animated.View`), for example to override `overf style object for the children container (`Animated.View`), for example to apply `flex: 1`. -### `simultaneousWithExternalGestures` +### `simultaneousWithExternalGesture` -An array of gesture configurations to be recognized simultaneously with the swipeable gesture. This is useful for allowing other gestures to work simultaneously with swipeable gesture handler. +A gesture configuration to be recognized simultaneously with the swipeable gesture. This is useful for allowing other gestures to work simultaneously with swipeable gesture handler. For example, to enable a pan gesture alongside the swipeable gesture: @@ -138,7 +138,7 @@ For example, to enable a pan gesture alongside the swipeable gesture: const panGesture = Gesture.Pan(); - + ``` From 74e2f8a0abe4abd28967097f78a773385fe86be6 Mon Sep 17 00:00:00 2001 From: Sultan Date: Mon, 27 Jan 2025 15:45:32 +0100 Subject: [PATCH 11/11] fix(styling): add a new line between `tapGesture` and `panGesture` --- src/components/ReanimatedSwipeable.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ReanimatedSwipeable.tsx b/src/components/ReanimatedSwipeable.tsx index ccecc8dd5e..fc085eef30 100644 --- a/src/components/ReanimatedSwipeable.tsx +++ b/src/components/ReanimatedSwipeable.tsx @@ -666,6 +666,7 @@ const Swipeable = forwardRef( return tap; }, [close, rowState, simultaneousWithExternalGesture]); + const panGesture = useMemo(() => { const pan = Gesture.Pan() .enabled(enabled !== false)