Skip to content
Kappa
Drag Selection
@dicehub/kappav0.4.2

Drag Selection

Select several items with a pointer rectangle, a click, or the keyboard.

Drag Selection · asset libraryOpen full example (new tab)
Shared files1 selected
Brand guidelines.pdf
Landing page.png
Project notes.md
Product photos.zip
Release checklist.md
Design tokens.json

Drag across files to select. Hold Ctrl, ⌘, or Shift to add. Press Escape to cancel a drag.

Tab into the list, then use arrow keys and Space.
<script setup lang="ts">
import { ref } from "vue";
import { DragSelection } from "@dicehub/kappa/components/drag-selection";

const selected = ref(["notes"]);
const items = [
  { value: "brand", label: "Brand guidelines.pdf" },
  { value: "landing", label: "Landing page.png" },
  { value: "notes", label: "Project notes.md" },
  { value: "photos", label: "Product photos.zip" },
  { value: "release", label: "Release checklist.md" },
  { value: "tokens", label: "Design tokens.json" },
];
</script>

<template>
  <DragSelection v-model="selected" :items="items" label="Shared files" :columns="3" />
</template>

Installation

import { DragSelection } from "@dicehub/kappa";
// Or: "@dicehub/kappa/components/drag-selection"

Usage

Give each item a unique value and a readable label. Bind the selected identifiers with v-model, or use defaultValue for local state. The item slot changes presentation without changing selection.

A normal drag replaces the selection. Hold Control, Command, or Shift to add to the selection. Escape or a canceled pointer restores the selection from before the drag. Touch devices retain scrolling and tap selection.

Composition

Ark UI Listbox supplies selected state, keyboard navigation, typeahead, and listbox semantics. Its grid collection keeps arrow navigation aligned with the columns prop. Kappa adds rectangle hit testing and vertical edge scrolling.

Keep item content presentational and place actions outside the listbox. This component renders every item; use VirtualTree for very large hierarchies. Rectangle selection only applies to mounted items.

Kappa filters disabled items out of new keyboard selections. This corrects the installed Ark version's select-all behavior, which includes disabled values. A disabled value supplied by the parent remains valid.

Examples

List layout

Use one column for long names. The same selection model works for lists and grids.

Drag Selection · listOpen full example (new tab)
Shared files0 selected
Brand guidelines.pdf
Landing page.png
Project notes.md
Product photos.zip
Release checklist.md
Design tokens.json

Drag across files to select. Hold Ctrl, ⌘, or Shift to add. Press Escape to cancel a drag.

Tab into the list, then use arrow keys and Space.
<DragSelection v-model="selected" :items="items" label="Shared files" :columns="1">
  <template #item="{ item, selected }">
    <span>{{ item.label }}</span>
    <span v-if="selected" aria-hidden="true">✓</span>
  </template>
</DragSelection>

Edge scrolling

Keep the pointer near the top or bottom edge during a drag to select items outside the visible area.

Drag Selection · scrollingOpen full example (new tab)
Asset library0 selected
Asset 01
Asset 02
Asset 03
Asset 04
Asset 05
Asset 06
Asset 07
Asset 08
Asset 09
Asset 10
Asset 11
Asset 12
Asset 13
Asset 14
Asset 15
Asset 16
Asset 17
Asset 18
Asset 19
Asset 20
Asset 21
Asset 22
Asset 23
Asset 24
Asset 25
Asset 26
Asset 27
Asset 28
Asset 29
Asset 30
Asset 31
Asset 32
Asset 33
Asset 34
Asset 35
Asset 36
Asset 37
Asset 38
Asset 39
Asset 40
Asset 41
Asset 42
Asset 43
Asset 44
Asset 45
Asset 46
Asset 47
Asset 48
Asset 49
Asset 50
Asset 51
Asset 52
Asset 53
Asset 54
Asset 55
Asset 56
Asset 57
Asset 58
Asset 59
Asset 60
Asset 61
Asset 62
Asset 63
Asset 64
Asset 65
Asset 66
Asset 67
Asset 68
Asset 69
Asset 70
Asset 71
Asset 72

Drag across files to select. Hold Ctrl, ⌘, or Shift to add. Press Escape to cancel a drag.

Tab into the list, then use arrow keys and Space.
<DragSelection
  v-model="selected"
  :items="assets"
  label="Asset library"
  :columns="3"
  style="--kappa-drag-selection-max-height: 18rem"
/>

Disabled items and collection

A disabled item is excluded from pointer and keyboard selection. Disable the entire collection to lock selection.

Drag Selection · disabledOpen full example (new tab)
Shared files0 selected
Brand guidelines.pdf
Landing page.png
Project notes.md
Product photos.zip
Release checklist.md
Design tokens.json

Drag across files to select. Hold Ctrl, ⌘, or Shift to add. Press Escape to cancel a drag.

Landing page.png is unavailable.
<script setup lang="ts">
const items = [
  { value: "notes", label: "Project notes.md" },
  { value: "landing", label: "Landing page.png", disabled: true },
];
</script>

<template>
  <DragSelection :items="items" label="Shared files" :disabled="locked" />
</template>

Click and keyboard only

Turn off rectangle gestures without removing the accessible selection behavior.

Drag Selection · click-onlyOpen full example (new tab)
Shared files0 selected
Brand guidelines.pdf
Landing page.png
Project notes.md
Product photos.zip
Release checklist.md
Design tokens.json

Click a file. Use Ctrl or ⌘ to add more, or Shift to select a range.

Tab into the list, then use arrow keys and Space.
<DragSelection v-model="selected" :items="items" label="Shared files" drag-disabled />

Accessibility

The required label names the multi-select listbox. Tab enters the list, arrow keys move focus, and Space selects. Shift extends a range; Control/Command+A selects enabled items. Visible focus, disabled states, and forced colors are supported. No animation is used.

API Reference

DragSelection accepts items: DragSelectionItem[], label: string, modelValue?: string[], defaultValue?: string[], columns?: number (3), disabled?: boolean, dragDisabled?: boolean, autoScroll?: boolean (true), threshold?: number (6 pixels), and emptyLabel?: string (“No items”). Native attributes reach the root.

An item has value: string, label: string, and optional disabled: boolean. The item slot receives { item, selected }. The empty slot replaces the empty message.

Events: update:modelValue emits the selected identifiers; valueChange emits { value }; dragStart starts a rectangle gesture; dragEnd emits { value, canceled }. Canceled gestures restore their initial selection.

Set --kappa-drag-selection-max-height to change the scroll height (22rem). Use columns for responsive layout changes so the keyboard grid changes with the visual grid.