---
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
---
<ResizablePanelGroup class="h-48 max-w-2xl rounded-lg border">
<ResizablePanel
defaultSize={35}
minSize={20}
class="flex items-center justify-center p-6"
>
Sidebar
</ResizablePanel>
<ResizableHandle withHandle aria-label="Resize sidebar and content" />
<ResizablePanel
defaultSize={65}
minSize={30}
class="flex items-center justify-center p-6"
>
Content
</ResizablePanel>
</ResizablePanelGroup>Installation
npx shadcn@latest add @fulldev/resizable
Usage
---
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
---
<ResizablePanelGroup class="h-48">
<ResizablePanel defaultSize={40}>Sidebar</ResizablePanel>
<ResizableHandle aria-label="Resize panels" />
<ResizablePanel defaultSize={60}>Content</ResizablePanel>
</ResizablePanelGroup>
A group needs one handle between each pair of panels. Give every handle an accessible label. Drag a handle with a pointer, or focus it and use the arrow keys.
Examples
Vertical
Use direction="vertical" for rows. The handle responds to the up and down arrow keys.
---
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
---
<ResizablePanelGroup
direction="vertical"
class="h-72 max-w-2xl rounded-lg border"
>
<ResizablePanel
defaultSize={35}
minSize={20}
class="flex items-center justify-center p-4"
>
Header
</ResizablePanel>
<ResizableHandle withHandle aria-label="Resize header and body" />
<ResizablePanel
defaultSize={65}
minSize={30}
class="flex items-center justify-center p-4"
>
Body
</ResizablePanel>
</ResizablePanelGroup>Collapsible
Focus the handle and press Enter to collapse or restore the first panel. Dragging through the minimum size also collapses it.
---
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
---
<ResizablePanelGroup class="h-48 max-w-2xl rounded-lg border">
<ResizablePanel
defaultSize={30}
minSize={20}
collapsible
collapsedSize={0}
class="flex items-center justify-center p-4"
>
Collapsible sidebar
</ResizablePanel>
<ResizableHandle withHandle aria-label="Resize or collapse sidebar" />
<ResizablePanel
defaultSize={70}
minSize={30}
class="flex items-center justify-center p-4"
>
Main content
</ResizablePanel>
</ResizablePanelGroup>Nested
Each group owns only its direct panels and handles, so a panel can safely contain another resizable group.
---
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
---
<ResizablePanelGroup class="h-72 max-w-2xl rounded-lg border">
<ResizablePanel
defaultSize={35}
minSize={20}
class="flex items-center justify-center p-4"
>
Navigation
</ResizablePanel>
<ResizableHandle aria-label="Resize navigation and workspace" />
<ResizablePanel defaultSize={65} minSize={30}>
<ResizablePanelGroup direction="vertical" class="h-full">
<ResizablePanel
defaultSize={60}
minSize={25}
class="flex items-center justify-center p-4"
>
Editor
</ResizablePanel>
<ResizableHandle withHandle aria-label="Resize editor and console" />
<ResizablePanel
defaultSize={40}
minSize={20}
class="flex items-center justify-center p-4"
>
Console
</ResizablePanel>
</ResizablePanelGroup>
</ResizablePanel>
</ResizablePanelGroup>Keyboard Controls
| Key | Action |
|---|---|
| Arrow keys | Resize by keyboardResizeBy in the group direction. |
Shift + arrow | Resize to the available limit. |
Home / End | Minimize or maximize the panel before the handle. |
Enter | Collapse or restore the collapsible panel before the handle. |
F6 / Shift + F6 | Focus the next or previous handle in the group. |
API Reference
ResizablePanelGroup
Resizable is an alias for ResizablePanelGroup.
| Prop | Type | Default | Description |
|---|---|---|---|
direction | "horizontal" | "vertical" | "horizontal" | Sets the layout and resize axis. |
keyboardResizeBy | number | 10 | Percentage moved by an arrow keypress. |
ResizablePanel
All sizes are percentages between 0 and 100.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultSize | number | even split | Initial panel size. |
minSize | number | 0 | Minimum expanded size. |
maxSize | number | 100 | Maximum size. |
collapsible | boolean | false | Allows the panel to use its collapsed size. |
collapsedSize | number | 0 | Size used while collapsed. |
ResizableHandle
| Prop | Type | Default | Description |
|---|---|---|---|
withHandle | boolean | false | Shows a visible grip on the separator. |
disabled | boolean | false | Blocks keyboard resizing on this handle. |
The root emits resizable:change with { layout: number[] } and resizable:dragging with { dragging: boolean }. Dispatch resizable:set with { layout: number[] } to set a layout from client code.
See the GitHub source code for the component source. See the data-slot docs for constraints, controller methods, and event details.