Sortable List React component
A list people can put in their own order: drag a row by its handle and the others slide out of the way, or use the keyboard (Space to lift, arrows to move, Space to drop, Escape to undo), with live position numbers and optional remove buttons.
About the Sortable List component
Sortable List is a list of rows people reorder by dragging a handle. The row being moved lifts slightly and the others slide out of its way, numbers in front of the rows update as they move, and an optional remove button lets rows collapse away. It works with the keyboard and screen readers too: each move is announced.
items takes objects with id, title and an optional meta text on the right, like a time or a count. Pass items alone and the list keeps its own order, or pass value with onValueChange to control it. showNumbers shows the 1, 2, 3 in front of each row, removable adds the remove buttons and label names the list for assistive tech.
When to use it
Use Sortable List wherever order is the user's decision: agendas, playlists, priorities, menu items, form fields, steps in a flow. Dragging from the handle keeps the rest of the row free for scrolling on touch screens.
Save the new order from onValueChange; the component only reorders what you give it.
Installation
Add the Sortable List component to your project with the shadcn CLI. It lands in components/sortable-list.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add @reactframe/sortable-listOr copy the source by hand and install its dependencies:
npm install motion clsx tailwind-mergeProps
<SortableList /> accepts 8 props, all optional.
| Prop | Type | Default |
|---|---|---|
| items | { id: string; title: string; meta?: string }[] | DEFAULT_ITEMS |
| value Controlled order. | { id: string; title: string; meta?: string }[] | — |
| onValueChange | (items: SortableItem[]) => void | — |
| showNumbers Show 1, 2, 3 ... in front of each row (they update as rows move). | boolean | true |
| removable A remove button on each row. | boolean | false |
| label | string | "Agenda" |
| theme | "dark" | "light" | "dark" |
| className | string | — |
- items{ id: string; title: string; meta?: string }[]Default: DEFAULT_ITEMS
- value
Controlled order.
{ id: string; title: string; meta?: string }[] - onValueChange(items: SortableItem[]) => void
- showNumbers
Show 1, 2, 3 ... in front of each row (they update as rows move).
booleanDefault: true - removable
A remove button on each row.
booleanDefault: false - labelstringDefault: "Agenda"
- theme"dark" | "light"Default: "dark"
- classNamestring
npm dependencies
Installed for you by the shadcn CLI.
Sortable List FAQ
- Can it be sorted without a mouse?
- Yes. Tab to a row's handle, press Space to lift it, move it with the up and down arrows, and press Space to drop or Escape to put it back. Each step is announced to screen readers.
- Why drag from a handle?
- So the rest of the row can still be scrolled, selected or clicked, which matters most on phones.
- Can people remove rows?
- Set removable to add a × button on each row; the row collapses away and onValueChange receives the shorter list.
- What is the difference between items and value?
- items is only the starting order; after that the list keeps its own. value is the controlled order: the list shows exactly that array, and you update it from onValueChange.