-
Notifications
You must be signed in to change notification settings - Fork 273
Trigger non-touch events on box-none targets #906
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
Merged
thymikee
merged 4 commits into
callstack:main
from
dcalhoun:trigger-non-touch-events-on-box-none-targets
Jul 19, 2022
Merged
Changes from 3 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
0e0664f
Trigger non-touch events on box-none targets
dcalhoun dd08c31
Event triggers target box-none View instead of child
dcalhoun 4e58922
Rename events in test description
dcalhoun e504406
Merge branch 'main' of https://github.com/callstack/react-native-test…
dcalhoun File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,12 +33,17 @@ const isPointerEventEnabled = ( | |
return isPointerEventEnabled(element.parent, true); | ||
}; | ||
|
||
const isTouchEvent = (eventName?: string) => { | ||
return eventName === 'press'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Originally, I structured this as |
||
}; | ||
|
||
const isEventEnabled = ( | ||
element?: ReactTestInstance, | ||
touchResponder?: ReactTestInstance | ||
touchResponder?: ReactTestInstance, | ||
eventName?: string | ||
) => { | ||
if (isTextInput(element)) return element?.props.editable !== false; | ||
if (!isPointerEventEnabled(element)) return false; | ||
if (!isPointerEventEnabled(element) && isTouchEvent(eventName)) return false; | ||
|
||
const touchStart = touchResponder?.props.onStartShouldSetResponder?.(); | ||
const touchMove = touchResponder?.props.onMoveShouldSetResponder?.(); | ||
|
@@ -59,7 +64,8 @@ const findEventHandler = ( | |
: nearestTouchResponder; | ||
|
||
const handler = getEventHandler(element, eventName); | ||
if (handler && isEventEnabled(element, touchResponder)) return handler; | ||
if (handler && isEventEnabled(element, touchResponder, eventName)) | ||
return handler; | ||
|
||
if (element.parent === null || element.parent.parent === null) { | ||
return null; | ||
|
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.
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.
The name
isTouchEvent
feels odd given thatonTouch*
is not considered to beisTouchEvent
here. However, I chose the nameisTouchEvent
based upon the language in thepointerEvents
documentation. Open to feedback on this naming.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.
I'm not sure whether this list is complete and/or even can be a static one because it may be platform-dependent.
On Android setting
pointerEvents
works by intercepting and discardingMotionEvent
s. These include at leasttouchstart
,touchend
,touchmove
andtouchcancel
events. See: https://github.com/facebook/react-native/blob/main/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java#L220-L245.In case of iOS it is setting this: https://developer.apple.com/documentation/uikit/uiview/1622577-userinteractionenabled?language=objc (related RN code: https://github.com/facebook/react-native/blob/main/React/Views/RCTView.m#L151-L158) to
false
, so it includestouch, press, keyboard, and focus events
.I'd experiment with both platforms and see what superset of events is covering both platforms.
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.
@Killavus I agree it is likely incomplete, however it pointedly addresses the issue outlined in #897. I opted to target the specific discrepancy between React Native and RNTL I experienced.
In regards to the list being static, from my testing the
onTouchStart
,onTouchEnd
, andonLayout
events all function the same way on both platforms in relation topointerEvents="box-none"
. This behavior is showcased in the example Expo Snack I created for #897. BothonTouchStart
andonTouchEnd
continue to fire for both iOS and Android even when theView
is set topointerEvents="box-none"
.From reviewing the Android and iOS code in the links, I do not believe it directly invalidates this PR. The Android
onInterceptTouchEvent
intercepts whennone
orbox-only
, which is different then the current subjectbox-none
. The iOSsetPointerEvents
disablesuserInteractionEnabled
whenpointerEvents="none"
, which again is different than the current subjectbox-none
. Additionally, as showcased in the Expo Snack, the subject events continue to trigger whenpointerEvents="box-none"
.Please let me know if I am misunderstanding what you attempted to communicate with your code references.
I might posit merging this PR as-is could be a step towards increased accuracy and consistency. A follow up PR could further increase accuracy and consistency. The ultimate "superset" is a bit unknown to me at this point. WDYT?
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.
That seems like a good approach for me. @thymikee has a final say here though!
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.
Still haven't found time for this, please bare with me! :D
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.
Hey @dcalhoun, I'll need more time to process it. Right now I focus on releasing a new library and needed to postpone this. It's not forgotten though.
In the meantime, I'll ask @AugustinLF, maybe he'll be able to check it.
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.
Thanks, @thymikee. That makes sense. I appreciate your time.
P.S. - feel free to ignore my ping from a different PR.
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.
So if I understand correctly, your suggestion of implementation is strictly more correct than what we have, but is missing some additional cases? i.e. it makes things better, but doesn't fix everything, right?
If that's the case, I'm fine with merging this change. I'd like to have documentation (code and/or through a detailed issue) on the missing behaviour, so we can fix it going forward. Does that seem reasonable?
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 for your thoughts, @AugustinLF. 🙇🏻
Correct. That was my sentiment in #906 (comment). There may be other cases where RNTL is misaligned with how RN implements
pointerEvents
, this PR provides a solution for the one case I ran into myself.Yes, detailed documentation of the (unproven) further misalignment between RNTL and RN makes sense. That would help avoid any additional issues going unnoticed.
To be transparent, I have not fully explored further misalignments. I am unsure if I will be able to prioritize doing so in the near future. If the maintainers prefer to postpone merging this improvement until that research/documentation is completed, I respect that. However, my perspective is that one step towards alignment is better than no steps. I.e. it is worth merging this work as-is. WDYT?
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.
I'd suggest to merge.