Drag & Drop
@domphy/dnd adds sortable lists and drag & drop to Domphy: reorder, transfer between lists, multi-drag, keyboard accessibility, and drop animations.
Unlike the TanStack ports (query/table/router/virtual/form), drag-and-drop has no portable framework-agnostic core to copy byte-for-byte. So this package depends on @formkit/drag-and-drop (MIT, zero-dependency, framework-agnostic) and adds a thin Domphy adapter — the same way FormKit's own React/Vue/Solid adapters wrap the engine. The full FormKit API is re-exported.
Install
npm install @domphy/dnd @domphy/core
@domphy/core is a peer dependency.
Live Example
Usage
Apply dragDrop(state, config?) to the list container with $, and render the children reactively from the same state with a stable _key:
import { toState } from "@domphy/core"
import { dragDrop } from "@domphy/dnd"
const items = toState([
{ id: 1, label: "Write docs" },
{ id: 2, label: "Ship it" },
])
const App = {
ul: (l) => items.get(l).map((item) => ({ li: item.label, _key: item.id })),
$: [dragDrop(items)],
}
Dragging reorders the DOM, FormKit calls setValues → the items state updates → Domphy re-renders the keyed children in the new order. The _key is required so the reorder maps to the right nodes.
Config & plugins
dragDrop(state, config) forwards config to FormKit's ParentConfig, and the whole FormKit API (plugins, sensors, group transfer) is re-exported:
import { dragDrop, animations } from "@domphy/dnd"
// drop animations + transfer items between any lists sharing a group
{ ul: (l) => ..., $: [dragDrop(items, { plugins: [animations()], group: "todos" })] }
Give two lists the same group to transfer items between them. Accessibility, touch and synthetic-drag handling come from FormKit — see the FormKit DnD docs for the full config.
Cleanup
The adapter tears down FormKit's listeners automatically on removal (_onRemove).