bvaughn / react-resizable-panels

https://react-resizable-panels.vercel.app/
MIT License
3.58k stars 124 forks source link

Elements behind hitAreaMargins receive mouse events inconsistently #336

Closed 4nnikaf closed 2 months ago

4nnikaf commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

Thanks for the PR.

Published version 2.0.17 just now with this change in it.


❤️ → ☕ givebrian.coffee