Handling drops
The library never mutates your data. When an item is dropped, the destination droppable emits a DropEvent, and you apply the move.
The drop event
destination.index is the insertion index after the item is removed from its source. "Remove at source.index, then insert at destination.index" is always correct, whether the move stays in one list or crosses lists.
With virtual scrolling most items are not in the DOM, so always work from the event's indexes, never from DOM order.
Helpers
Signals
Stores and immutable state
applyMove() returns a shallow copy of the record, with new arrays for the lists that changed.
Saving to a server
Apply the move straight away and roll back if the request fails:
Drag lifecycle events
Draggables also emit (dragStart) and (dragEnd):
(dragEnd) fires after every drag, dropped or not. Check event.destinationIndex === null to detect "no drop": the drag was cancelled (for example with Escape), or released outside every droppable or over a disabled one. Don't rely on cancelled, which is true only in the first case. DragEndEvent lists every way a drag can end without a drop.
During a drag, droppables and <vdnd-sortable-list> emit (placeholderMove) each time the placeholder moves within them. Use it for per-step feedback such as haptics. See Animations and haptics.
To react to drags anywhere in the app, for example to show a hint, inject DragStateService and read its signals, such as isDragging() and activeDroppableId(). See the API reference.