v0.1

Sortable

An interaction wrapper for drag-and-drop reordering

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>

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. We can 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}>
			<div>{item.label}</div>
		</Sortable.Item>
	))}
</Sortable.Root>

Constraints

You can easily change dragging behavior via the constraints property.

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>
v0.1

Overview

AboutGetting started

Components

AvatarBadgeBannerButtonCalloutCheckboxCodeCode InputColor InputData TableDialogDividerDisclosureDrawerEditable TextEmbedEmphasisError BoundaryFieldFile InputFlexFormFrameGridImageInlineInputMarqueeMenuMeta PixelPortalRootRadio GroupRich Text EditorSelectSkeletonSlotSortableSpacerSpinnerStackStatus IconStepperSwitchTab SwitchTextText AreaToastToggleUrlIcon