Sortable list
Reorders items with drag handles, move buttons, and keyboard shortcuts.
Preview
Use move buttons, or focus an item handle and press Alt with Arrow up or Arrow down.
- Research
- Design
- Build
In action
- Research
- Design
- Build
When to use
Use it for
- Ordering tasks, workflow steps, and priority lists.
Not for
- Cross-column status changes alone; use KanbanBoard.
Install
Three ways in. They share one source, so the pixels match whichever you pick.
1. Import the package
npm install @noorddev/vlak-react
// once, next to your app's root
import "@noorddev/vlak-react/css";
import { SortableList } from "@noorddev/vlak-react";Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/sortable-list.
2. Vendor the source
npx @noorddev/vlak-cli add sortable-list
The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.
3. Through shadcn
npx shadcn add https://vlak.dev/r/sortable-list.json
The same registry item, installed by shadcn's CLI.
CSS only
<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />
No React. Link vlak.css and use the markup and classes below.
React
import { SortableList } from "@noorddev/vlak-react";
<SortableList defaultValue={[{ id: "research", label: "Research" }, { id: "design", label: "Design" }, { id: "build", label: "Build" }]} />Props
SortableList
Reordering through drag, named move buttons, or Alt and the arrow keys.
| Prop | Type | Default | Description |
|---|---|---|---|
value | SortableItem[] | ||
defaultValue | SortableItem[] | [] | |
onValueChange | (items: SortableItem[]) => void | ||
label | string | "Reorder items" |
Also accepts Omit<HTMLAttributes<HTMLOListElement>, "defaultValue">.
Keyboard
| Keys | Does |
|---|---|
| Tab, Enter, Space, Alt+Arrow up/down | Move buttons work with Enter/Space; Alt with Up/Down on a handle changes its position. |
Accessibility
- Each move action names the item; position changes are announced and focus stays with the moved item.
Markup
<ol class="rs-sortable-list" aria-label="Reorder items"><li class="rs-sortable-list-item"><div class="rs-sortable-list-content">Research</div><div class="rs-sortable-list-actions"><button class="rs-btn-ghost" aria-label="Move Research down">Move down</button></div></li></ol>
Classes
.rs-sortable-list.rs-sortable-list-item.rs-sortable-list-content.rs-sortable-list-actions.rs-sortable-list-status