VayuUI

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

src/components/ui/draggable.tsx
// Copy the full component code

Features

  • 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 announcements
  • DragHandle convenience component with grip icon
  • Vertical and horizontal layouts

DraggableList Props

PropTypeDefaultDescription
itemsT[] (each needs id: string)Items array
onReorder(items: T[]) => voidReorder callback
directionvertical | horizontal | grid"vertical"Layout direction
columnsnumber3Grid columns (grid mode only)
children(item, { dragHandleProps, isDragging, isOver }) => ReactNodeRender function
aria-labelstring"Sortable list"List label

DragHandle Props

PropTypeDescription
handlePropsDragHandlePropsPass through from render function

Keyboard Shortcuts

KeyAction
Space / EnterGrab or drop item
↑ ↓ / ← →Move grabbed item
EscapeCancel reorder

On this page