-
-
Notifications
You must be signed in to change notification settings - Fork 988
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add simultaneousWithExternalGesture
to ReanimatedSwipable
#3324
feat: Add simultaneousWithExternalGesture
to ReanimatedSwipable
#3324
Conversation
I think this is very reasonable. One thing i'd request, is that you rename the prop to I'm not sure if we want to also add |
Hi @MrSltun! Thanks for this PR!
Actually I'm not sure if we want to rename it in current state. Also, now when I look at it, I assume that What I think should be done here is to call this prop const panGesture = useMemo(
() =>
Gesture.Pan()
.enabled(enabled !== false)
.enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture)
.activeOffsetX([-dragOffsetFromRightEdge, dragOffsetFromLeftEdge])
.onStart(() => {
updateRightElementWidth();
})
.onUpdate(
(event: GestureUpdateEvent<PanGestureHandlerEventPayload>) => {
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<PanGestureHandlerEventPayload>) => {
handleRelease(event);
}
)
.onFinalize(() => {
dragStarted.value = false;
})
+ .simultaneousWithExternalGesture(simultaneousGesture),
[
dragOffsetFromLeftEdge,
dragOffsetFromRightEdge,
dragStarted,
enableTrackpadTwoFingerGesture,
enabled,
handleRelease,
onSwipeableCloseStartDrag,
onSwipeableOpenStartDrag,
rowState,
updateAnimatedEvent,
updateRightElementWidth,
userDrag,
]
); Could you please check if this works? |
My Approach was just to combine an external gesture with the But I like the approach of having the Edit: It works perfectly! I'll update the PR now! |
simultaneousWithExternalGesture
to ReanimatedSwipable
Thank you for testing the changes @latekvo 🫶
Hmm I tested the pan gestures, but didn't check the other types, I'll test all the gestures and see which works and which doesn't, and try to figure out why
Oh that's weird! I didn't come across it, not sure why it's happening but I'll check |
TypeScript errorWe've spent some time with @tjzel trying to find out what's going on. Turns out that this is a problem with our configuration (thank you @j-piasecki ❤️). Could you please update {
"extends": "../tsconfig.json",
"compilerOptions": {
"noEmit": true,
"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"]
}
},
"include": ["src/**/*.ts", "src/**/*.tsx", "App.tsx"]
}
TypesRegarding the code, I'd like to use the type that simultaneousWithExternalGesture: Exclude<GestureRef, number>[]; And that requires a change in passing it into config: .simultaneousWithExternalGesture(
...(simultaneousWithExternalGesture ?? [])
), In that case, example usage looks like this: <ReanimatedSwipeable
simultaneousWithExternalGesture={[pan, tap]}
...
> I know that this may be inconvenient with single gestures - we can change the type to: simultaneousWithExternalGesture: Exclude<GestureRef, number> | Exclude<GestureRef, number>[]; This will require a bit more logic when passing this prop into config, but it will be easier to use 😅 |
ee0392a
to
c30bbe2
Compare
@m-bert thank you for taking the time to test the change :) I updated the the example app's tsconfig Re: updating the I updated the name as well to reflect that change to be I also tested the new change and it works as it should 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @MrSltun! Thank you for changing our tsconfig
😅
Prop name
Please change prop name to simultaneousWithExternalGesture
. I know that it sounds better with s
at the end, but this is how it is currently named in Gesture Handler and we would like to stick to it.
Prop type
After looking at it I'd prefer to remove array if not necessary. It means that type of the prop should be
simultaneousWithExternalGesture?:
| Exclude<GestureRef, number>
| Exclude<GestureRef, number>[];
To handle it correctly, I suggest adding the following logic into useMemo
:
...
.onFinalize(() => {
dragStarted.value = false;
});
if (!simultaneousWithExternalGesture) {
return pan;
}
if (Array.isArray(simultaneousWithExternalGesture)) {
pan.simultaneousWithExternalGesture(...simultaneousWithExternalGesture);
} else {
pan.simultaneousWithExternalGesture(simultaneousWithExternalGesture);
}
return pan;
Tap gesture
Currently this prop is not used with Tap
gesture that is present inside Swipeable
- please add this 😅
* An array of gesture objects containing the configuration and callbacks to be | ||
* used with the swipeable's gesture handler. | ||
*/ | ||
simultaneousWithExternalGestures?: Exclude<GestureRef, number>[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simultaneousWithExternalGestures?: Exclude<GestureRef, number>[]; | |
simultaneousWithExternalGesture?: Exclude<GestureRef, number>[]; |
@m-bert Thank you for the detailed feedback :) I completely missed the tap gesture 😅 thank you for pointing it out! I just updated the name of the variable, as well as the definition of the pan gesture, and I added the gesture to the tab one as well :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for this PR @MrSltun ❤️
Description
This PR adds a new prop to
RenimatedSwipable
that allows adding a gesture config that can be used simultaneously withReanimatedSwipeable
's gesture config.The new prop is called
simultaneousWithExternalGesture
, it uses the the cross-component interaction methodology that's mentioned in the documentation here.I also update the docs for it
Motivation
I've been recently using ReanimatedSwipeable component, and I tried to add an additional gesture config to enable haptic feedback and "release to run function" kind of interaction
After looking through the issues in the repo, I found this issue #2862, I tried to apply it, but it turned out that it was only applicable to the Swipable component
I tried to find a way to add a gesture config that would work simultaneously with the swipeable one but I couldn't find a way to add it. So I looked through the documentation of RNGH for simultaneous gesture handlers and came up with this solution
Test plan
I already tested it locally on both iOS and Android, and the callbacks work as expected
Not sure if there's something else to do here since this is my first contribution