Search documentation

Type to search the documentation.

Core

Drag & Drop

Sortable lists, between-container transfers, and drop zones — built on the native HTML5 DnD API with keyboard and touch support.

At a glance

  • Native DnD — HTML5 Drag & Drop API
  • Sortable — Reorder within a list
  • Typed drops — Accept only matching types
  • Touch ready — Mobile compatible

Live examples

Loading demo…

Code

File Upload Zone

<!-- Draggable file chip -->
<div qzDraggable [qzDraggableData]="file" qzDraggableType="file">{{ file.name }}</div>

<!-- Upload drop zone — accepts only 'file' type -->
<div qzDropZone [qzDropZoneAccept]="['file']" (qzDrop)="onFileDrop($event)">
  Drop files to upload
</div>

Sortable List

<!-- Sortable List -->
<div qzDropZone [qzDropZoneSortable]="true" (qzDrop)="onReorder($event)">
  <div qzDraggable [qzDraggableData]="item">{{ item.text }}</div>
</div>

Between Containers (Kanban)

<!-- Draggable Task -->
<div qzDraggable [qzDraggableData]="task" qzDraggableType="task">{{ task.title }}</div>

<!-- Drop Zone Column -->
<div qzDropZone [qzDropZoneAccept]="['task']" (qzDrop)="onTaskDrop($event, column.id)">
  <!-- Tasks here -->
</div>

Free Position Drag

<!-- Bounded container -->
<div class="canvas" (pointermove)="onMove($event)" (pointerup)="onRelease()">
  <!-- Freely positioned token -->
  @for (node of nodes(); track node.id) {
  <div
    class="token"
    [style.left.px]="node.x"
    [style.top.px]="node.y"
    (pointerdown)="onGrab($event, node.id)"
  >
    {{ node.label }}
  </div>
  }
</div>