Drag Reorder List
A list reordered by press-and-drag, where the other items flow aside to make way, with a drag handle.
Grab the handle on the left to lift an item: it floats up and scales, tilts slightly with a shadow, the other items flow aside on a spring to make way, and it springs back into place on release. Pure-keyboard reordering is also supported (Space to grab plus arrow keys to move), with live announcements of the position through aria-live.
Loading preview…
npx shadcn@latest add https://webberui.com/r/drag-reorder-list.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<DragReorderList />
Installation
npx shadcn@latest add https://webberui.com/r/drag-reorder-list.jsonOr, once registries are configured in components.json, install it as @webberui/drag-reorder-list.
Usage
import { DragReorderList } from "@/components/ui/drag-reorder-list";
const items = [
{ id: "changelog", icon: "📝", label: "Write the changelog" },
{ id: "deploy", icon: "🚀", label: "Deploy to production" },
{ id: "newsletter", icon: "✉️", label: "Send the newsletter" },
];
<DragReorderList items={items} onReorder={(next) => console.log(next)} />Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | DragReorderItem[] | — | The list items; the internal order syncs whenever the id sequence changes (controlled update or new data) |
onReorder | (items: DragReorderItem[]) => void | — | Callback fired when the order changes; drag swaps, keyboard moves, and Esc restore all deliver the latest array |
showIndex | boolean | true | Whether to show the position number badge, which pops as it updates on a swap |
className | string | — | Forwarded to the outermost container |
DragReorderItem fields:
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier, used as the key and for order tracking |
label | string | Main title text |
description | string (optional) | Secondary explanatory text |
icon | React.ReactNode (optional) | Decoration on the left, an emoji string or any node |
Accessibility
- The handle is a native
button: focus it and press Space or Enter to grab, up/down arrow keys to move, Space again to drop, Esc to cancel and restore the original order - Grabbing, moving, dropping, and hitting the top/bottom boundary are all announced live through an
aria-liveregion (for example "moved to position 2 of 5") - The handle carries a full
aria-label(item name and current position) plusaria-pressedfor the grabbed state; the number badge and emoji are hidden from assistive technology - When "reduce motion" is enabled at the system level, the make-way and spring-back animations complete instantly
- Dragging is triggered only from the handle (
touch-action: noneapplies to the handle alone), so the rest of the list still scrolls normally on touch devices