Drag to reorder
Also called sortable list or reorderable list
A list you can rearrange by dragging an item to a new spot while the other items slide aside to make room.
import { useState } from 'react';
import { Reorder } from 'motion/react';
// How quickly the other rows slide aside to make room.
const SLIDE = { type: 'spring', stiffness: 500, damping: 40 } as const;
const LIFTED = { scale: 1.04, boxShadow: '0 12px 24px -8px rgb(0 0 0 / 0.25)' };
type TaskListProps = { initial: string[]; onSave: (tasks: string[]) => void };
export function TaskList({ initial, onSave }: TaskListProps) {
const [tasks, setTasks] = useState(initial);
// Move up and Move down: the keyboard and screen reader alternative.
function move(task: string, offset: -1 | 1) {
const next = tasks.filter((t) => t !== task);
next.splice(tasks.indexOf(task) + offset, 0, task);
setTasks(next);
onSave(next);
}
return (
<Reorder.Group
axis='y'
values={tasks}
onReorder={setTasks}
className='flex w-80 flex-col gap-2'
>
{tasks.map((task, index) => (
<Reorder.Item
key={task}
value={task}
transition={SLIDE}
whileDrag={LIFTED}
onDragEnd={() => onSave(tasks)} // save as soon as the row drops
className='flex cursor-grab items-center gap-2 rounded-xl border bg-background px-3 py-2.5 text-sm active:cursor-grabbing'
>
<span className='flex-1'>{task}</span>
{([-1, 1] as const).map((offset) => (
<button
key={offset}
type='button'
disabled={!tasks[index + offset]}
onClick={() => move(task, offset)}
aria-label={`Move ${task} ${offset < 0 ? 'up' : 'down'}`}
className='rounded px-1.5 text-muted-foreground hover:bg-muted disabled:opacity-30'
>
{offset < 0 ? '↑' : '↓'}
</button>
))}
</Reorder.Item>
))}
</Reorder.Group>
);
}Make the task list reorderable by dragging, using Motion's Reorder.Group and Reorder.Item: lift the dragged row with scale 1.04 and a larger shadow, let the other rows slide aside with a spring (stiffness 500, damping 40), and save the new order on drop. Add "Move up" and "Move down" menu items for keyboard users, and set touch-action: none on the drag handle.
Paste into Layerwise or any AI coding tool.
What is Drag to reorder?
In a drag-to-reorder list, you grab a row, often by a grip handle, and move it up or down. The row lifts with a slight scale and shadow and follows the pointer, and its neighbors slide out of the way as it passes them. Releasing drops it into the open slot.
The sliding neighbors are what make it feel solid: they show where the item will land before you let go. Animate them with a layout animation, such as Motion's Reorder components, instead of snapping items between positions.
Use it for to-do lists, playlists, menus, and kanban columns. Dragging is hard for keyboard and screen reader users, so pair it with "Move up" and "Move down" actions, and save the new order as soon as the item drops.
Often confused with
- Drag and drop
- Drag and drop moves items between places, like into a folder or another column. Drag to reorder changes the order within one list.
Related terms
All termsLayout animation
An animation that smoothly moves and resizes elements when the layout changes, such as list items gliding to new spots after a sort or filter.
Drag gesture
Moving an element by pressing on it and sliding the pointer or finger, usually within set bounds and with a glide after release.
Spring animation
An animation driven by simulated spring physics in place of a fixed duration and curve, so motion can overshoot, settle, and react naturally.
Interruptible animation
An animation that can change course mid-flight, continuing smoothly from its current position and speed when someone acts again before it ends.
Build it with Layerwise
Describe your app, watch it run in a live preview, and publish it with a database, storage, and sign-in built in.