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

Drag gets priority over overlapping elements #296

Closed
vanquishkuso opened this issue Feb 13, 2024 · 7 comments · Fixed by #301
Closed

Drag gets priority over overlapping elements #296

vanquishkuso opened this issue Feb 13, 2024 · 7 comments · Fixed by #301

Comments

@vanquishkuso
Copy link

Hi, thank you for an awesome package!

I have an issue that I thought was similar to #288 but it doesn't seem to be fixed with the latest version 2.0.7. I have an overlapping button element that I want to be able to click and collapse a drawer. However, the draggable border gets priority even though the Z-index on the button is above.

This can be partially solved by moving the button outside of the resizable components (although it makes the positioning of the button troublesome), but when the button contains only an icon and not text, the drag gets priority again. The button is although still clickable.

If the button contains text and is outside of the resizable components it works as expected, but the positioning of the button is again cumbersome.

It's difficult to explain, so I reproduced a simple example it in the sandbox below:
https://codesandbox.io/p/sandbox/react-resizable-panels-forked-s5jzpg

@bvaughn
Copy link
Owner

bvaughn commented Feb 13, 2024

The behavior you're describing is controlled by this logic:

// TRICKY
// We listen for pointers events at the root in order to support hit area margins
// (determining when the pointer is close enough to an element to be considered a "hit")
// Clicking on an element "above" a handle (e.g. a modal) should prevent a hit though
// so at this point we need to compare stacking order of a potentially intersecting drag handle,
// and the element that was actually clicked/touched
if (
targetElement !== null &&
dragHandleElement !== targetElement &&
!dragHandleElement.contains(targetElement) &&
!targetElement.contains(dragHandleElement) &&
// Calculating stacking order has a cost, so we should avoid it if possible
// That is why we only check potentially intersecting handles,
// and why we skip if the event target is within the handle's DOM
compare(targetElement, dragHandleElement) > 0
) {
// If the target is above the drag handle, then we also need to confirm they overlap
// If they are beside each other (e.g. a panel and its drag handle) then the handle is still interactive
//
// It's not enough to compare only the target
// The target might be a small element inside of a larger container
// (For example, a SPAN or a DIV inside of a larger modal dialog)
let currentElement: HTMLElement | null = targetElement;
let didIntersect = false;
while (currentElement) {
if (currentElement.contains(dragHandleElement)) {
break;
} else if (
intersects(
currentElement.getBoundingClientRect(),
dragHandleRect,
true
)
) {
didIntersect = true;
break;
}

This Replay shows what's happening: 8c5e2948-00d4-4dd0-a7f7-c11f660ee59f

Nearest I can tell, it looks like a bug in the stacking-order package, because it's returning a value indicating that your buttons are not "above" the drag-handle. I added a comment where I Think that library is broken, but I don't have time to dig into it more.

You could try reducing this test case even more and filing an issue in that project's GitHub? Or if you'd like to dig in yourself and submit a PR I'll try to find time to review it. I'm pretty swamped right now though with work and don't have time to dig into this more.

@vanquishkuso
Copy link
Author

Thank you for the reply, I'll see what I kind find in that repo, in the meantime I'll try to use a workaround though.

@bvaughn
Copy link
Owner

bvaughn commented Feb 14, 2024

I had a few minutes this morning so I made a smaller repro and filed Rich-Harris/stacking-order#3

@vanquishkuso
Copy link
Author

Wow thank you so much for taking the time to look at it! Very glad the problem could be located. Looking forward to their response and hopefully a fix since my workaround wasn't so good 😊.

@bvaughn
Copy link
Owner

bvaughn commented Feb 14, 2024

No problem! Think I found a fix @ Rich-Harris/stacking-order#4

bvaughn added a commit that referenced this issue Feb 14, 2024
Resolves #296

I've proposed an upstream fix for this at
Rich-Harris/stacking-order#4

For now, this commit inlines that dependency and applies the fix
@bvaughn
Copy link
Owner

bvaughn commented Feb 14, 2024

Fixed published in 2.0.9


❤️ → ☕ givebrian.coffee

@vanquishkuso
Copy link
Author

Amazing, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants