Skip to content

Undo a cancelled ReanimatedDrawerLayout pan - #4635

Open
mkantautas wants to merge 1 commit into
software-mansion:mainfrom
mkantautas:fix/drawer-cancelled-pan
Open

mkantautas wants to merge 1 commit into
software-mansion:mainfrom
mkantautas:fix/drawer-cancelled-pan

Conversation

@mkantautas

Copy link
Copy Markdown

Description

ReanimatedDrawerLayout passes its pan's onDeactivate to handleRelease, which does not read event.canceled. When the pan is cancelled or fails after it activated (on web, for example, when the browser sends pointercancel), 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 calls onDrawerOpen, and an open drawer dragged past half of its width closes and calls onDrawerClose.

handleRelease now 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 to ReanimatedSwipeable.

The restore goes through animateDrawer, so onDrawerStateChanged still ends in IDLE and 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.tsx drive the pan through createGestureController: 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 on main.

  • Web, apps/expo-example "Reanimated Drawer Layout" screen in Chromium with touch input sent over CDP (Input.dispatchTouchEvent):

    Touch sequence main This PR
    Drag from the edge past half, touchCancel opens stays closed
    Open the drawer, drag it past half towards closed, touchCancel closes stays open
    Drag from the edge past half, touchEnd opens opens
    Drag from the edge below half, touchCancel stays closed stays closed
  • yarn test (24 suites, 238 tests), yarn ts-check, yarn lint-js and yarn circular-dependency-check pass in packages/react-native-gesture-handler.

  • Not run on Android or iOS.

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.
Copilot AI balanced review requested due to automatic review settings October 23, 2026 17:36
@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8514cbd8-1920-4c45-85df-ef45b36a1589
📥 Commits

Reviewing files that changed from the base of the PR and between a83496b and a8bd22d.

📒 Files selected for processing: 2
  • packages/react-native-gesture-handler/src/__tests__/reanimatedDrawerLayoutRelease.test.tsx
  • packages/react-native-gesture-handler/src/components/ReanimatedDrawerLayout.tsx

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Canceled or failed pan gestures now leave the drawer in its existing open or closed state instead of applying the completed-gesture release behavior.
  • Tests
    • Added coverage for drawer state, progress, callbacks, and idle status when pan gestures are released, canceled, or fail.

Canceled drawer pans now settle at the drawer’s current open or closed endpoint instead of using the completed-pan release calculation. Tests cover completed, canceled, and failed pan outcomes.

Changes: Drawer pan release

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: ➖ Normal

Merge Risk: ⚪ Minimal · up to a8bd2

The cancellation behavior and its tests are consistent with the intended change. No issue identified here prevents merge.

Pre-merge checks: Passed 3
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: restoring ReanimatedDrawerLayout behavior after a cancelled pan.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
  • 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants