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

Support hugely overlapping Droppables #655

Open
O4epegb opened this issue Jul 19, 2018 · 13 comments
Open

Support hugely overlapping Droppables #655

O4epegb opened this issue Jul 19, 2018 · 13 comments

Comments

@O4epegb
Copy link

O4epegb commented Jul 19, 2018

Bug or feature request?

Possible bug, please check the demo.
I am not sure if such behaviour is supposed to work, maybe I should use something different for that :)

Expected behavior

Droppables are being selected correctly

Actual behavior

Very often higher positioned (z-index) Droppable (dropzone in demo) is not selected, but Droppable List underneath is selected instead.

Steps to reproduce

Just try to drag items from the list to dropzones at the bottom. Lists should be long enough that they overlap under dropzones, if they don't just try to add more items (there is a function at the top).

What browser are you using?

macOS Chrome Version 67.0.3396.99 (Official Build) (64-bit)

What version of React are you using?

"react": "16.4.1"

What version of react-beautiful-dnd are you running?

"react-beautiful-dnd": "8.0.5"

Demo

Very rough demo

https://codesandbox.io/s/yjp4zyjw3z

@alexreardon
Copy link
Collaborator

We currently do not consider z index when selecting the droppable target.

Overlapping droppables are not officially supported. A little overlap on the edges is fine, but the scenario you posted is not right now.

I'll convert this issue into a suggestion to add the feature 👍

@alexreardon alexreardon changed the title Possible bug when Droppables overlap Support hugely overlapping Droppables Jul 19, 2018
@O4epegb
Copy link
Author

O4epegb commented Jul 20, 2018

Oh, that very nice, thank you! 👍

@ksloan
Copy link

ksloan commented Jul 25, 2018

We have this issue as well. We have want to allow user to drag cards between several "tabs", so we're showing/hiding the tabs when their label is moused over during a drag. However, when the card is dropped it's detected as being dropped on the original list even though it's been hidden/moved.

@alexreardon Any ideas how we could accomplish this? Thanks for your work!

@ksloan
Copy link

ksloan commented Jul 25, 2018

Example:
example

@ksloan
Copy link

ksloan commented Jul 31, 2018

Hey @alexreardon , do you have any ideas for work-arounds for this kind of scenario?

@artooras
Copy link

artooras commented Dec 8, 2018

@alexreardon, you mentioned in your comment above that

We currently do not consider z index when selecting the droppable target.

Looking at the example posted by @O4epegb - and I have a conceptually similar setup, hence my interest in the issue - it seems (my assumption!) that the library is detecting the first DOM node wrapped in Droppable that is under a Draggable and triggers its interactions. Which, if z-index is not explicitly set, results in the library always detecting the Droppable with a lower z-index simply because it's encountered first in the DOM tree.

If I'm reading the src correctly, you have an array of Droppables to check if the draggable is over any of those. The first Droppable you find() is the one returned. Perhaps doing a simple Array.reverse() before find() could solve this issue? Of course, needs to be tested, but... fingers crossed :)

@alexreardon
Copy link
Collaborator

alexreardon commented Dec 8, 2018 via email

@artooras
Copy link

artooras commented Jan 2, 2019

Hi. I managed to have some progress on the issue. As I expected, all it indeed was to reverse the array of Droppables. Changing the return value of toDroppableList method here from

values(droppables) // returns an array

to

values(droppables).reverse()

makes the example above work as expected.

@alexreardon, would it be possible for someone on the team to check if this change breaks any tests? I'm cautiously optimistic it doesn't. I wish I could do it myself, but I managed to glue together a working example on my machine - only just - and I'm surprised it even ran with all the errors my editor is throwing at me...

@treshugart
Copy link

Hey, @artooras. Alex will be back mid-jan. See #1010 for more details.

@artooras
Copy link

artooras commented Mar 4, 2019

@treshugart any updates on this? #1010 also fails to shed more light...

@Gowthaman-Ganesan
Copy link

@alexreardon Having z-index for prioritizing droppables would be good. I've a similar setup that could use this feature. Any workaround or updates regarding this?

@yourheropaul
Copy link

yourheropaul commented Aug 5, 2021

I have a solution for a limited and specific use case, which may help someone.

Our problem

When building a horizontally-scrolling set of droppable columns (think Trello or GitHub Projects) with a visually-overlapping droppable panel (that is, with a higher z-index so it sits over one or more columns), we found a problem: Draggable cards in the overlapping panel were sometimes vanishing when they were vertically re-ordered. A user would move a card up or down the panel, and it would just disappear when they stopped dragging.

Analysis

Upon inspection, it turned out the draggable cards weren't vanishing. They were being added the the droppable column directly underneath. This isn't very surprising, since all droppable areas are mapped on a two-dimensional grid, and in this case two of them (the overlapping panel and the column under it) were often completely overlapping.

Some experimentation showed that the DOM order of the droppables made some difference (specifically, putting the overlapping droppable layer in the DOM before the underlying one, and changing its position to from fixed to relative) but didn't completely solve the problem. Nor did React Portals.

As @alexreardon mentioned above, there's no support for overlapping droppables (the original source code makes this pretty clear, too).

Solution

The solution was to make a fork of react-beautiful-dnd and change getDroppableOver to prefer the draggable's current droppable.

Specifically, when there are multiple possible candidates from a draggable to be dropped onto, if one of them has the same ID as droppable the draggable is currently attached to, then always use that.

What this means in practice is that the top-most (in terms of visibility) droppable is always selected when re-ordering draggables, which is what the user expects.

Code

This is no kind of general solution, and probably won't work in many cases. But if you want a simple overlaid droppable that might end up sitting right on top of another droppable without confusing users, it does the job.

There's an npm repo for the fork. If you happen to use TypeScript (which we do), then you can set up an alias in package.json to keep your types:

{
  "dependencies": {
    "@types/react-beautiful-dnd": "^13.0.0",
    "react-beautiful-dnd": "npm:@gethigher/react-beautiful-dnd@13.1.1"
} 

karanparmar1 added a commit to karanparmar1/react-dnd-beautiful that referenced this issue Nov 27, 2021
- Fixes issue atlassian#655: while dragging over multiple overlapping droppables, By passing droppableId as "HIGHEST_DROPPABLE"
@pasppro
Copy link

pasppro commented Feb 22, 2022

Any idea when z-index prioritization may be implemented?

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

No branches or pull requests

8 participants