dnd-kit icon indicating copy to clipboard operation
dnd-kit copied to clipboard

Nested Multiple Containers

Open jnavb opened this issue 2 years ago • 2 comments

I'm trying to do a layout with multiple containers, the direction of the containers would be vertical (Fixed rows, no option to drag) and the item list would be horizontal (horizontalListSortingStrategy), I'll call this component a Panel for now on.

It took me less of an hour to build this Panel with the awesome components helpers from the Storybook, however, users should be able to have Panels as an item of a container (nesting capabilities).

Is this supported? I think I'm really close to a desired result but don't want to deep further if there's a limitation in the library, I'll list the problems I have:

  1. Nested useSortable items move when dragging an item at left/right of its parent

nestedOk

  1. Infinite loop when trying to drag a Panel, not sure if is due the collision strategy. Let me know if I need to open a different issue for this, I think it's related to #552

infinite

You can reproduce both at example-nested-multiple-containers

Second topic is, if example results succesful, are you interested in document this use case? I can offer to refactor the branch and make a PR with such changes, perhaps merging Panel and MultipleContainers components.

Thank you, library is amazing

jnavb avatar May 13 '22 16:05 jnavb

I've discovered problem 2 arises because there are useSortables (useDraggable + useDroppable) inside a DragOverlay, as documentation states this is not the intended way:

make sure that the components rendered within the drag overlay do not use the useDraggable hook.

However, at Tree story there are useSortables inside DragOverlay so I don't know if there's a safe way to do it. https://5fc05e08a4a65d0021ae0bf2-polasjgdps.chromatic.com/?path=/story/examples-tree-sortable--all-features

jnavb avatar May 17 '22 15:05 jnavb

I am getting the same infinite loop error did you figure out the reason why it is happening?

MuhammadHamzaChippa avatar Jul 06 '22 02:07 MuhammadHamzaChippa

I'm getting the same thing, and I cannot for the life of me figure out why :S

Heilemann avatar Jan 07 '23 02:01 Heilemann

@jnavb Did you find a solution to the issue?

theisnygaard avatar Feb 23 '23 08:02 theisnygaard

I'm hitting this infinite loop issue also. Has anyone figured out solution to this?

diginikkari avatar Mar 15 '23 07:03 diginikkari

I've been at this issue for a while now, attacking it from several directions. Gave up, but then tried to do it with React-DND which has it's own issues and so came back and tried again.

My use case is nested sortables.

Imgur

Code sandbox: https://codesandbox.io/s/stoic-bohr-fosy2f?file=/src/MultipleContainer.tsx

Note: Previous iteration was using a droppable when a sortable has no children, but now I have changed it to an empty sortable.

I've found out that by dragging an item into another sortable. It will result in an infinite loop of renders of the receiving sortable. Which ultimately ends up in a complete lock of the browser.

To circumvent this, if I check whether the sortable has the item already (post insert) then to do nothing. This resolved the issue. Now I'm able to drag an item from any sortable up and down the nested chain and it won't ever freeze.

I don't think I'm quite done yet, but I'm almost there.

paulm17 avatar Mar 23 '23 16:03 paulm17

@Heilemann @theisnygaard @diginikkari @MuhammadHamzaChippa hey, sorry for the delay. I did solve it, there are currently two ways to approach the problem:

A. (Simplest solution) Don't render the dragging element, use a placeholder as the dragoverlay element.

B. In the custom collision strategy filter the droppable containers that are inside the element you are currently dragging. Let's say you are using closestCorners:

closestCorners({
  ...args,
  droppableContainers: args.droppableContainers.filter((container: DroppableContainer) =>
      // remove draggingId and its children
    )
})

hope this helps!

jnavb avatar Mar 29 '23 15:03 jnavb