For AI agents: the complete documentation index is available at https://gultyayev.github.io/ngx-virtual-dnd/llms.txt, the full documentation bundle is available at https://gultyayev.github.io/ngx-virtual-dnd/llms-full.txt, and this page is available as Markdown at https://gultyayev.github.io/ngx-virtual-dnd/guide/essentials/choosing-a-component.md.

Choosing a component

The first three options support dynamic heights, pointer auto-scroll and moving items between lists. They differ in how much markup you control and in which element scrolls. Only <vdnd-sortable-list> and <vdnd-virtual-scroll> scroll to follow a keyboard drag.

You wantUse
A sortable list with the least code<vdnd-sortable-list>
Your own markup around the scroller, or programmatic scrollingvdndDroppable + <vdnd-virtual-scroll>
A list that scrolls with the page, or inside Ionic ion-contentvdndScrollable + <vdnd-virtual-content>
A self-scrolling building block for a structural directive<vdnd-virtual-viewport> + *vdndVirtualFor

Sortable list

The default. One element combines the droppable, the virtual scroller and the placeholder. It also keeps the dragged item rendered while it is scrolled out of view. See the Quick start.

<vdnd-sortable-list
  droppableId="tasks"
  [items]="tasks()"
  [itemHeight]="48"
  [containerHeight]="400"
  [itemIdFn]="taskId"
  [itemTemplate]="taskTpl"
  (drop)="onDrop($event)"
/>

Low-level scroller

Put vdndDroppable on your own element and place <vdnd-virtual-scroll> inside it. Use this when you need a wrapper with its own layout, the stickyItemIds input, or the scrolling methods (scrollTo, scrollToIndex, scrollBy).

<div vdndGroup="tasks">
  <ng-template #taskTpl let-task>
    <div class="row" [vdndDraggable]="task.id">{{ task.title }}</div>
  </ng-template>

  <div class="panel" vdndDroppable="tasks" (drop)="onDrop($event)">
    <vdnd-virtual-scroll
      droppableId="tasks"
      [items]="tasks()"
      [itemHeight]="48"
      [containerHeight]="400"
      [itemIdFn]="taskId"
      [itemTemplate]="taskTpl"
    />
  </div>
</div>

Pass the same ID to vdndDroppable and to droppableId on <vdnd-virtual-scroll>. The scroller needs it to show the placeholder. To scroll from code, get the component with viewChild(VirtualScrollContainerComponent).

Page-level scroll

When the list scrolls together with the page, headers and footers, the scroll container is an element you own. Mark it with vdndScrollable and render items with <vdnd-virtual-content> and *vdndVirtualFor. See Page-level scrolling.

Virtual viewport

<vdnd-virtual-viewport> is a lower-level building block: a self-scrolling container for *vdndVirtualFor that positions all rows with a single transform. Children inherit itemHeight and dynamicItemHeight from it. For drag and drop, put vdndDroppable on the viewport itself; *vdndVirtualFor inherits its ID.

<div vdndGroup="tasks">
  <vdnd-virtual-viewport
    class="viewport"
    vdndDroppable="tasks"
    [itemHeight]="48"
    (drop)="onDrop($event)"
  >
    <ng-container *vdndVirtualFor="let task of tasks(); trackBy: trackById">
      <div class="row" [vdndDraggable]="task.id">{{ task.title }}</div>
    </ng-container>
  </vdnd-virtual-viewport>
</div>

Give the viewport a height with CSS (for example .viewport { height: 400px; }).