Sortable

Drag-and-drop reordering with lifting cards, neighbours that make room with springs, and a keyboard mode for everyone else.

Data Display
  • Migrate auth to passkeys
  • Write the onboarding emails
  • Fix flaky checkout test
  • Ship dark mode for the dashboard
  • Review pricing page copy

Playground

Tweak the props, the preview and the code follow.

  • Design
  • Build
  • Test
  • Ship
Props
<Sortable values={items} onValuesChange={setItems}>
  {items.map((item) => (
    <SortableItem key={item} value={item}>
      <SortableHandle />
      {item}
    </SortableItem>
  ))}
</Sortable>

Installation

npx @plumsydev/plum-ui add sortable

Usage

import { Sortable, SortableHandle, SortableItem } from "@/components/ui/sortable"
const [items, setItems] = React.useState(["One", "Two", "Three"])

<Sortable values={items} onValuesChange={setItems}>
  {items.map((item) => (
    <SortableItem key={item} value={item}>
      <SortableHandle />
      {item}
    </SortableItem>
  ))}
</Sortable>

Examples

Horizontal

axis="x" and handle={false} to drag the whole item.

  • Overview
  • Deployments
  • Analytics
  • Logs
  • Settings

Drag the tabs to reorder them.

Ranking

Pair with AnimatedNumber so positions roll as you reorder.

Rank what we build next

Drag, or focus a handle and press Space then ↑ ↓.

  • Offline mode
  • SSO for teams
  • Public API
  • Mobile app
  • Audit logs

API Reference

Sortable

PropTypeDefault
values*

The ordered items.

T[]—
onValuesChange*

Receives the new order.

(values: T[]) => void—
axis

Drag direction.

"x" | "y""y"

SortableItem

PropTypeDefault
value*

The item from `values` (same reference).

T—
handle

Only start dragging from a SortableHandle.

booleantrue

Notes

  • Keyboard: focus a handle, press Space to pick up, arrows to move, Space to drop, Escape to cancel. Moves are announced to screen readers.