Sortable List
A generic, accessible drag-to-reorder vertical list. Rows are moved via a grip handle using native HTML5 drag-and-drop or the keyboard (↑/↓, Home/End), firing onReorder with the updated items array.
Basic reorder
Pass items, getKey, and renderItem. Drag the grip handle (three horizontal lines) to reorder rows.
Drag rows by their grip handle to reorder.
With custom row content
renderItem receives the item and a meta object. Compose any content — badges, actions, truncated text — inside the row.
Custom row content — each row shows the field type badge and required flag.
Keyboard reorder
Focus a grip handle and press ↑/↓ to move an item one position, or Home/End to jump it to the top or bottom. Navigation clamps at the ends and never wraps.
Focus a grip handle and use ↑ / ↓ to reorder, Home / End to jump to the first or last position.
Installation
pnpm add @refraction-ui/reactUsage
import { SortableList } from '@refraction-ui/react'
const [items, setItems] = React.useState([
{ id: '1', label: 'Phone Screen' },
{ id: '2', label: 'Technical Interview' },
{ id: '3', label: 'Final Interview' },
])
return (
<SortableList
items={items}
getKey={(item) => item.id}
onReorder={setItems}
renderItem={(item) => <span>{item.label}</span>}
/>
)Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | T[] | -- | The ordered array of items to render. |
getKey | (item: T, index: number) => string | number | -- | Return a stable key for each item (used as the React key). |
renderItem | (item: T, meta: { index: number; dragHandleProps: DragHandleProps }) => ReactNode | -- | Render the row content. Spread `dragHandleProps` onto your custom grip element if you choose to render your own. |
onReorder | (items: T[]) => void | -- | Called with the new items array after a drag or keyboard reorder. |
disabled | boolean | false | Disables all drag and keyboard reordering. |
className | string | -- | Additional CSS classes for the list container. |