Drag and drop
Drag and drop that reads as signals and drops a single splice into your own array. Make any element draggable with a typed payload, or build a sortable list on a native HTML5 engine or a pointer engine with FLIP, where siblings glide aside to open the gap and there is no browser drag image to fight.
@mmstack/dndnpm
npm install @mmstack/dnd @atlaskit/pragmatic-drag-and-drop@atlaskit/pragmatic-drag-and-drop is a peer dependency. It powers the native engine and the shared monitor.
#Two engines
The native engine uses the browser's HTML5 drag and drop, so it handles files, dragging across windows, and the browser drag image. The pointer engine uses pointer events with FLIP animation, so siblings glide aside to open a gap and there is no browser drag image to fight.
Both feed one session, so the state signals read the same either way. Set an engine per element, or set a default once with provideDnd.
#Setup
The primitives work with no configuration. Provide plugins when you want edge detection or auto-scroll. The zero-dependency plugins live in the @mmstack/dnd/plugins entry point.
import { provideDnd } from '@mmstack/dnd';
import { edgeAutoScroll } from '@mmstack/dnd/plugins';
import {
attachClosestEdge,
extractClosestEdge,
} from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
export const appConfig = {
providers: [
provideDnd({
plugins: {
hitbox: { attachClosestEdge, extractClosestEdge },
autoScroll: edgeAutoScroll,
},
}),
],
};A missing plugin degrades to a no-op with a dev warning rather than throwing.
#Two layers
The element layer is draggable and dropTarget (directives mmDraggable and mmDropTarget). Use it for free-form drag and drop, like moving cards between columns.
The sortable layer is reorderable plus a sortableGroup for cross-list moves. Use it for ordered lists, including nested and cross-list cases.
On top of those sit two preview layers: grids (a wrapping 2D sortable and a spanning dashboard grid) and a free-form canvas with move, resize, rotate, marquee and snaplines. Both write your state signal once per gesture, which is what op-log stores, undo history and realtime sync want.