Skip to content

[DRAFT] Add preventRecognizers prop to the gesture handlers#4094

Draft
coado wants to merge 18 commits intomainfrom
prevent-recognizers
Draft

[DRAFT] Add preventRecognizers prop to the gesture handlers#4094
coado wants to merge 18 commits intomainfrom
prevent-recognizers

Conversation

@coado
Copy link
Copy Markdown
Contributor

@coado coado commented Apr 16, 2026

Description

Adds preventRecognizers prop to the gesture handlers for controlling RN touch system.

Adds a per-gesture cancelsJSResponder?: boolean prop on both platforms to the v3 handler hooks. It defaults to true to preserve the behavior of cancelling RN JS responder system.

On Android it moves the root-view dispatch off onCancel onto new orchestrator callbacks onCancelJSResponderRequested and onCancelJSResponderReleased. The orchestrator only files the "released" callback when the last active handler with cancelsJSResponder: true finishes.

on iOS the RNRootViewGestureRecognizer checks the handler prop before notifying the delegate.

Test plan

Added new test example with multiple handlers that might or might not cancel the JS responder.

Simulator Screenshot - iPhone 16 Pro Max - 2026-04-17 at 12 59 42

Copilot AI review requested due to automatic review settings April 16, 2026 09:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new preventRecognizers configuration option to gesture handlers to control whether GH activation cancels React Native JS responders (with native iOS/Android plumbing + an example to demonstrate behavior).

Changes:

  • Added preventRecognizers to shared gesture config types/whitelists so it can flow from JS to native.
  • Implemented native behavior gates on iOS (root recognizer) and Android (orchestrator → root helper interception) with default true.
  • Added docs + a new common-app example to showcase responder cancellation differences.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/react-native-gesture-handler/src/v3/types/ConfigTypes.ts Adds preventRecognizers to common gesture config typing.
packages/react-native-gesture-handler/src/v3/hooks/utils/propsWhiteList.ts Allows the new config prop to pass through native config filtering.
packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx Minor formatting-only change near detector initialization.
packages/react-native-gesture-handler/src/handlers/gestures/GestureDetector/utils.ts Adds preventRecognizers to allowed prop list for detector plumbing.
packages/react-native-gesture-handler/apple/RNRootViewGestureRecognizer.m iOS: only trigger RN responder cancellation when preventRecognizers is enabled.
packages/react-native-gesture-handler/apple/RNGestureHandler.mm iOS: default + config parsing for preventRecognizers.
packages/react-native-gesture-handler/apple/RNGestureHandler.h iOS: exposes preventRecognizers on the handler.
packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt Android: intercept/cancel RN touch stream when requested by orchestrator.
packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt Android: emits request/release callbacks based on handler activation + finish.
packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt Android: stores/reads preventRecognizers from config with default true.
packages/docs-gesture-handler/docs/fundamentals/root-view.mdx Doc formatting cleanup (indentation/trailing whitespace).
packages/docs-gesture-handler/docs/fundamentals/gesture-detector.mdx Adds docs for preventRecognizers (but currently includes a broken tag and placement concerns).
apps/common-app/src/new_api/tests/rnResponderCancellation/index.tsx New example screen demonstrating RN responder cancellation vs. concurrent handling.
apps/common-app/src/new_api/index.tsx Registers the new example in the app’s examples list.
Comments suppressed due to low confidence (1)

packages/docs-gesture-handler/docs/fundamentals/gesture-detector.mdx:206

  • The closing tag for HeaderWithBadges was changed to </BadHeaderWithBadgesges>, which is not a valid component/tag and will break MDX rendering/build. Replace it with the correct </HeaderWithBadges> closing tag.
<HeaderWithBadges platforms={['web']}>
### touchAction
</HeaderWithBadges>


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/react-native-gesture-handler/apple/RNRootViewGestureRecognizer.m Outdated
Comment thread packages/docs-gesture-handler/docs/fundamentals/gesture-detector.mdx Outdated
@coado
Copy link
Copy Markdown
Contributor Author

coado commented Apr 17, 2026

@copilot review?

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 17, 2026

@copilot review?

Here's the review of the current state of the PR:

Overall: The implementation is solid. All 3 previously flagged issues are resolved. Here's a brief summary per area:

Android:

  • onCancelJSResponderRequested is correctly placed after the FAILED/CANCELLED early-return guard in makeActive — no stale shouldIntercept=true risk for already-finished handlers.
  • onCancelJSResponderReleased checks that no other active handler still has cancelsJSResponder=true before clearing shouldIntercept. ✓

iOS:

  • cancelsJSResponder property defaults to YES in resetConfig, read from config in updateConfig. ✓
  • canBePreventedByGestureRecognizer: gates the delegate call on handler.cancelsJSResponder. ✓

TypeScript:

  • Prop flows correctly: CommonGestureConfig (v3 types) → CommonConfig whitelist (v3) → ALLOWED_PROPS (v2 utils). ✓

Docs: cancelsJSResponder is documented in base-gesture-config.mdx (not under GestureDetector props). ✓

No issues found in the current state.

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.

3 participants