A list you reorder by dragging a handle, or entirely from the keyboard, with every move announced.
pnpm dlx shadcn@latest add @latheui/sortable-listPart of Lathe Pro. Set up your project once with your license key: npx latheui init --key <key>. See Lathe Pro.
Sortable List is part of Lathe Pro
The preview is live and free to try. The source, the install and every assembly come with Pro: $79 once, with lifetime updates.
Depends on
Controlled only: it renders the order you give it.
| Prop | Type | Default | Description |
|---|---|---|---|
| items* (required) | T[] | — | Items in their current order. |
| onReorder* (required) | (items: T[]) => void | — | Called with the new order as items move. |
| getId* (required) | (item: T) => string | — | Stable, unique id for an item. |
| getLabel* (required) | (item: T) => string | — | Plain-text name, used for the handle's name and for announcements. |
| renderItem* (required) | (item: T, state: { dragging: boolean }) => ReactNode | — | Row content. dragging is true while the row is lifted. |
| label* (required) | string | — | Accessible name of the list. |
| className | string | — | Classes for the list. |
| itemClassName | string | — | Classes for each row. |
renderItem={(item, { dragging }) => (
<span className={dragging ? "font-medium" : undefined}>{item.title}</span>
)}onReorder fires on every swap while dragging. Debounce it, or save on a separate effect.
React.useEffect(() => {
const timer = setTimeout(() => saveOrder(items.map((item) => item.id)), 600)
return () => clearTimeout(timer)
}, [items])