Core concepts
Every setup, from one list to a full board, is made of the same four parts.
Life of a drag
- The user presses on a draggable and moves past the drag threshold (5 px by default), or presses Space on a focused draggable.
- The dragged element is hidden with
display: none. The preview appears under the pointer and an empty placeholder marks the drop position in the target list. - As the pointer moves, the library works out which droppable is under it and at which index the item would land. Near the edges of a scrollable list it scrolls automatically.
- On release, the dragged draggable emits
(dragEnd), whether the item was dropped or not. If it was dropped, the destination droppable then emits(drop)with the source and destination indexes. Both fire before the next render. - Your handler updates the data. The library never changes your arrays.
See Handling drops for the event shape and the helper functions.
Rules that fail silently
Breaking any of these rules causes no build error. The list just does not drag, or drops items in the wrong place.
- Every draggable and droppable needs a group, even when there is only one list. Wrap them in
vdndGroup, or setvdndDraggableGroup/vdndDroppableGroup(groupon<vdnd-sortable-list>). Without a group, dragging is disabled and the only hint is a warning in the console in dev mode. - Declare the item
<ng-template>inside thevdndGroupelement. Templates resolve injection where they are declared, not where they are rendered. - The draggable ID must equal the list's item ID: what
itemIdFn(item)returns, or thetrackBykey for*vdndVirtualFor. IDs are strings, so convert numeric IDs the same way in both places. - Draggable IDs must be unique across all lists, and droppable IDs must be unique on the page.
- Render
<vdnd-drag-preview />once. Without it, dragging works but nothing follows the pointer. - Give every virtual list a height, with
containerHeightor with CSS. A list without a height collapses to 0 px. To size<vdnd-sortable-list>with CSS, set the height on its innervdnd-virtual-scrollfrom a global stylesheet. - Put
vdndDraggableon the root element of the item template. A wrapper around it would stay in the list during the drag and leave a gap. - Bind
(drop)on every list that can receive items. It fires on the destination only. - With fixed heights, make every row exactly
itemHeightpixels tall, borders and padding included. Otherwise the rows on screen drift away from the positions the list calculates. For rows of different heights, usedynamicItemHeight.
Troubleshooting maps common symptoms back to these rules.