[Web] Make getEffectiveBoundingRect recursive#4303
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes a web-specific hit-testing/measurement issue for nested GestureDetector wrappers that use display: contents by making getEffectiveBoundingRect traverse through multiple layers of display: contents elements until it reaches elements with real layout boxes.
Changes:
- Make
getEffectiveBoundingRectrecursive so nesteddisplay: contentsdetector hosts no longer collapse to a0×0rect. - Ignore zero-sized intermediate rects and fall back to the current element’s
getBoundingClientRect()when no non-zero child bounds are found.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| this.gestureHandler.usesNativeOrVirtualDetector() && | ||
| this.view.style.display === 'contents' | ||
| hasDisplayContents(this.view) | ||
| ? (this.view.children[0] as HTMLElement) | ||
| : this.view; |
There was a problem hiding this comment.
Why does this work? Now you're checking for display: contents recursively, but you're still taking the first child when it's set.
There was a problem hiding this comment.
Well, this one (absoluteToLocal) is used only in Pinch and Rotation to calculate correct anchor and focal points. I have not tried degenerate example of nesting these handlers with other display: contents; view. Problems with Hover were discovered only because of our on-going Pressable refactor.
Anyway, given that it is better to use correct view rather than assuming correct hierarchy, I've changed that (bd1fa6e).
Let me know what you think
There was a problem hiding this comment.
Ideally, I think we would calculate the bounding box of all non-contents nodes, but this is fine for now.
Description
Currently
getEffectiveBoundingRecttakes bounding box either from view, or children if element hasdisplay: contents;. However, in case of nested detectors this brakes, as can be seen when running the example code below.This PR makes
getEffectiveBoundingRectrecursive, so it will not stop on the first layer of children.Test plan
Tested on the following code: