clauderic / dnd-kit

The modern, lightweight, performant, accessible and extensible drag & drop toolkit for React.
http://dndkit.com
MIT License
13.05k stars 646 forks source link

sorting too complicated #1188

Open eudinnou opened 1 year ago

eudinnou commented 1 year ago

Hello,

I am trying to migrate some code from react-sortable-hoc & react-beautiful-dnd to dnd-kit. I thought that I made the correct decision, but now I have second thoughts.

The main issue that I have is sorting from multiple containers. The amount of logic that I need to add comparing to the previous libraries is huge. The documentation for this part is very simplistic, like: In this example, we would use the onDragOver callback of DndContext to detect when a draggable element is moved over a different container to insert it in that new container while dragging. but the implications for it are overwhelming.

I started investigating the source code, starting from the storybook, and my impression is that this library looks well on the outside, but the implementation & usage is chaotic. There are also a lot of issues, and not sure about the author availability 🤔

Hopefully this library will be improved over time (code, bugs, examples, documentation, tests), and will cover more common use cases that will be easy to integrate. I know it is not easy to maintain a library, and I appreciate all the effort (the presentation website is making this library to look like a pro)!

Chunkford commented 1 year ago

Multiple containers seems to be the holy grail and is the area I'm struggling with the most. If it helps, Claudéric has 2 codesandboxes I've found invaluable but doesn't touch on multiple containers - https://codesandbox.io/u/clauderic You might be able to glean some insight at least.

I've tried most DnD libs and I love the low level implementation, allowing you to wrap it in your own code to expand it in the direction you need it too. Of course the downside is this becomes challenging especially for a lib with a small community and not much on e.g. stack overflow, but the idea is once you've created your code, you should be able to reuse it in other projects quite easily.

Chunkford commented 1 year ago

Also, here's a codesandbox I've found that does multiple containers - https://codesandbox.io/s/react-multiple-container-drag-and-drop-forked-sdd2km But the actual containers themselves are not sortable. It helped me tho so hopefully that will help you to :)

Then there's the storybook version of multiple containers - https://master--5fc05e08a4a65d0021ae0bf2.chromatic.com/?path=/story/presets-sortable-multiple-containers--basic-setup Here's the code - https://github.com/clauderic/dnd-kit/blob/master/stories/2%20-%20Presets/Sortable/MultipleContainers.tsx But OMG storybook is so frustrating

Monu18765 commented 1 year ago

Thanks @Chunkford codesandbox example is helpful but still it is a nightmare to use this library.

Monu18765 commented 1 year ago

I think this tutorial is excellent to understand Drag and drop between MultipleContiners https://www.youtube.com/watch?v=RG-3R6Pu_Ik

nikischin commented 8 months ago

I really like the idea of the library, however, I agree using it turnes out to be quite a nightmare. I really don't understand why to use the concept of a <DragOverlay/> instead of a PreviewContainer or something like that first of all. Like in the majority of cases I just want to move what I am touching but need to replace it with a placeholder with this library and render it at another place again.

Then talking about multiple containers, I would expect the library to handle the moving between containers for me, but I need to implement hundreds of lines, temporary states, refs, etc. just to be able to move between containers and it's super complicated and not straightforward. This is really a bit of a pity, as this library overall looks very nice, though when going deeper is rather a nightmare to implement unfortunately.

maiconcarraro commented 7 months ago

I managed to figure out a better solution for my context because I had the individual containers using react-query (trpc), so not able to reproduce the logic from the examples above since it uses a single state in the parent, I already had redux for specific behaviors, so I used it to fit a better approach:

  1. For the redux slice I have two attributes:

    currentOver: { containerId; string, activeId: string };
    maps: Record<string, string[]>; // key = container id and value = sortable id
  2. Inside of each container I have an useEffect to sync react-query data w/ the maps from redux slice.

  3. For each item that has useSortable, the id is composed on ${container.id}_${item.id} (make easier to capture the container over)

  4. DndContext onDragOver only needs to get the over split the id to get the container id. and update currentOver from the slice + active.

  5. Final part is the SortableContext based on currentOver + maps (inside of each container)

            <SortableContext
              items={
                currentOver.containerId === id
                  ? [
                      maps[id].includes(
                        currentOver.activeId,
                      )
                        ? "" // over its original container, so dont mess position
                        : currentOver.activeId, // dynamically include the id to another container
                      ...(maps[currentOver.containerId]?.map((id) => ({ id })),
                    ]
                  : []
              }

Seems very possible to build an api context to do this automatically using the proper functions and abstracting all the complex part, don't have the time right now to do this, but I can assist if anyone needs support w/ a solution similar to mine

nikischin commented 5 months ago

I ended up switching to pragmatic-drag-and-drop. It's far from perfect but performance is amazing and also implementation (if you integrate it into a custom hook) is very pretty compared to anything I have seen before. It has quite some browser bugs still present but generally works nicely on both desktop and mobile.

Monu18765 commented 5 months ago

Good job @nikischin I think Pragmatic-drag-and-drop is the future in the react ecosystem considering it is built by Atlassian.

clauderic commented 4 months ago

This is all fair feedback. You're free to use whichever library works best for you, and the answer to that question can largely depend on the use-case(s) you have.

In case you aren't aware, however, I've been working on rebuilding @dnd-kit from the ground up over the past year. One of the main goals of this refactor is to make it much simpler for consumers to adopt it, and make complex use-cases like setting up multiple lists much more straightforward.

For example, here is a detailed guide I have been working on that explains how setting up multiple lists will work with the new version of @dnd-kit:

Screenshot 2024-06-11 at 8 58 18 PM

You can follow along here for development updates. It's been a long journey and I can't promise when the new version will officially replace the current one, but you can expect more updates in the near future.

MGSimard commented 4 months ago

This is all fair feedback. You're free to use whichever library works best for you, and the answer to that question can largely depend on the use-case(s) you have.

In case you aren't aware, however, I've been working on rebuilding @dnd-kit from the ground up over the past year. One of the main goals of this refactor is to make it much simpler for consumers to adopt it, and make complex use-cases like setting up multiple lists much more straightforward.

For example, here is a detailed guide I have been working on that explains how setting up multiple lists will work with the new version of @dnd-kit: Screenshot 2024-06-11 at 8 58 18 PM

You can follow along here for development updates. It's been a long journey and I can't promise when the new version will officially replace the current one, but you can expect more updates in the near future.

Refactored my drag api Tier List tool (which acts similar to a Kanban board) using those alpha libraries and the guide, took about 10 minutes and got a working setup.

certified banger, thanks

Markopteryx commented 3 months ago

Like the above comment I was able to follow along and honestly it works great for its purpose. I am wondering if it would be possible to basically do the same thing but without the sorting and have the elements snap to a grid inside each container? This way you could put items anywhere in each container and the gap between them would be meaningful