Declarative, data-driven drag and drop components for sortable lists and
Kanban-style layouts. Built on svelte-dnd-action with Svelte 5 runes.
Each item needs a stable, unique string or number id.
IDs must be unique across all lists in a group. Give independent lists unique list IDs too: ungrouped lists with matching IDs share the same engine zone type. Pointer and keyboard sorting update bind:items on finalize; onchange runs only when the finalized ID order differs from its previous snapshot. Pointer dragging finalizes on drop; keyboard arrow moves finalize immediately, so keyboard persistence may run more than once during a grab.
Version 0.0.34 limitation: SortableGroup shares a zone type,
but its rules and typeField are not consumed by the current SortableList implementation.
Do not rely on them to reject cross-list moves.
SortableList renders a one-dimensional sortable
list. Item order can be changed by dragging; bind:items keeps state in sync automatically.
SortableGroup connects multiple SortableList instances, enabling items to be moved between columns. The items binding on each list stores its final order. This board accepts both tasks and bugs
in every column; group rules are not enforced in 0.0.34.
dragHandleSelector restricts drag initiation to a
specific element inside each item. Set the selector on the list and add a
matching attribute (e.g. data-drag-handle) to your
handle element. The rest of the item — inputs, buttons, text — remains fully
interactive and will never accidentally start a drag.
orientation="horizontal" switches the layout to
left-to-right. The drop indicator and sort logic adapt automatically.
orientation="grid" produces a wrapping (flex-wrap) horizontal layout — ideal for fixed-width items such as files or cards.
The dropIndicator snippet gives full control over
the indicator's appearance. It receives the engine’s shadow item (typed as item or undefined), so the
indicator can reflect the item's own color or type. The snippet replaces the shadow item’s content while dragging; the wrapper still participates in the sortable layout.
grabbedClass applies Tailwind classes to the drag
element’s first child — tilt, scale, shadow, opacity, or any combination. This uses the sortable engine’s element transform, not the native-preview helpers.
The empty prop renders an EmptyState when the list has no items. Particularly useful in Kanban layouts where
a column can become empty during a drag session. icon and title are required; description is optional.
To Do
Done
Nothing done yet
Drop completed tasks here.
Archived
Archive is empty
Move tasks here to archive them.
Use onchange to persist finalized changes or inspect movement metadata. Press Space or Enter to pick up a focused item, use arrows to move it, then Space, Enter or Escape to end the grab. In the installed engine, Escape drops at the current position; it does not restore the original order. Arrow moves emit finalize events immediately.
Reorder an item with the pointer, or focus it and press Space, arrows, then Space.
The separate dnd actions use Pragmatic DnD, not the SortableList engine. They do not reorder arrays or interoperate with sortable zones automatically. Supply data, canDrop and event callbacks to implement your own native-pointer behavior.
Drag the card into the target.
DropSlot is a visual insertion slot driven by atIndex and insertIndex. DropIndicator registers a native drop target with { type: "list-indicator", listId }; it delegates events to your callbacks. Neither is used internally by SortableList in 0.0.34, and neither moves data by itself.