Component

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.

Phone Screen
Technical Interview
Take-home Assignment
Final Interview

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.

textFull namerequired
emailWork emailrequired
selectDepartment
textareaNotes

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.

Round 1 — Recruiter
Round 2 — Engineering
Round 3 — System Design

Focus a grip handle and use / to reorder, Home / End to jump to the first or last position.

Installation

$pnpm add @refraction-ui/react

Usage

tsx
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

PropTypeDefaultDescription
itemsT[]--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.
disabledbooleanfalseDisables all drag and keyboard reordering.
classNamestring--Additional CSS classes for the list container.