drag-drop-engine
v1.0.0
Published
Performant drag and drop engine without heavy dependencies. Supports collision detection, multi-drag, and mobile.
Maintainers
Readme
drag-drop-engine
Lightweight, dependency-free drag and drop engine for the web. Supports multi-drag, collision detection, mobile/touch, and auto-scroll.
Installation
npm install drag-drop-engineFeatures
- No heavy dependencies
- Collision detection: overlap, center-point, closest-edge strategies
- Multi-drag with Ctrl/Cmd+click selection
- Full mobile/touch support
- Auto-scroll near viewport edges
- Ghost element with CSS transform (GPU accelerated)
- Kanban, builder, list, and grid use cases
Quick Start
import { DragDropEngine } from "drag-drop-engine";
const engine = new DragDropEngine({
collisionStrategy: "overlap",
multiDrag: true,
onDrop: ({ items, source, destination, newIndex }) => {
// Update your state here
moveItem(source.id, destination.id, items[0].id, newIndex);
},
onDragStart: ({ item }) => {
console.log("Started dragging", item.id);
},
});
// Register containers (drop zones)
const listA = document.getElementById("list-a");
const listB = document.getElementById("list-b");
engine.registerContainer("list-a", listA);
engine.registerContainer("list-b", listB);
// Make items draggable
items.forEach((item, index) => {
const el = document.getElementById(item.id);
engine.makeDraggable(el, { id: item.id, containerId: "list-a" }, index);
});API
new DragDropEngine(options)
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| onDragStart | (event: DragEvent) => void | - | Fired when drag begins |
| onDragMove | (event: DragEvent) => void | - | Fired on each move |
| onDragEnd | (event: DragEvent) => void | - | Fired when drag ends |
| onDrop | (event: DropEvent) => void | - | Fired on successful drop |
| multiDrag | boolean | false | Enable multi-item selection |
| animationDuration | number | 200 | Ghost animation duration ms |
| scrollSensitivity | number | 40 | Pixels from edge to trigger scroll |
| scrollSpeed | number | 10 | Pixels per scroll tick |
| collisionStrategy | "overlap" \| "center" \| "closest-edge" | "overlap" | Hit detection algorithm |
engine.registerContainer(id, element, accepts?)
Register an HTML element as a drop target.
engine.makeDraggable(element, item, index)
Make an element draggable. Returns a cleanup function to remove listeners.
const cleanup = engine.makeDraggable(el, {
id: "card-42",
containerId: "column-todo",
data: { title: "My Task" },
}, 3);
// Later:
cleanup();engine.clearSelection()
Clear the multi-drag selection.
engine.destroy()
Remove all listeners and containers.
Kanban Example
const engine = new DragDropEngine({
onDrop: ({ items, source, destination, newIndex }) => {
setState((prev) => {
const card = prev[source.id].find((c) => c.id === items[0].id);
return {
...prev,
[source.id]: prev[source.id].filter((c) => c.id !== items[0].id),
[destination.id]: [
...prev[destination.id].slice(0, newIndex),
card,
...prev[destination.id].slice(newIndex),
],
};
});
},
});
columns.forEach((col) => {
engine.registerContainer(col.id, col.element);
col.cards.forEach((card, i) => {
engine.makeDraggable(card.element, {
id: card.id,
containerId: col.id,
}, i);
});
});Running Tests
npm install
npm testLicense
MIT
