When an activated session ends, usually by releasing the pointer, SnapSort officially “commits” to the drop. Ghosts are removed, and the item’s DOM element is moved to its final position.

onItemMove

To formalize the item drop, onItemMove is invoked on the root container with the container and index of the final position. As with the ghost item, the application must use this callback to update the list. And also as with ghosts, SnapSort will automatically handle animations, if enabled.

Swap mode instead dispatches one atomic onItemSwap; event.a and event.b name the two pre-swap slots.

If session.dropEffect is "none", SnapSort reports the resolved destination at drag end but suppresses the persistent move or swap callback.

Drop and Cleanup Order

The root’s onDragEnd runs for every drag that reached active state, including a return to the original source and cancellation. It does not run when onDragStart vetoes startup or the session otherwise fails before activation.

interface DragEndEvent {
  session: DragSession;
  item: Item;
  itemId: ItemId;
  itemMetadata: ItemMetadata;
  items: Item[];
  itemIds: ItemId[];
  itemsMetadata: ItemMetadata[];
  element: HTMLElement | null;
  source: DragLocation;
  sources: DragLocation[];
  destination: DragLocation | null;
}

destination is the final resolved direct Container and index. It may equal source; it is null when the lifecycle ends without a resolved destination. The session handle has status "ended" by the time onDragEnd runs, and root.dragSession has been cleared.

Cancellation and Failed Drops

Cancellation sets the effective drop behavior to "none", removes temporary ghosts, and skips onItemMove or onItemSwap. onDragEnd still runs with destination === null if the gesture had already activated.