v0.3.0
Note: This documentation is in active development — content may be incomplete

Sortable

View as Markdown

Overview

Sortable is a layout component that enables drag-and-drop reordering of items. It supports items arranged as vertical lists, horizontal rows, or grids.

A
B
C
const [items, setItems] = useState([
	{ id: 1, label: "A" },
	{ id: 2, label: "B" },
	{ id: 3, label: "C" },
]);

<Sortable.Root items={items} onItemsChange={setItems}>
	{items.map((item) => (
		<Sortable.Item key={item.id} id={item.id}>
			<div>{item.label}</div>
		</Sortable.Item>
	))}
</Sortable.Root>

Usage Guidelines

  • Use sorting for meaningful order: Use a sortable layout when item order should be user-defined and affects priority, sequence, or organization.
  • Use drag handles when needed: Use Sortable.Handle when items contain other interactive controls or when a smaller drag target provides a clearer affordance.
  • Keep items easy to identify: Make sortable items distinct and scannable so users can track what they are moving.

API Reference

Sortable.Root

Provides drag-and-drop context and ordering logic for sortable items.

PropTypeDefault
itemsArray<{ id: string | number }>-
onItemsChange(items: Array<{ id: string | number }>) => void-
childrenReactNode-
orientation"vertical" | "horizontal" | "free""vertical"
constrainToParentbooleantrue

Sortable.Item

Registers an item in the sortable context and applies drag state.

PropTypeDefault
idstring | number-
childrenReactNode-
classNamestring-
styleCSSProperties-
renderRenderProp<{ dragging: boolean }>-

Sortable.Handle

Optional drag handle that limits dragging to a specific child element.

PropTypeDefault
childrenReactNode-
classNamestring-
renderRenderProp-

Examples

Orientation

The orientation property controls how items can be sorted. Sortable supports sorting in a vertical column, a horizontal row, or even across a grid.

A
B
C
E
F
G
H
I
J
const [items, setItems] = useState([
	{ id: 1, label: "A" },
	{ id: 2, label: "B" },
	{ id: 3, label: "C" },
]);

<Sortable.Root orientation="horizontal" items={items} onItemsChange={setItems}>
	<Stack orientation="horizontal" gap={4}>
		{items.map((item) => (
			<Sortable.Item key={item.id} id={item.id}>
				<Box label={item.label} height="160px" width="80px" />
			</Sortable.Item>
		))}
	</Stack>
</Sortable.Root>

Drag handles

By default, the entire Sortable.Item is draggable. Use Sortable.Handle to only allow certain parts of a sortable item to be dragged.

A
B
C
const [items, setItems] = useState([
	{ id: 1, label: "A" },
	{ id: 2, label: "B" },
	{ id: 3, label: "C" },
]);

<Sortable.Root items={items} onItemsChange={setItems}>
	{items.map((item) => (
		<Sortable.Item key={item.id} id={item.id}>
			<Sortable.Handle />
			<div>{item.label}</div>
		</Sortable.Item>
	))}
</Sortable.Root>

Constraints

Items can be dragged beyond the parent's boundary by disabling the constrainToParent property.

A
B
C
const [items, setItems] = useState([
	{ id: 1, label: "A" },
	{ id: 2, label: "B" },
	{ id: 3, label: "C" },
]);

<Sortable.Root constrainToParent={false} items={items} onItemsChange={setItems}>
	{items.map((item) => (
		<Sortable.Item key={item.id} id={item.id}>
			<div>{item.label}</div>
		</Sortable.Item>
	))}
</Sortable.Root>

On this page

(Top)OverviewUsage GuidelinesAPI ReferenceSortable.RootSortable.ItemSortable.HandleExamplesOrientationDrag handlesConstraints
v0.3.0

Overview

AboutGetting started

Components

AvatarBadgeBannerButtonCalloutCheckboxChipCodeCode InputColor InputData TableDialogDividerDisclosureDrawerEditable TextEmbedEmphasisError BoundaryFieldFile InputFlexFormFrameGridImageInlineInputMarqueeMenuPortalRootRadio GroupRich Text EditorSelectSkeletonSlotSortableSpacerSpinnerStackStatus IconStepperSwitchTab SwitchTextText AreaToggleUrlIcon