Panels whose sizes you change by dragging the handle between them, or with the keyboard.
$ pnpm dlx shadcn@latest add https://dashral.com/r/resizable.jsonInstallation
$ pnpm dlx shadcn@latest add https://dashral.com/r/resizable.jsonAdds the component, the components it builds on, its npm packages and the theme tokens it uses. Using Dashral often? Add the registry to components.json once:
{
"registries": {
"@dashral": "https://dashral.com/r/{name}.json"
}
}Then add components by name:
$ pnpm dlx shadcn@latest add @dashral/resizableUsage
import { Resizable } from "@/components/dashral/resizable"
<Resizable
withHandle
panels={[
{ content: <Sidebar />, defaultSize: 30, minSize: 20 },
{ content: <Editor />, minSize: 40 },
]}
className="h-96 rounded-lg border"
/>Examples
Nested
A vertical Resizable inside a panel of a horizontal one, like a mail app.
API reference
Resizable
Also takes every prop of <div>(opens in a new tab).
| Prop | Type | Default |
|---|---|---|
panels | { content, defaultSize?, minSize?, maxSize?, className? }[]In order, a handle between each two. Sizes in percent. Required. | — |
direction | "horizontal" | "vertical"Side by side, or stacked; put a Resizable in a panel to split it the other way. | "horizontal" |
withHandle | booleanA grip on each handle. | false |
onLayout | (sizes: number[]) => voidEvery panel's size (percent) when a resize ends — store it to restore the layout. | — |
classNames | { panel, handle }Classes for each part. | — |
className | stringExtra classes, merged with cn() so yours win. | — |
Keyboard
| Keys | Action |
|---|---|
| ←or→ | Move the boundary 2% (↑ / ↓ in a vertical group) |
| Shift+arrow keys | Move it 10% |
| HomeorEnd | The panel's smallest / largest size |
Accessibility
- Handles are focusable role="separator" with aria-valuenow (the panel before it, in percent), min, max and aria-controls — the WAI-ARIA window splitter pattern.