Resizable
Accessible resizable panel groups and layouts built with react-resizable-panels.
Installation
1. Install the dependency:
npm install react-resizable-panels2. Copy and paste the following code into your project:
// components/ui/resizable.tsx
"use client"
import * as ResizablePrimitive from "react-resizable-panels"
import { GripVerticalIcon } from "lucide-react"
// ResizablePanelGroup: flex h-full w-full, vertical direction: flex-col
// ResizableHandle: w-px bg-border, withHandle prop shows a grip iconUsage
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/components/ui/resizable'
import { ComponentPreview } from '@/components/component-preview'<ResizablePanelGroup direction="horizontal" className="max-w-md rounded-lg border">
<ResizablePanel defaultSize={50}>
<div className="flex h-32 items-center justify-center p-6">
<span className="font-semibold">One</span>
</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel defaultSize={50}>
<div className="flex h-32 items-center justify-center p-6">
<span className="font-semibold">Two</span>
</div>
</ResizablePanel>
</ResizablePanelGroup>Examples
Vertical Layout
Use direction="vertical" to stack panels top to bottom.
<ResizablePanelGroup direction="vertical" className="max-w-md rounded-lg border">
<ResizablePanel defaultSize={50}>
<div className="flex h-32 items-center justify-center p-6">
<span className="font-semibold">Top</span>
</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel defaultSize={50}>
<div className="flex h-32 items-center justify-center p-6">
<span className="font-semibold">Bottom</span>
</div>
</ResizablePanel>
</ResizablePanelGroup>With Handle Grip
Add withHandle to ResizableHandle to display a visible grip indicator.
<ResizablePanelGroup direction="horizontal" className="max-w-md rounded-lg border">
<ResizablePanel defaultSize={50}>
<div className="flex h-32 items-center justify-center p-6">
<span className="font-semibold">One</span>
</div>
</ResizablePanel>
<ResizableHandle withHandle />
<ResizablePanel defaultSize={50}>
<div className="flex h-32 items-center justify-center p-6">
<span className="font-semibold">Two</span>
</div>
</ResizablePanel>
</ResizablePanelGroup>Three Panels
<ResizablePanelGroup direction="horizontal" className="max-w-lg rounded-lg border">
<ResizablePanel defaultSize={33}>
<div className="flex h-32 items-center justify-center p-6">
<span className="font-semibold">One</span>
</div>
</ResizablePanel>
<ResizableHandle withHandle />
<ResizablePanel defaultSize={34}>
<div className="flex h-32 items-center justify-center p-6">
<span className="font-semibold">Two</span>
</div>
</ResizablePanel>
<ResizableHandle withHandle />
<ResizablePanel defaultSize={33}>
<div className="flex h-32 items-center justify-center p-6">
<span className="font-semibold">Three</span>
</div>
</ResizablePanel>
</ResizablePanelGroup>API Reference
ResizablePanelGroup
| Prop | Type | Default | Description |
|---|---|---|---|
direction | "horizontal" | "vertical" | — | The direction panels are arranged. |
onLayout | (sizes: number[]) => void | — | Callback fired when panel sizes change. |
ResizablePanel
| Prop | Type | Default | Description |
|---|---|---|---|
defaultSize | number | — | Initial size of the panel as a percentage. |
minSize | number | — | Minimum size of the panel as a percentage. |
maxSize | number | — | Maximum size of the panel as a percentage. |
collapsible | boolean | — | Whether the panel can be collapsed. |
ResizableHandle
| Prop | Type | Default | Description |
|---|---|---|---|
withHandle | boolean | false | Whether to display a visible grip icon on the handle. |
Last updated on