Resizable Panels
Drag-to-resize panel layout. Horizontal or vertical, with per-panel min/max size constraints. Panels can be nested for split-view editors.
Features
minSize / maxSize constraints (in percent).defaultSize.Example
Sidebar
Files
Search
Anatomy
import { ResizablePanels } from '@wire-ui/react'
<ResizablePanels.Group orientation="horizontal">
<ResizablePanels.Panel defaultSize={50}>Left</ResizablePanels.Panel>
<ResizablePanels.Handle />
<ResizablePanels.Panel defaultSize={50}>Right</ResizablePanels.Panel>
</ResizablePanels.Group>Styling
Group sets data-orientation ("horizontal" / "vertical"). Panel and Handle inherit the same attribute so you can flip width/height styles without prop drilling.
<ResizablePanels.Handle className="
data-[orientation=horizontal]:w-px data-[orientation=horizontal]:cursor-col-resize
data-[orientation=vertical]:h-px data-[orientation=vertical]:cursor-row-resize
bg-black
" />Handles already set cursor and touch-action: none inline; the className is for visual styling on top of that.
Using data attributes
[data-orientation="horizontal"] [data-handle] { width: 1px; cursor: col-resize; }
[data-orientation="vertical"] [data-handle] { height: 1px; cursor: row-resize; }
[data-handle][data-disabled] { pointer-events: none; opacity: 0.5; }Group props
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'horizontal' | 'vertical' | 'horizontal' | Layout direction |
sizes | number[] | — | Controlled sizes (percentages, summing to ~100) |
defaultSizes | number[] | — | Initial sizes (uncontrolled) |
onSizesChange | (sizes: number[]) => void | — | Called whenever sizes change |
Panel props
| Prop | Type | Default | Description |
|---|---|---|---|
defaultSize | number | distributed | Default size in percent of the group |
minSize | number | 0 | Minimum size in percent |
maxSize | number | 100 | Maximum size in percent |
If only some panels declare defaultSize, the remaining space is split evenly between the rest.
Handle props
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean | false | Disable dragging on this handle |
aria-label | string | 'Resize handle' | Accessible label |
Data attributes
| Attribute | Element | Values |
|---|---|---|
data-orientation | Group, Panel, Handle | "horizontal" / "vertical" |
data-panel | Panel | Present (empty) on every panel |
data-handle | Handle | Present (empty) on every handle |
data-disabled | Handle | Present when disabled |
Handle renders with role="separator" and aria-orientation set perpendicular to the Group (a vertical line separating horizontal panels reports aria-orientation="vertical").
Accessibility
- Handles are focusable (
tabIndex=0) and userole="separator"with the correctaria-orientation. - Dragging uses pointer events with pointer capture, so moving the cursor outside the handle keeps dragging smoothly.
touch-action: noneis set on handles so touch dragging doesn’t scroll the page.
Keyboard Interactions
| Key | Description |
|---|---|
| Tab | Moves focus to the next handle. |
Keyboard-driven resizing is not currently implemented — users resize via pointer drag.