Build · New
Resizable
Panels people resize by dragging the handle between them: side by side editors, inboxes and dashboards.
Preview
Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.
Installation
SoonInstalling from the registry opens at launch. Until then the command below is what it will be.
npx shadcn@latest add @ritla/resizableDependencies it brings: @phosphor-icons/react
Usage
import { ResizableGroup, ResizableHandle, ResizablePanel } from "@/components/ui/resizable";<ResizableGroup>
<ResizablePanel defaultSize={36} minSize={20}>Sidebar</ResizablePanel>
<ResizableHandle withGrip />
<ResizablePanel minSize={30}>Content</ResizablePanel>
</ResizableGroup>Examples
Vertical
orientation="vertical": top and bottom. ArrowDown makes the top panel taller.
Nested
A vertical group inside a panel. The inner group is bare and its handle has no grip, as in Figma.
Remember sizes
storageKey keeps the sizes in this browser so the layout survives a reload; onLayoutChange hands them to you to save per user on your server.
API reference
ResizableGroup
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal" | Figma's Layout: side by side or top and bottom. Nest a group in a panel for both. |
storageKey | string | Saves the sizes in localStorage under this key. | |
onLayoutChange | (sizes: number[]) => void | The sizes (%, in order) after each resize. | |
bare | boolean | false | No frame, for a group inside a panel. |
ResizablePanel
| Prop | Type | Default | Description |
|---|---|---|---|
defaultSize | number | The starting size (%). Panels without one share the rest. | |
minSize | number | 10 | The smallest size (%), so content never collapses. |
maxSize | number | 100 | The largest size (%). |
ResizableHandle
| Prop | Type | Default | Description |
|---|---|---|---|
withGrip | boolean | false | Figma's Grip: where resizing is the main task. |
label | string | "Resize" / «تغيير الحجم» | The handle's name for screen readers. |
step | number | 5 | The arrow keys' step (%). |
Accessibility
Keyboard
Keys are written for left-to-right. In right-to-left the arrow keys swap: the one pointing toward the reading direction moves forward.
| Key | Action |
|---|---|
| Tab | To the handle. |
| ArrowRightArrowLeft | Moves the handle in steps; in Arabic ArrowLeft widens the first panel. |
| ArrowDownArrowUp | In a vertical group. |
| HomeEnd | To the first panel's smallest and largest size. |
ARIA
- The handle is a focusable
role="separator"witharia-valuenow,aria-valuemin,aria-valuemax(the first panel's size) andaria-controls. - Its 48px drag area covers 24px of each panel, inside their padding.
Arabic and RTL notes
Mirrors
- The first panel sits on the right.
- Dragging and arrow keys follow the reading direction.
Does not mirror
- Vertical groups don't change, and the grip dots don't mirror.
- Numerals
- Sizes you show follow the numerals setting in your UI.
- Arabic typography
- The group sets no type; panels bring their own content.
- Mixed-direction text
- Kanz builds its own splitter because the common alternatives hard-wire ArrowLeft to shrink the first panel, even in Arabic.