Repository navigation
Undo a cancelled ReanimatedDrawerLayout pan - #4635
Conversation
A pan that is cancelled or fails after it activated still runs the release logic, so a drawer dragged past half of its width opens (or closes) and fires onDrawerOpen (or onDrawerClose). Settle the drawer where it rested before the gesture instead, the same way ReanimatedSwipeable handles a cancelled pan.
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes.
|
| Layer / File(s) | Summary |
|---|---|
Handle and test pan release behavior packages/react-native-gesture-handler/src/components/ReanimatedDrawerLayout.tsx, packages/react-native-gesture-handler/src/__tests__/reanimatedDrawerLayoutRelease.test.tsx |
handleRelease accepts a canceled flag and settles canceled pans at the current endpoint with zero initial velocity. Tests check completed, canceled, and failed pans, including drawer progress, callbacks, and idle state. |
Suggested reviewers: m-bert
Priority:
Merge Risk: 
Minimal · previous review a8bd2
-
The cancellation behavior and its tests are consistent with the intended change. No issue identified here prevents merge.
Pre-merge checks: 
3
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
There was a problem hiding this comment.
🟢 Approval recommended
The narrowly scoped fix preserves the existing animation lifecycle and has targeted regression coverage, with no blocking issues identified.
No open issues 🎉
What changed in this PR
Updates ReanimatedDrawerLayout to restore its current open or closed state when an active pan is cancelled or fails, instead of treating it as a normal release.
Changes:
- Handles cancelled releases through the existing drawer animation and callback lifecycle.
- Adds regression tests for normal release and cancellation or failure from both open and closed states.
| File | Description |
|---|---|
| packages/react-native-gesture-handler/src/components/ReanimatedDrawerLayout.tsx | Restores the drawer’s resting state on cancelled releases. |
| packages/react-native-gesture-handler/src/__tests__/reanimatedDrawerLayoutRelease.test.tsx | Tests release behavior, restored positions, and state callbacks. |
Review effort: Balanced
m-bert
left a comment
There was a problem hiding this comment.
Thank you for fixing this!
Description
ReanimatedDrawerLayoutpasses its pan'sonDeactivatetohandleRelease, which does not readevent.canceled. When the pan is cancelled or fails after it activated (on web, for example, when the browser sendspointercancel), the drawer settles from the last translation and velocity as if the finger had lifted. A closed drawer dragged past half of its width opens and callsonDrawerOpen, and an open drawer dragged past half of its width closes and callsonDrawerClose.handleReleasenow settles a cancelled release at the drawer's current open or closed state instead of projecting the drag. This is the cancellation handling #4618 added toReanimatedSwipeable.The restore goes through
animateDrawer, soonDrawerStateChangedstill ends inIDLEand the callback for the resting position fires, as it does after a release that does not cross half of the width.Test plan
New Jest tests in
reanimatedDrawerLayoutRelease.test.tsxdrive the pan throughcreateGestureController: a pan that ends past half of the width opens the drawer, and a cancelled or failed pan past half keeps a closed drawer closed and an open drawer open. The four cancel and fail cases fail onmain.Web,
apps/expo-example"Reanimated Drawer Layout" screen in Chromium with touch input sent over CDP (Input.dispatchTouchEvent):maintouchCanceltouchCanceltouchEndtouchCancelyarn test(24 suites, 238 tests),yarn ts-check,yarn lint-jsandyarn circular-dependency-checkpass inpackages/react-native-gesture-handler.Not run on Android or iOS.