sveltejs / v2.svelte.dev

The Svelte v2 website
https://v2.svelte.dev
MIT License
210 stars 79 forks source link

Add drag and drop example #208

Open Rich-Harris opened 6 years ago

Rich-Harris commented 6 years ago

From @gka: https://svelte.technology/repl?version=1.51.0&gist=b2e2bc99a74361c92e5bf0f57daab175

Need to check it works on mobile first

mindplay-dk commented 6 years ago

Didn't work for me.

Updated to work with current version.

https://svelte.technology/repl?version=2.9.10&gist=8a9b145a738530b20d0c3ba138512289

I wanted to see what it was, but I don't know that this is a very useful example - for most use-cases, ordering/sorting is going to be important, but likely that's much harder to implement?

mindplay-dk commented 6 years ago

See also #581

PierBover commented 5 years ago

(Since this is the first result on google I will ask here)

Is there any example of an implementation of drag and drop with Svelte that does not use the HTML5 draggable API?

I've implemented drag and drop solutions in the past (vanilla, jQuery, AS3, C++) and it was somewhat easy. I'm trying to do it now in React and it's so arduous... I'm starting to see the limits of not having direct access to the scene graph since the virtual DOM is actually controlling the nodes.

I've started to think that a drag and drop implementation would probably be the best test of a UI library after a todo list.

mindplay-dk commented 5 years ago

@PierBover I wrote this library with the intention to build something that would work in Svelte, but ended up using Preact for that project, so I never got around to testing it with Svelte. This is for custom drag-operations - it does not use the HTML5 draggable API.

I'm starting to see the limits of not having direct access to the scene graph since the virtual DOM is actually controlling the nodes.

That's where I was when I set out hardcoding event-handlers in Preact like I would have with any plain DOM project. It worked okay in Preact, but was still pretty tricky for some corner cases.

You need to be really careful with keys on elements that get dragged or dropped to - if a DOM element gets removed/replaced during the drag-and-drop operation, it loses the DOM reference.

You also need to be really strict about letting the UI library (Preact) apply all the DOM changes - for example, if you're repositioning a "drag ghost", use inline style to render and position it, and use e.g. pointer-events: none to keep it from interfering with the events.

My library worked for this (and should work with Svelte) since it deals exclusively with events and doesn't create/modify DOM elements directly. It requires a single event-handler to be attached to onmousedown to start the drag-operation, and you should let e.g. Svelte attach it - the library will then attach/remove temporary global event-handlers during the drag-and-drop interaction, which won't interfere with anything Svelte is doing.

If you'd like to try it with Svelte, I'd be glad to get some feedback.

PierBover commented 5 years ago

Thanks @mindplay-dk .

I was actually looking for a quick example to get an idea how DnD would work with Svelte, rather than a library, but I've skimmed the code in your library and your approach makes sense to me.

So how does Svelte maintain a "link" between the DOM nodes it has generated and the component at the JS level?

Is it OK to getElementById() and then move that element wherever I want to?

mindplay-dk commented 5 years ago

So how does Svelte maintain a "link" between the DOM nodes it has generated and the component at the JS level?

Are you asking me how Svelte works? I honestly don't know the details.

Is it OK to getElementById() and then move that element wherever I want to?

No.

Avoid any manual DOM manipulation - if you're going to move an element, such as a drag ghost, use the library to track the drag-events, apply the coordinates to state in Svelte, and let Svelte move the element.

I found it's a good idea to leave the original (dragged) element where it is, and have a separate element for the drag ghost, which displays conditionally, e.g. only during a drag-drop operation.

PierBover commented 5 years ago

Are you asking me how Svelte works? I honestly don't know the details.

Well... I'm just asking, in case maybe @Rich-Harris has some time left. :)

Thanks for the ideas @mindplay-dk 👍

FormBucketSupport commented 5 years ago

Updated to work with v3.

https://svelte.dev/repl/3721cbc9490a4c51b07068944a36a40d?version=3.4.2

fujiii commented 5 years ago

Updated to work with v3.

https://svelte.dev/repl/3721cbc9490a4c51b07068944a36a40d?version=3.4.2

Seems to work only on Chrome, right?

FormBucketSupport commented 5 years ago

Updated to work with v3. https://svelte.dev/repl/3721cbc9490a4c51b07068944a36a40d?version=3.4.2

Seems to work only on Chrome, right?

The HTML5 Touch API is not implement so I wouldn't expect it to work on tablet or phone. I tested it in firefox and it worked ok for me.

raphet commented 4 years ago

This doesn't work on chrome mobile (android 9). Is there a way to enable d&d with svelte on mobiles, too? At least caniuse reports that it should theoretically work on Chrome for android since 22. October. Also I can confirm that this issue only exists in svelte. Drag & drop in vanilla javascript works correctly on android chrome.

raphet commented 4 years ago

I have created a drag&drop example on svelte3 that even works on mobiles:

https://svelte.dev/repl/810b0f1e16ac4bbd8af8ba25d5e0deff?version=3.4.2

Thanks to all my predecessors :-)

louwers commented 4 years ago

@raphet Does not work on Firefox for Android 68.4.1 (selects text instead)

Works on Chromium though!

ddoice commented 3 years ago

Why is the performance so bad in all the D&D examples of Svelte?

Love how simple the code is compared to other D&D libs but when I drag the elements are very slow (near to 1 FPS).

PierBover commented 3 years ago

@ddoice it works fine here at 60 fps. I doubt it's a Svelte thing.