Draggable
An animated sortable drag-and-drop list with keyboard support, live announcements, and WCAG 2.2 AA compliance.
Usage
List — Drag or keyboard (Space → Arrow ↑↓ → Space)
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
Inbox
12 unread
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
Photos
3,429 items
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
Documents
156 files
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
Music
2,847 tracks
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
Videos
89 clips
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
Archives
24 files
Grid — Drag or keyboard (Space → Arrow ←→↑↓ → Space)
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
12
Inbox
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
3,429
Photos
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
156
Docs
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
2,847
Music
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
89
Videos
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
24
Archives
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
7
Starred
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
31
Favorites
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
5
Quick
Cross-list — Drag items between columns
To Do (3)
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
Write unit tests
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
Review PR #42
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
Update changelog
Done (2)
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
Setup CI pipeline
Press Space to grab, arrow keys to move, Space to drop, Escape to cancel.
Design token audit
import { DraggableList, DragHandle } from "@/components/ui/draggable"
const [items, setItems] = useState([
{ id: "1", label: "First" },
{ id: "2", label: "Second" },
{ id: "3", label: "Third" },
])
<DraggableList items={items} onReorder={setItems} aria-label="My list">
{(item, { dragHandleProps }) => (
<div className="flex items-center gap-2 p-3 border rounded-lg">
<DragHandle handleProps={dragHandleProps} />
<span>{item.label}</span>
</div>
)}
</DraggableList>Installation
// Copy the full component codeFeatures
- Render-prop pattern — full control over item rendering
- Mouse and touch drag with animated visual clone
- CSS transform displacement animations (cubic-bezier spring)
- Keyboard sort: Space to grab, Arrow keys to move, Space to drop, Escape to cancel
- Screen reader:
role="listbox"/role="option"/aria-roledescription="sortable item" aria-live="assertive"live region for position announcementsDragHandleconvenience component with grip icon- Vertical and horizontal layouts
DraggableList Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | T[] (each needs id: string) | — | Items array |
onReorder | (items: T[]) => void | — | Reorder callback |
direction | vertical | horizontal | grid | "vertical" | Layout direction |
columns | number | 3 | Grid columns (grid mode only) |
children | (item, { dragHandleProps, isDragging, isOver }) => ReactNode | — | Render function |
aria-label | string | "Sortable list" | List label |
DragHandle Props
| Prop | Type | Description |
|---|---|---|
handleProps | DragHandleProps | Pass through from render function |
Keyboard Shortcuts
| Key | Action |
|---|---|
Space / Enter | Grab or drop item |
↑ ↓ / ← → | Move grabbed item |
Escape | Cancel reorder |