Skip to content
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

Elements behind hitAreaMargins receive mouse events inconsistently #336

Closed
4nnikaf opened this issue Apr 12, 2024 · 3 comments
Closed

Elements behind hitAreaMargins receive mouse events inconsistently #336

4nnikaf opened this issue Apr 12, 2024 · 3 comments
Labels
help wanted Extra attention is needed

Comments

@4nnikaf
Copy link
Contributor

4nnikaf commented Apr 12, 2024

The general problem
Elements that are behind the hitAreaMargins of a PanelResizeHandle receive mouse events inconsistently.

onClick is blocked by the hitAreaMargin and is not triggered on the element beneath it.
onMouseEnter/onMouseLeave events however are NOT blocked, creating hover effects that might suggest to the user that the element was clickable.
onPointerDown is NOT blocked by the hitAreaMargins. So depending on the implementation clicks may be triggered on the element if the onPointerDown event is consumed instead of the onClick event.
onPointerUp however does get blocked.

If the hitAreaMargins size is set to 0, the issue still occurs because there is still a 1 pixel overlap between the resize handle and the panel content, where both the content receives the event and the resize handle is being dragged. But this overlap only exists to the right for vertical and to the bottom for horizontal resize handles.

I made this codesandbox to show the described issue: https://codesandbox.io/p/sandbox/react-resize-panels-event-issue-forked-gq7j2f

Desired behavior
All pointer events are treated equally and get blocked by the hitAreaMargin. Or there is at least a way to make it behave this way. I currently couldn't figure out a way to prevent these events from going through to the panel content.
Generally if the cursor turns into the resize cursor and the user clicks and drags to resize the panel, that is the only thing that should be happening.

My specific use case
I am currently implementing a component where you can move and split panels via Drag&Drop, like you're used to from any IDE, and I'm using dnd-kit for the Drag&Drop. dnd-kit listens to the onPointerDown event, which is still triggered underneath the hitAreaMargins. So when I start resizing a panel on the hitAreaMargins, dnd-kit also starts dragging the panel at the same time, which make the entire component pretty much unusable. I struggle to find a way to prevent the onPointerDown event from being triggered for dnd-kit, when the resize handle's margin is the actual target for the action.
I tried setting the hitAreaMargins to 0, but as described above that is currently not a working workaround either.

Probably a minor side issue
If I click on the hitAreaMargin while hovering the element beath it, the onMouseLeave event is called, even though the cursor is still hovering the element. I'd exepect the mouse leave/enter events to either function normally or to get fully blocked by the hitAreaMargins.
This can also be seen in the codesandbox example. I'm not sure if this is the same problem, so I could create a separate issue for this, though it's not currently a problem I'm having in my use case.

@bvaughn bvaughn added the help wanted Extra attention is needed label Apr 12, 2024
@bvaughn
Copy link
Owner

bvaughn commented Apr 12, 2024

Realistically this is not something I have the time to look into. If you'd like to submit a PR, I will try to make time to review it though. You'd probably make changes to this file: https://github.com/bvaughn/react-resizable-panels/blob/main/packages/react-resizable-panels/src/PanelResizeHandleRegistry.ts

@4nnikaf
Copy link
Contributor Author

4nnikaf commented Apr 12, 2024

Workaround
I found a workaround to at least get the behavior that one click only ever either drags the handle or interacts with the content by setting the hitAreaMargins to { fine: 0, coarse: 0 } and then making sure that any interactable panel content has at least a one pixel margin to the resize handle, to make room for the weird 1px overlap. It feels a little dirty but at least I don't get any unwanted behavior this way.

Though it's a shame that this cool feature where you can move intersecting horizontal and vertical handles at the same time is lost without the hitAreaMargins.

bvaughn pushed a commit that referenced this issue Apr 15, 2024
…ins (#338)

Fixing a problem described in #336 

To solve the issue of click events passing through the hitAreaMargins to
the elements behind them all we need to do is handle the events in the
capture phase and prevent them from bubbling down to the children/panel
content by calling `event.stopPropagation()`.

However cancelling the mouse/touch events (for exmaple
`mousedown`/`touchstart`), does not cancel their pointer event
counterparts (`pointerdown`), like it does the other way around. So I
also changed the event handlers to listen to the pointer events instead.
@bvaughn
Copy link
Owner

bvaughn commented Apr 15, 2024

Thanks for the PR.

Published version 2.0.17 just now with this change in it.


❤️ → ☕ givebrian.coffee

@bvaughn bvaughn closed this as completed Apr 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants