resizable
Accessible resizable panel groups and layouts with keyboard support.
Philosophy
Resizable panels let users allocate screen real estate to match their workflow. We wrap react-resizable-panels because the math of proportional resizing, minimum sizes, and persistent layouts is deceptively complex. The PanelGroup/Panel/Handle model keeps the API simple while supporting arbitrarily complex layouts.
About
The Resizable component is built on top of
react-resizable-panels by bvaughn.
How It's Built
Installation
npx @gentleduck/cli add resizable
npx @gentleduck/cli add resizable
Usage
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
<ResizablePanelGroup orientation="horizontal">
<ResizablePanel>One</ResizablePanel>
<ResizableHandle />
<ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>
Examples
Vertical
Use the orientation prop to set the direction of the resizable panels.
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
export default function Example() {
return (
<ResizablePanelGroup orientation="vertical">
<ResizablePanel>One</ResizablePanel>
<ResizableHandle />
<ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>
)
}
Handle
The grip handle shows by default. Pass withHandle={false} to render only the thin line without the visible grip.
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
export default function Example() {
return (
<ResizablePanelGroup orientation="horizontal">
<ResizablePanel>One</ResizablePanel>
<ResizableHandle />
<ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>
)
}
Component Composition
RTL Support
Set the direction once with DirectionProvider (or <html dir="rtl">) and the panel group follows it: panels mirror, and dragging and arrow keys follow the visual layout. No dir prop or rtl: classes needed.
Motion
Use MotionResizablePanelGroup for a smooth entrance animation powered by motion. The panel group uses a scaleIn entrance (fade, scale, and blur) with a springBouncy transition on mount.
motion package. Use MotionResizablePanelGroup instead of ResizablePanelGroup. The rest of the components (ResizablePanel, ResizableHandle) stay the same. The regular ResizablePanelGroup is perfectly fine - this is an optional enhancement.API Reference
ResizablePanelGroup
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | "horizontal" | "vertical" | (required) | Layout orientation of the panels |
className | string | -- | Additional CSS classes for the panel group |
dir | "ltr" | "rtl" | -- | Text direction override for RTL support |
children | React.ReactNode | -- | ResizablePanel and ResizableHandle elements |
...props | React.ComponentPropsWithoutRef<typeof Group> | - | Additional props inherited from Group. |
ResizablePanel
Re-exports Panel from react-resizable-panels directly.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultSize | number | - | Default size of the panel as a percentage (0-100) |
minSize | number | - | Minimum size of the panel as a percentage |
maxSize | number | - | Maximum size of the panel as a percentage |
collapsible | boolean | false | Whether the panel can be collapsed |
className | string | -- | Additional CSS classes for the panel |
children | React.ReactNode | -- | Panel content |
...props | React.ComponentPropsWithoutRef<typeof Panel> | - | Additional props inherited from Panel. |
ResizableHandle
| Prop | Type | Default | Description |
|---|---|---|---|
withHandle | boolean | true | Whether to render the visible grip icon handle. Set to false to show only the thin line. |
className | string | -- | Additional CSS classes for the resize handle |
...props | React.ComponentPropsWithoutRef<typeof Separator> | - | Additional props inherited from Separator. |
MotionResizablePanelGroup
scaleIn entrance (fade, scale, and blur) with springBouncy transition on mount. Wraps ResizablePanelGroup. Requires the motion package.
| Prop | Type | Default | Description |
|---|---|---|---|
...props | ResizablePanelGroupProps | - | All props from ResizablePanelGroup are supported |