Layout & containers
Split panel
Two panes and a draggable divider — the master/detail layout behind most list-plus-preview views. Drag the gutter to rebalance, double-click to reset, resize from the keyboard, and split horizontally or vertically.
npx shadcn@latest add @orbit/split-panelOverview
Drag the divider to rebalance the panes, double-click it to reset, and pick a row on the left to update the detail.
Orientation
Split side-by-side for list/detail, or stacked for a preview-above-content layout. Each is independently draggable.
Controlled size & constraints
Pass size + onSizeChange to own the split in state. minSize/maxSize clamp every drag, key press, and reset — the divider reports them as aria-valuemin/max.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| orientation | "horizontal" | "vertical" | "horizontal" | Side-by-side panes, or stacked with a horizontal gutter. |
| size | number | — | Controlled first-pane size as a percentage of the container. Pair with onSizeChange. |
| defaultSize | number | 38 | Initial first-pane percentage when uncontrolled — also the double-click reset target. |
| minSize | number | 18 | Smallest the first pane can get (percent). Clamps drags, keys, and resets. |
| maxSize | number | 82 | Largest the first pane can get (percent). |
| onSizeChange | (size: number) => void | — | Called with the clamped percentage on every drag move, key press, or reset. |
| keyboardStep | number | 2 | Percent moved per arrow-key press on the focused divider. |
| dividerLabel | string | "Resize panes" | Accessible name announced for the separator. |
| firstPaneClassName | string | — | Extra classes for the first scrollable pane wrapper (padding, background…). |
| secondPaneClassName | string | — | Extra classes for the second scrollable pane wrapper. |
| children | [ReactNode, ReactNode] | — | Exactly two children — the first and second pane content. |
| …rest | HTMLAttributes<div> | — | Everything else is forwarded to the root element, including ref. |
Usage
Set sensible min sizes
Clamp both panes so a drag can’t collapse content into an unusable sliver. The defaults hold 18–82%.
Nest splitters deeply
One split is legible; three nested ones are a puzzle. Past two panes, reach for a different layout.
Make the handle findable
The gutter highlights on hover with a resize cursor and a brand-tinted grip — discoverable but quiet at rest.
Forget a reset
Let people recover the default balance — a double-click on the divider snaps it back to defaultSize.
Keyboard & accessibility
The divider is a real focusable element with role=separator, an accessible name, and aria-valuenow/min/max reflecting the current split. Use a Drawer instead when the detail should overlay rather than coexist.