Resizable
Accessible resizable panel groups and layouts with keyboard support.
Made by bvaughnPowered by
Loading component...
When to use
Resizable panels create flexible layouts where users can adjust the size of content areas. Use this decision tree to determine when resizable panels are appropriate:
Installation
Usage
Basic Horizontal Layout
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/redpanda-ui/resizable"
<ResizablePanelGroup direction="horizontal" className="min-h-[200px]">
<ResizablePanel defaultSize={50}>
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Left Panel</span>
</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel defaultSize={50}>
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Right Panel</span>
</div>
</ResizablePanel>
</ResizablePanelGroup>With Size Constraints
<ResizablePanelGroup direction="horizontal" className="min-h-[200px]">
<ResizablePanel defaultSize={25} minSize={20} maxSize={40}>
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Sidebar (20-40%)</span>
</div>
</ResizablePanel>
<ResizableHandle withHandle />
<ResizablePanel defaultSize={75}>
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Main Content</span>
</div>
</ResizablePanel>
</ResizablePanelGroup>Three Panel Layout
<ResizablePanelGroup direction="horizontal" className="min-h-[200px]">
<ResizablePanel defaultSize={20} minSize={15}>
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Nav</span>
</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel defaultSize={60}>
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Content</span>
</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel defaultSize={20} minSize={15}>
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Sidebar</span>
</div>
</ResizablePanel>
</ResizablePanelGroup>Nested Layouts
<ResizablePanelGroup direction="vertical" className="min-h-[400px]">
<ResizablePanel defaultSize={25}>
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Header</span>
</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel defaultSize={75}>
<ResizablePanelGroup direction="horizontal">
<ResizablePanel defaultSize={30}>
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Sidebar</span>
</div>
</ResizablePanel>
<ResizableHandle withHandle />
<ResizablePanel defaultSize={70}>
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Main Content</span>
</div>
</ResizablePanel>
</ResizablePanelGroup>
</ResizablePanel>
</ResizablePanelGroup>Anatomy
The Resizable component system is built with react-resizable-panels and provides a flexible layout system:
<ResizablePanelGroup> (Container)
├── direction="horizontal" | "vertical"
├── Layout Management
│ ├── Size distribution
│ ├── Constraint enforcement
│ └── Resize calculations
├── <ResizablePanel> (Content Areas)
│ ├── Size Properties
│ │ ├── defaultSize - initial size percentage
│ │ ├── minSize - minimum size percentage
│ │ └── maxSize - maximum size percentage
│ ├── Content Container
│ └── Flex/Grid Positioning
└── <ResizableHandle> (Resize Controls)
├── Visual Divider - 1px border line
├── Interaction Area - invisible expanded hit area
├── Handle Indicator (optional)
│ ├── <GripVertical> icon
│ └── Rounded border container
├── Keyboard Support
│ ├── Arrow keys for adjustment
│ └── Home/End for min/max
└── Mouse/Touch Support
├── Drag interaction
└── Double-click reset
Data Attributes:
├── [data-panel-group-direction] - horizontal/vertical
├── [data-resize-handle-active] - during resize
└── [data-resize-handle-state] - drag/hover/idleKey Features:
- Flexible Sizing: Percentage-based with constraints
- Keyboard Accessible: Full keyboard navigation support
- Touch Friendly: Works on mobile devices
- Nested Layouts: Supports complex nested arrangements
- Persistent State: Can save/restore layout configurations
- Smooth Animations: Smooth resize transitions
Examples
Vertical
Use the direction prop to set the direction of the resizable panels.
Loading component...
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
export default function Example() {
return (
<ResizablePanelGroup direction="vertical">
<ResizablePanel>One</ResizablePanel>
<ResizableHandle />
<ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>
)
}Handle
You can set or hide the handle by using the withHandle prop on the ResizableHandle component.
Loading component...
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
export default function Example() {
return (
<ResizablePanelGroup direction="horizontal">
<ResizablePanel>One</ResizablePanel>
<ResizableHandle withHandle />
<ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>
)
}Credits
- We use react-resizable-panels for the resizable component.
- We take our inspiration from Shadcn UI for the resizable style.
Built by malinskibeniamin. The source code is available on GitHub.