7 ms·
I was researching drag and drop in JS recently, and what I found seemed pretty disappointing. Wondering if anyone can reinforce my opinion or counter it. Drag
by tekstar 6y ago
I was researching drag and drop in JS recently, and what I found seemed pretty disappointing. Wondering if anyone can reinforce my opinion or counter it.
Drag and drop still seems like a mess. Browser support and touch support varies so you can't just use native APIs. Every popular library sits with tons of open issues and open PRs. Corporate solutions that have been open sourced appear abandoned. All the libraries I saw clocked in over 100kb.
Am I wrong? I want the "preact" or "day.js" drag and drop library. 10kb or less poly fill that gives me the basics. Does that exist?
- city41 6y agoThis has been my experience too. Every React DnD library I have used has had some painful moments for me, sometimes super painful. For the app I am working on now I have pretty simple DnD needs so I just rolled my own using mouse events. it's about 100-200 lines of code total and works great. To the library authors's credit, I think creating a general DnD library that can address most use cases is tough.
- tekstar 6y agoThis is all I want, too. But if you go the DIY route, don't you end up chasing the long tail of browser and device compatibility issues and bugs? I typically solve my own issues but this one just seems like a huge and uneven surface area. I would love to see your 100-200 lines if you are willing to share. Not asking you to ship it and support it and end up the N+1'th unsupported DND library though ;)
- city41 6y agoYeah, rolling your own is probably a bad idea in most cases. My implementation doesn't generalize at all really and I only need to support desktop browsers. If I ever own source this app I'll let you know. But basically I have one component listening to mouse events and firing callbacks with the rectangle the user has dragged (mouse down point to most recent mouse point), and with that my state manager updates things accordingly and drops upon mouse release.
- tmotwu 6y agoIts sometimes worth going the DIY route, especially in this case. Drag and drop could cause all sorts of compatibility issues if you try very hard to generalize, sure. I wrote my own as well, not in 100-200 lines granted. Dependency free ~300-400sloc using basic mouse events and element calculations were enough to implement advanced behaviors such as snapping, collision detection, free movement, packing, swapping, containerization. I had lots of freedom on how it behaves and was able to tweak it to what I wanted, something probably impossible with general dnd libraries. It works the same in most modern browsers I've tested, since it's only using DOM apis for basic events and style modification. Libraries are great if you need established algorithms and data structures. Building out custom UX interactions, presumably like interacting with DOM objects, DIY was easier since there's actually very little work to do.
- jimmy2020 6y agoI share your disappointment and I'd like to invite you to DFlex (https://github.com/jalal246/dflex https://github.com/jalal246/dflex). It's not perfect and in the development process but I think it's a real alternative to native-like API focused on performance and easy implementation. It's just a pure js. So every fix should enhance all framework implementations. Decoupled with a separate package to prevent a bloated bundle. Work with mouse event, so nothing new to learn. And most importantly it's just a utility. You can use what you want. Finally, it doesn't sort, move,s or whatsoever. Node positions are stored separately. Each movement calculates the current position and triggers any effect that movement caused. So It may cause "dragging only with zero effect" Or "Switch with another element". It has also container/children architecture. So you can drag a child, or parent..etc Edit: I have implementation for React and Vue but not for Svelet. So if anyone is interested let me know. And congrats to Isaac for this nice work dedicated to Svelte community.
- JMTQp8lwXL 6y agoOne of the up and coming React DnD projects is https://github.com/clauderic/dnd-kit https://github.com/clauderic/dnd-kit. It's still in beta, and the drag/drop animations are rough around the edges, but it appears to be targeting an enterprise-grade set of features, including accessibility support. Its core + plugin model will likely be the closest you can get to bundle size minimization. Until the situation improves, for production, I use react-beautiful-dnd. Long term, I think this might actually be a good problem to be solved in web components (e.g., using something like Stencil), then output targets for React, Svelte, Angular, etc can be generated.
- jimmy2020 6y agoReact kit is an implementation of Shopify's famous package: https://github.com/Shopify/draggable https://github.com/Shopify/draggable It's great but complicated with strict API. While react-beautiful-dnd is so React-ish. To manipulate DOM you need pure js with a solution can expose DOM elements to you because you probably need to do more than dragging an element on your layout.
- lhorie 6y agoI've heard good things about dragula[0]. It's 9.8kb minified[1], no dependencies and browser support goes all the way back to IE7. There are also bridges for all the major frameworks. [0] https://bevacqua.github.io/dragula/ https://bevacqua.github.io/dragula/ [1] https://bundlephobia.com/result?p=dragula@3.7.3 https://bundlephobia.com/result?p=dragula@3.7.3
- wirahx 6y agocan confirm that dragula works well. If you don't need all the crazy browser support though, doing it like this is much more lightweight.
- duhi88 6y agoLooks pretty solid to me. Good demos of some common edge-cases. I wouldn't say "all" the major frameworks, though (just Angular[JS] and React).
- lhorie 6y agoThere are also vue bridges, though admittedly unofficial.
- chrismorgan 6y agoThat’s not no dependencies, it’s two direct dependencies, one of which is crossvent, which is 2.2kB of stuff that’s mostly not used (only around 0.6kB of it is used). There are also a couple more transitive dependencies. But the 9.8kB figure does include all the dependencies. I actively hate spending bytes supporting IE (and especially such ancient versions as IE7), and if necessary maintain forks of any libraries I use to avoid doing so; so I tried ripping out IE support along with crossvent and a few obsolete and/or bad abstractions, and quickly got it down to 7kB minified, and I expect one so inclined could shrink it further. (The crossvent part can be done in two minutes, it’s that simple.) I should really make a feature of this kind of thing on my blog, I enjoy doing it so much.