thisbeyond / solid-dnd

A lightweight, performant, extensible drag and drop toolkit for Solid JS.
https://solid-dnd.com
MIT License
515 stars 34 forks source link

Nested drag and drop #16

Open martinpengellyphillips opened 3 years ago

martinpengellyphillips commented 3 years ago

Would be good to have an example of nested drag and drop, as well as test and improve the API if necessary for this use case.

Imagine a classic filetree for example.

martinpengellyphillips commented 3 years ago

See also someone experimenting with this type of interface: https://codesandbox.io/embed/solid-nested-dnd-prototype-uu5jm?file=/src/App.tsx&codemirror=1

dharmaturtle commented 2 years ago

Hi, just here to express my interest in a file tree-style drag and drop demo. Unfortunately, the above link no longer seems to work/load. (I'm just futzing around with a side project - please don't take this as an obligation or time-sensitive issue!)

martinpengellyphillips commented 2 years ago

Ah, that link was just an example of what someone was trying to do - not a working implementation for Solid DnD. I've updated the comment to be clearer.

I'll take a look at a Solid DnD example on the main site in the near future - but if you get something first, please feel free to share a PR.

99bits commented 2 years ago

Really amazing project Martin.
Would really like to use your project and wondering if something like the link below can be made: I tried to do it with dnd-action and that package is not able to support it. Perhaps yours can.

https://svelte.dev/repl/1f3437021e76495e83746200ed002096?version=3.46.4

Desired Behaviour:

  1. Accordions can be reordered with dragndrop.
  2. Accordions cannot be dragndrop into subaccordions.
  3. Subaccordions can be reordered within same parent Accordion.
  4. Subaccordions can be dragndrop into other parent Accordions.
  5. When a subaccordion is dragndrop into other parent Accordions, it will be added to the new parent Accordion and removed from the accordion where it came from.
martinpengellyphillips commented 2 years ago

Thanks for the kind words.

I haven't tried to do something similar yet. I'm sure the basic building blocks will make it possible in solid-dnd, but I'm also sure there will be things to figure out. In other words, I don't believe it will just work out of the box.

I would be curious about any attempt you make and where you hit issues that I might be able to address in the core. Meanwhile, I'm working on a related example which might uncover some better answer here.

By the way, I'm surprised https://github.com/isaacHagoel/solid-dnd-directive couldn't do it as based off same Svelte lib as in your example. What was the issue faced there?

99bits commented 2 years ago

Hi Martin,

That example that I made was in Svelte using Isaac's dragndrop project. If you play with the example, you can see that draging a subaccordion into another accordion doesn't work as expected. The subaccordion should be removed from where it was dragged from and added into the new accordion.

I didn't try to use his solidjs because the svelte project is not working correctly.

martinpengellyphillips commented 2 years ago

Ah, understood.

I'm making good progress on some improvements to solid dnd that might help for your use case. I'll post an update here once they are done.

99bits commented 2 years ago

That would be amazing. A solid DnD to rule them all. Kudos

martinpengellyphillips commented 2 years ago

0.5.0 has been released and should make implementing nested use cases easier as it supports seamless recreation of draggables/droppables during active drag (as well as a new closestCorners collision detector). You can see this working in the new multiple lists example on https://solid-dnd.com/

However, I will leave this issue open until I or someone else successfully implements a working nested example 😄

Note: 0.5.0 release contains breaking changes - see changelog for details.

HiperMaximus commented 2 years ago

+1 on an example of nested dnd

martinpengellyphillips commented 2 years ago

The "Board" example on the site now gives some example of nested in that both the columns and the items within them can be dragged and sorted independently. However, I'll leave this open as I also want to add a more specific nested example where items can be arbitrarily nested within each other.

Adevien commented 12 months ago

Any update on this? I'd love a nested example, currently trying to figure it out myself but no luck.

wadamek65 commented 4 months ago

Hey, just wanted to mention that I implemented something similar to this using solid-dnd in my own application. It's not a perfect nesting multiple droppable zones within one another but it's an example implementation of arbitrary drag&dropping elements in a file tree. You can find the code for it here and here. It's actually pretty simple and works out of the box, just need to be aware of which DOM elements you are applying the droppable and draggable as that may cause strange behavior. The working example can be found in my app here.

This is only the dnd part though and you obviously need the logic for reordering the items as well, like in my case this logic.

Hope this helps anyone trying to implement this on their own.

martinpengellyphillips commented 4 months ago

Thanks - I'll take a look. What in solid-dnd could make it easier to implement do you think?

wadamek65 commented 4 months ago

@martinpengellyphillips

Hmm, I'm not sure I can say exactly what to improve but I'll try to describe my overall experience in case it gives you an idea:

I started by figuring out which elements to make draggable and droppable. I remember some weird behaviors if I made the same element both draggable and droppable or if I nested them in certain ways. This took a little bit of experimentation but was not unexpected as some combinations just naturally produce undefined behavior.

I didn't want it to look like the user was dragging the whole tree so I implemented a custom drag shadow. This was very simple other than my one misunderstanding of the createDraggable reactivity.

I added in the custom logic for figuring out what happens when something gets drag and dropped. Had a few edge-cases to cover like parent being dropped onto a child or an element dropped onto itself etc. But I don't think this should be the responsibility of the package itself but rather the application that uses it.

Overall, implementing it was rather straightforward. The package behaved and worked just like I expected it to so everything went smooth. Hope this helps somehow.

martinpengellyphillips commented 4 months ago

Super useful - thank you!