I have no idea how DFlex works under the hood (nor any other modern drag & drop library), but I'll share something clever I came up with. I'm sure others arrived at a similar solution.
I had to build something for my employer's website maybe 12-15 years ago. jQuery was the hot, new thing at the time. So was customizing UI. All available solutions used a combination of absolute positioning & coordinates to determine the interactivity of the elements. As you can imagine, it was a finicky, buggy mess.
I found myself wishing I could just use the DOM's own mouseover event -- but that didn't work, because the cursor was only over the element being dragged. My epiphany was this: When an element was picked up (drag start), I could duplicate every element in the set and set their opacities to zero (I called them "ghosts"). If I gave them a higher z-index than the element being dragged, mouseover events would be triggered on the ghost elements and I wouldn't have to do anything with coordinates, ever. It was also, by far, the most efficient solution at a time when browsers kinda sucked.
(I finally had a reason to share this anecdote.)
Anyway, thanks for this library, I'll be taking a look!
Cloning elements and duplicating containers are what DFlex tries to avoid. Because the usual implementation is to clone the element (ghost it) and then append a new one with a fixed position. The result is to reconstruct the DOM tree directly with every user interaction which leads to poor user experience and not a very practical transformation. That's why the default thing to do with DFlex is not to clone or change the element position unless there's a need to do so, for example: transforming from a container with a scroll.
Hi HN, DFlex author here. I built DFlex because I couldn't find a comprehensive solution for interactive apps. All existing solutions depend heavily on HTML5 drag and drop to achieve interactivity despite the fact that the standard implementation is not designed to turn the apps into an interactive ones. So I started from scratch, built the transformation mechanism, and implement a custom reconciler built specifically to deal with DOM transformation. It also has a concurrent registration to prevent any blocking event and reduce initial loading. I also tried to take care of browser painting and scripting time. It's still in development mode but I'm glad it's shared here. Happy to take any questions you have and I'd love to get your feedback.
A request: could you please remove "case" from the font-feature-settings on the root element of https://www.dflex.dev/. It’s wrong (its purpose is to tweak vertical positioning of punctuation to align with all-caps text, which is not the case here), and some fonts (including a couple of the largest font foundries) also have "case" effectively imply `text-transform: uppercase`, and I’m using such a font, so the entire site is inappropriately uppercase for me.
(The rest of the font-feature-settings declaration also doesn’t make much sense: "case" 1, "rlig" 1,"calt" 0: rlig is for other scripts, and calt is a weird thing to turn off. I’d remove the entire declaration.)
The live demo[1] is completely unusable for people relying on assistive technology like screen readers and speech recognition, plus anyone using alternative input modalities like the keyboard. Do you have accessibility on your roadmap, to ensure that you're not encouraging users of your library to exclude a large percentage of the world's population?
I spent a long time a few weeks ago looking for a replacement for jQueryUI's sortable(), but none of the DnD libraries supported both sortable and the grid option out of the box. Would yours work for that?
Here's where we want to use it:
https://pamelafox.github.io/faded-parsons-static/problem.htm...
I was wondering if DFlex supports nesting containers inside items in infinite depth.
I saw you had nested example but I couldn't drag on item on the other container.
None the less promising, you say it's still in development, is there some aspects you are more specifically working on?
Having done something similar before, 2 things really hard to get right:
- animate position shift when the list is reordered. you can't rely on natural dom ordering to properly animate all items
- anything that has to do a tree structure
In Firefox I noticed some flickering when dragging a lower item to the top edge of the black box on this page: https://www.dflex.dev/demo/lists/asymmetric/ it might need some debouncing or something since it appears to be repeatedly redordering when it's in right on the edge/border (might not be a standard usecase but it was noticeable).
Demos in the site are behind the current version and not being updated to the latest one [1]. And updating the demos will take a while since I have to take resizing containers into consideration. So the current version is 2.x.x while the last one was 3.7.0. Sorry about that.
It's true that the HTML drag and drop API is pretty limited for more complex interactions. I recently did a lot of searching for a drag and drop library for a board game I'm working on and almost went with DFlex. I decided to go with DnD Kit because of its powerful React API. However, I'm very glad there's a vanilla JS solution as well with DFlex.
Thanks for the feedback. DnD kit is amazing and the initial library also is so powerful [1]. But we still need a comprehensive solution. Committing changes to DOM with each interaction and shadow caching is not a sustainable solution for building interactive apps. React or any other framework is not designed for interactivity. So even if you are using React you are not actually getting the benefit of React to reconcile because you still committing changes directly to DOM. That's why I built DFlex which has its own reconciler and transformation mechanism.
HTML drag and drop does have a few powerful features that cannot be done otherwise. You can move an item outside your app into, for example, a native photo library app. Or even on iPhone, drag/drop an item to iMessage and send it to someone as an image or piece of text. Something that also doesn't work in DFlex is scrolling through a page while holding an item, something that also "just works" with native HTML drag and drop.
Thanks for sharing the link. Appreciate your feedback. I'd like to point out that the site is not fully updated. The last release is not included in the demo yet but I'm working on it.
I hate to ask, since you built this framework with vanilla in mind... but what happens when you use this with React? Does the "infinitely transformed DOM" work with React components and states? Should we not even try?
You are invited to try and give me your feedback or work on any issues you have. The playground and the end-to-end tests are done entirely with React. I am not sure why you suggest it's not going to work with it. Also, it has to be done this way, since how to reconcile transformation is different from than usual reconciler algorithm.
DFlex has an infinite transformation mechanism even between containers. So you can transform indefinitely and if you want you can enable committing to DOM which will trigger a custom reconciler built specifically for transformation. It's also not just for React, you can hook it with your JS framework.
Yeah that statement is simply not true. Manipulating the DOM was how all of this was done already in the before jQuery days, not to mention many, many libraries since.
Product managers are absolutely ga-ga for drag & drop, no matter how much you tell them it'll at least double the defect rate on the site and slow down all future user-facing feature development. It's that valuable to them, to the tune of effectively hundreds of "story points" over the life of a Web project.
So the use case is adding drag & drop interaction to sites, which is evidently extremely desirable.
[+] [-] rolha-capoeira|3 years ago|reply
I had to build something for my employer's website maybe 12-15 years ago. jQuery was the hot, new thing at the time. So was customizing UI. All available solutions used a combination of absolute positioning & coordinates to determine the interactivity of the elements. As you can imagine, it was a finicky, buggy mess.
I found myself wishing I could just use the DOM's own mouseover event -- but that didn't work, because the cursor was only over the element being dragged. My epiphany was this: When an element was picked up (drag start), I could duplicate every element in the set and set their opacities to zero (I called them "ghosts"). If I gave them a higher z-index than the element being dragged, mouseover events would be triggered on the ghost elements and I wouldn't have to do anything with coordinates, ever. It was also, by far, the most efficient solution at a time when browsers kinda sucked.
(I finally had a reason to share this anecdote.)
Anyway, thanks for this library, I'll be taking a look!
[+] [-] jimmy2020|3 years ago|reply
[+] [-] jimmy2020|3 years ago|reply
[+] [-] chrismorgan|3 years ago|reply
(The rest of the font-feature-settings declaration also doesn’t make much sense: "case" 1, "rlig" 1,"calt" 0: rlig is for other scripts, and calt is a weird thing to turn off. I’d remove the entire declaration.)
[+] [-] jscholes|3 years ago|reply
[1] https://www.dflex.dev/demo/lists/symmetric/
[+] [-] pamelafox|3 years ago|reply
[+] [-] anton96|3 years ago|reply
Thanks for this lib, it looks very nice so far.
I was wondering if DFlex supports nesting containers inside items in infinite depth. I saw you had nested example but I couldn't drag on item on the other container.
None the less promising, you say it's still in development, is there some aspects you are more specifically working on?
[+] [-] mijoharas|3 years ago|reply
[+] [-] peppertree|3 years ago|reply
[+] [-] ape4|3 years ago|reply
[+] [-] lelandfe|3 years ago|reply
[+] [-] dmix|3 years ago|reply
I came across Shopify's recently which has an amazing website: https://shopify.github.io/draggable/
In Firefox I noticed some flickering when dragging a lower item to the top edge of the black box on this page: https://www.dflex.dev/demo/lists/asymmetric/ it might need some debouncing or something since it appears to be repeatedly redordering when it's in right on the edge/border (might not be a standard usecase but it was noticeable).
[+] [-] jimmy2020|3 years ago|reply
[1] - https://github.com/dflex-js/dflex/pull/573
[+] [-] caradine|3 years ago|reply
[+] [-] jimmy2020|3 years ago|reply
[1]: https://shopify.github.io/draggable/
[+] [-] cornedor|3 years ago|reply
[+] [-] TimMeade|3 years ago|reply
This looks worth checking out. Appears to work well on desktops and mobile.
[+] [-] jimmy2020|3 years ago|reply
[+] [-] solardev|3 years ago|reply
[+] [-] jimmy2020|3 years ago|reply
[+] [-] potamic|3 years ago|reply
I'm not sure this is the only library doing this. It's in fact a popular approach for drag and drop on the browser. I believe dndkit also does this.
[+] [-] jimmy2020|3 years ago|reply
[+] [-] Etheryte|3 years ago|reply
[+] [-] cosmotic|3 years ago|reply
[+] [-] jimmy2020|3 years ago|reply
[+] [-] pupppet|3 years ago|reply
[+] [-] gherkinnn|3 years ago|reply
[+] [-] jimmy2020|3 years ago|reply
[+] [-] daviddutch|3 years ago|reply
[deleted]
[+] [-] iamgopal|3 years ago|reply
[+] [-] yamtaddle|3 years ago|reply
So the use case is adding drag & drop interaction to sites, which is evidently extremely desirable.
[+] [-] jimmy2020|3 years ago|reply