Usage
TheSortable class allows you to reorder elements in a list or across multiple lists. A sortable element is both Droppable and Draggable, which means you can drag it and drop it to reorder.
First, create a DragDropManager instance and use it to create sortable items:
Multiple Lists
You can create multiple sortable lists by assigning sortable items to different groups:Drag Handles
By default, the entire sortable element can be used to initiate dragging. You can restrict dragging to a specific handle element:Animations
Sortable items automatically animate when their position changes. You can customize the animation through thetransition option:
Optimistic Sorting
By default, everySortable instance registers the OptimisticSortingPlugin. This plugin optimistically reorders DOM elements during a drag operation so that the UI feels responsive — without requiring your framework to re-render on every dragover event.
How it works
When you drag a sortable item over another sortable item, the plugin:- Physically moves the DOM elements to reflect the new order.
- Updates the
index(andgroup, for multi-list scenarios) on each affectedSortableinstance. - Sets the drop target to the drag source itself by calling
manager.actions.setDropTarget(source.id).
source and target on the operation will refer to the same element. This also means that isDragSource and isDropTarget will both be true on the dragged item.
Tracking position changes
Sincesource and target are the same, you cannot compare their IDs to determine what moved. Instead, use the sortable-specific properties available on the source:
Preventing optimistic sorting for a single event
If you callevent.preventDefault() in a dragover handler, the OptimisticSortingPlugin will skip the optimistic update for that particular event. This is useful when you want to handle certain moves yourself (for example, to prevent items from being dragged into a specific group) while still letting the plugin handle the rest:
Disabling optimistic sorting
If you prefer to manage sorting entirely in your application state (for example, by handling everydragover event), you can disable optimistic sorting by omitting the OptimisticSortingPlugin from the plugins array:
source and target will be different elements during drag, and you can use their IDs directly. However, you will need to handle reordering in your dragover listener for smooth visual feedback.
Managing state without the move helper
Themove helper from @dnd-kit/helpers is a convenience function that takes your items and a drag event and returns a new array with the item moved to its new position. It supports flat arrays and grouped records, handles canceled drags, and works with optimistic sorting out of the box.
If you need more control over state updates, you can manage state manually using the sortable properties and the isSortable type guard.
Single list
With optimistic sorting enabled (the default), you only need to handle thedragend event. The isSortable type guard narrows the source to expose initialIndex and index:
Multiple lists
For multiple lists, useinitialGroup and group to detect whether the item stayed in the same list or moved to a different one:
Type Guards
@dnd-kit/dom/sortable exports two type guards to help you work with sortable drag operations.
isSortable
Checks whether a Draggable or Droppable instance is a sortable element. If it returns true, the type is narrowed to expose sortable-specific properties like index, initialIndex, group, and initialGroup.
isSortableOperation
Checks whether both source and target of a drag operation are sortable elements. This is useful when you want to narrow the entire operation at once:
@dnd-kit/react/sortable@dnd-kit/vue/sortable@dnd-kit/svelte/sortable@dnd-kit/solid/sortable
API Reference
Arguments
TheSortable class accepts the following arguments:
string | number
required
A unique identifier for this sortable item within the drag and drop manager.
number
required
The position of this item within its sortable group.
Element
The DOM element to make sortable. While not required in the constructor, it must be set to enable sorting.
string | number
Optionally assign this item to a group. Items can only be sorted within their group.
Element
Optionally specify a drag handle element. If not provided, the entire element will be draggable.
Element
Optionally specify a different element to use as the drop target. By default, uses the main element.
SortableTransition | null
Configure the animation when items are reordered:
boolean | SortableDisabled
Set to
true to temporarily disable sorting for this item. Pass an object to disable dragging and dropping independently:string | number | Symbol
Optionally restrict which types of items can be sorted together.
Type | Type[] | ((source: Draggable) => boolean)
Restrict which draggables can be dropped on this sortable item. Pass a single
type, an array of types, or a predicate that receives the draggable and returns true to accept it.{[key: string]: any}
Optional data to associate with this sortable item, available in event handlers.
Properties
TheSortable instance provides these key properties:
index: The current position in the listgroup: The assigned group identifierisDragging: Whether this item is currently being draggedisDropTarget: Whether this item is currently a drop targetdisabled: Whether sorting is disabled for this item. Returns abooleanwhen dragging and dropping share the same state, or a{draggable, droppable}object when they differelement: The main DOM elementtarget: The drop target element (if different from main element)
Methods
register(): Register this sortable item with the managerunregister(): Remove this item from the managerdestroy(): Clean up this sortable instanceaccepts(draggable): Check if this item accepts a draggablerefreshShape(): Recalculate the item’s dimensions