Installation
Theme
Mode

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-panel

Overview

Drag the divider to rebalance the panes, double-click it to reset, and pick a row on the left to update the detail.

Tasks
Ship onboarding flow v2In progress
AssigneeSam Chen
StatusIn progress
PriorityHigh
Due dateJun 30
Rework the first-run experience so a new workspace reaches its first created task in under two minutes.

Orientation

Split side-by-side for list/detail, or stacked for a preview-above-content layout. Each is independently draggable.

Vertical — orientation=vertical · defaultSize={45}
Tasks
Ship onboarding flow v2In progress
AssigneeSam Chen
StatusIn progress
PriorityHigh
Due dateJun 30
Rework the first-run experience so a new workspace reaches its first created task in under two minutes.

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.

size = 30% · min 20 · max 70
First pane
Second pane

Props

PropTypeDefaultDescription
orientation"horizontal" | "vertical""horizontal"Side-by-side panes, or stacked with a horizontal gutter.
sizenumberControlled first-pane size as a percentage of the container. Pair with onSizeChange.
defaultSizenumber38Initial first-pane percentage when uncontrolled — also the double-click reset target.
minSizenumber18Smallest the first pane can get (percent). Clamps drags, keys, and resets.
maxSizenumber82Largest the first pane can get (percent).
onSizeChange(size: number) => voidCalled with the clamped percentage on every drag move, key press, or reset.
keyboardStepnumber2Percent moved per arrow-key press on the focused divider.
dividerLabelstring"Resize panes"Accessible name announced for the separator.
firstPaneClassNamestringExtra classes for the first scrollable pane wrapper (padding, background…).
secondPaneClassNamestringExtra classes for the second scrollable pane wrapper.
children[ReactNode, ReactNode]Exactly two children — the first and second pane content.
…restHTMLAttributes<div>Everything else is forwarded to the root element, including ref.

Usage

Do

Set sensible min sizes

Clamp both panes so a drag can’t collapse content into an unusable sliver. The defaults hold 18–82%.

Don’t

Nest splitters deeply

One split is legible; three nested ones are a puzzle. Past two panes, reach for a different layout.

Do

Make the handle findable

The gutter highlights on hover with a resize cursor and a brand-tinted grip — discoverable but quiet at rest.

Don’t

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.

TabMoves focus to the divider
← → / ↑ ↓Resizes by keyboardStep (per orientation)
Home / EndJumps to minSize / maxSize
Double-clickResets the split to defaultSize