Multi Selection
Select multiple items — by clicking checkboxes or rubber-band drawing with Ctrl — then drag them all at once as a single batch.
Demo
Three ways to select:
- Click a checkbox to toggle an individual item
- Hold Ctrl and drag an empty area to rubber-band select all items the rect crosses
- Mix both — checkboxes and rubber-band selections accumulate
Once items are selected, drag any one of them (by the ⠿ handle) to reorder the whole selection.
Checkbox selection
makeDraggable returns a selected writable computed ref. Bind it to a checkbox with v-model:
<script setup>
const { isDragging, isDragOver, selected } = makeDraggable(
itemRef,
{ dragHandle: '.handle' },
() => [props.index, props.items]
);
</script>
<template>
<div ref="itemRef">
<input v-model="selected" type="checkbox" />
<span>{{ task.name }}</span>
<button class="handle">⠿</button>
</div>
</template>Selecting an item adds it to the provider's selection set. Dragging any selected item automatically drags all selected items together.
Rubber-band selection with makeSelectionArea
makeSelectionArea turns a container into a lasso zone. When the configured modifier key is held, a pointer-drag draws a selection rectangle and selects all draggable items inside it.
const { isSelecting, style } = makeSelectionArea(containerRef, {
modifier: {
keys: ['ControlLeft', 'ControlRight'],
method: 'some', // either Ctrl key triggers selection
},
});Render the selection rectangle using the returned style:
<div ref="containerRef" style="position: relative">
<!-- Selection rectangle -->
<div
v-if="isSelecting"
class="selection-rect"
:style="style"
/>
<TaskItem v-for="(task, i) in tasks" ... />
</div>.selection-rect {
position: absolute;
border: 1.5px solid var(--vp-c-brand-1);
background-color: rgba(62, 175, 124, 0.1);
pointer-events: none;
z-index: 10;
}Provider scope
makeSelectionArea must be called in a component that is a descendant of <DnDProvider> — not the same component that renders it. Both makeSelectionArea and makeDroppable use inject internally.
Multi-drag drop handler
suggestSort handles single and multi-drag identically — the returned sourceItems already has all selected items repositioned:
makeDroppable(
listRef,
{
events: {
onDrop(e) {
const r = e.helpers.suggestSort('vertical');
if (!r) return;
tasks.value = r.sourceItems as Task[];
},
},
},
() => tasks.value
);e.draggedItems contains one entry per dragged item, sorted by original index. You can read e.draggedItems.length in your overlay to show a count badge when multiple items are dragged.
modifier options
| Field | Type | Description |
|---|---|---|
keys | string[] | Key codes that activate selection (e.g. 'ControlLeft') |
method | 'every' | 'some' | 'every' — all keys pressed; 'some' — at least one |
Default is { keys: ['ControlLeft'], method: 'every' }.
See also
- Drag Handle — restricting drag to a grip element
- Sorting Lists — multi-list transfer with multi-drag
- makeDraggable —
selectedref - makeSelectionArea — full options reference