feat(Android, FormSheet v5): Setup TouchHandler on Dialog window#4204
Open
t0maboro wants to merge 1 commit into
Open
feat(Android, FormSheet v5): Setup TouchHandler on Dialog window#4204t0maboro wants to merge 1 commit into
t0maboro wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes touch/pointer event dispatch for the Android FormSheet (rendered inside a native Dialog) by turning the dialog’s content container into its own React RootView, with local JSTouchDispatcher / JSPointerDispatcher instances to route MotionEvents into React Native correctly.
Changes:
- Make
FormSheetContentViewimplementRootViewand forward touch/hover/gesture events toJSTouchDispatcherandJSPointerDispatcher. - Make
FormSheetHostimplementReactPointerEventsViewwithpointerEvents = NONEso the “empty” host in the main window doesn’t block hit-testing behind it.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| android/src/main/java/com/swmansion/rnscreens/gamma/modals/formsheet/FormSheetHost.kt | Marks the host view as non-hit-testable in the main window via pointerEvents = NONE. |
| android/src/main/java/com/swmansion/rnscreens/gamma/modals/formsheet/FormSheetContentView.kt | Adds RootView-style touch/pointer dispatching so dialog-window interactions reach the RN event system. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+107
to
+117
| @SuppressLint("ClickableViewAccessibility") | ||
| override fun onTouchEvent(event: MotionEvent): Boolean { | ||
| eventDispatcher?.let { eventDispatcher -> | ||
| jsTouchDispatcher.handleTouchEvent(event, eventDispatcher, themedReactContext) | ||
| jsPointerDispatcher?.handleMotionEvent(event, eventDispatcher, false) | ||
| } | ||
| super.onTouchEvent(event) | ||
| // In case when there is no children interested in handling touch event, we return true from | ||
| // the root view in order to receive subsequent events related to that gesture | ||
| return true | ||
| } |
Comment on lines
+152
to
+154
| override fun handleException(t: Throwable) { | ||
| themedReactContext.reactApplicationContext.handleException(RuntimeException(t)) | ||
| } |
kmichalikk
approved these changes
Jun 24, 2026
kmichalikk
left a comment
Contributor
There was a problem hiding this comment.
runtime seems ok from quick glance, no further comments from me, but please look at what copilot added
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR implements the touch and pointer event handling for the FormSheet by making the ContentView to act as a separate React RootView.
When rendering React Native components inside a native Dialog, the views are rendered in a completely separate window. This breaks touch event dispatching because React Native's main ReactRootView is completely unaware of this detached window.
To solve this, we make
FormSheetContentViewimplement theRootViewinterface and instantiate its ownJSTouchDispatcherandJSPointerDispatcher. By overriding the standard Android touch and hover methods and feeding the MotionEvents directly into these local dispatchers, we successfully forward user interactions from the dialog's window into the RN event system.Because FormSheetContentView establishes itself as a new, independent
RootViewboundary, theMotionEventcoordinates supplied by theAndroidframework are naturally scoped to the bounds of the dialog's window, resulting in the proper coordinate mapping for the React children without any shadow tree contentOriginOffset corrections.Closes: https://github.com/software-mansion/react-native-screens-labs/issues/1548
Changes
FormSheetContentViewnow acts as aRootView.JSTouchDispatcherfrom RN core modal implementation to handle standard MotionEventsJSPointerDispatcherfrom RN core modal implementation to handle pointer events and hover statesBefore & after - visual documentation
formsheet-pressables-android.mov
Test plan
Base test for formsheets, verify that pressables are working properly.
Checklist