-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat(positioning): implement useSafeZoneArea() hook #34445
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
base: master
Are you sure you want to change the base?
Conversation
1880dbe
to
9531b6f
Compare
Pull request demo site: URL |
9531b6f
to
6a5d3dd
Compare
📊 Bundle size report
Unchanged fixtures
|
6a5d3dd
to
ef32e89
Compare
@@ -0,0 +1,132 @@ | |||
import * as React from 'react'; |
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.
🕵🏾♀️ visual changes to review in the Visual Change Report
vr-tests-react-components/Drawer 2 screenshots
Image Name | Diff(in Pixels) | Image Type |
---|---|---|
vr-tests-react-components/Drawer.overlay drawer full - Dark Mode.chromium.png | 2647 | Changed |
vr-tests-react-components/Drawer.overlay drawer full - High Contrast.chromium.png | 6684 | Changed |
vr-tests-react-components/Positioning 2 screenshots
Image Name | Diff(in Pixels) | Image Type |
---|---|---|
vr-tests-react-components/Positioning.Positioning end.chromium.png | 825 | Changed |
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png | 317 | Changed |
vr-tests-react-components/Positioning (safe area) 1 screenshots
Image Name | Diff(in Pixels) | Image Type |
---|---|---|
vr-tests-react-components/Positioning (safe area).using safe zone area.chromium.png | 0 | Added |
vr-tests-react-components/Skeleton converged 1 screenshots
Image Name | Diff(in Pixels) | Image Type |
---|---|---|
vr-tests-react-components/Skeleton converged.Opaque Skeleton with square - Dark Mode.default.chromium.png | 2 | Changed |
vr-tests-react-components/TagPicker 2 screenshots
Image Name | Diff(in Pixels) | Image Type |
---|---|---|
vr-tests-react-components/TagPicker.disabled - RTL.disabled input hover.chromium.png | 635 | Changed |
vr-tests-react-components/TagPicker.disabled - High Contrast.chromium.png | 1321 | Changed |
There were 2 duplicate changes discarded. Check the build logs for more information.
packages/react-components/react-positioning/src/SafeZoneArea.tsx
Outdated
Show resolved
Hide resolved
packages/react-components/react-positioning/src/SafeZoneArea.tsx
Outdated
Show resolved
Hide resolved
|
||
switch (containerPlacement.slice(0, 3)) { | ||
case 'top': | ||
svgStyle = { |
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.
can we extract the svg creation into testable factories?
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 don't think that we need to extract them, I added tests for the component
packages/react-components/react-positioning/src/useSafeZoneArea.tsx
Outdated
Show resolved
Hide resolved
Do not merge until it's tested in a product. |
New Behavior
This PR implements
useSafeZone()
hook which calculates a V-shaped safe zone where a mouse cursor is temporary trapped and prevents a menu from being closed:This is similar to to
safePolygon()
in Floating UI, however is implemented using SVGs (the solution is inspired by https://www.smashingmagazine.com/2023/08/better-context-menus-safe-triangles/).Why SVGs over JS?
SVG elements are still HTML elements ➡️ they are a part of DOM and mouse capturing that allows to work with mouse events and avoid blocking
pointerEvents
ondocument.body
when a cursor is in a safe zone:To clarify, the problem is not to block pointer events, the problem to ensure that they will be unblocked - otherwise the whole app will be unusable.
It's also easier to debug potential issues when something goes wrong as SVGs could be visible.
With SVGs we can explore more complicated shapes in future:
However, considering that other libraries use JS over SVGs - there might be some problems that I am not aware yet ¯_(ツ)_/¯
How it works?
timeout
, we hide a safe zone2025-05-14.15.46.56.mp4