Resizable

Drag-to-resize panel groups powered by react-resizable-panels. Supports horizontal and vertical layouts, nested groups, and optional handle grip indicators.

Anatomy

<ResizablePanelGroup> is the root container. It holds <ResizablePanel> elements separated by <ResizableHandle> dividers. The direction is controlled by the orientation prop.

Panel A
Panel B

Horizontal

Side-by-side panels. Drag the vertical divider to redistribute the available width between them.

Sidebar

Dashboard
Projects
Settings
Main content area

Vertical

Stacked panels. Drag the horizontal divider to redistribute height.

Top Panel
Bottom Panel

Three Panels

Add more panels with handles between each pair. Set minSize to prevent panels from collapsing too far.

Left
Center
Right

Design Guidelines

Do

  • Set minSize on every panel. Without a minimum, panels can collapse to zero and become impossible to re-expand.
  • Use withHandle for discoverability. The grip indicator tells users the divider is draggable, especially for less familiar users.
  • Use for complex layout tools. Code editors, dashboards, and file explorers are natural fits.

Don't

  • Don't use on mobile without a fallback. Drag handles are difficult to use on touch devices — provide a fixed layout on small screens.
  • Don't use for simple two-column layouts. CSS grid or flex is easier to maintain; resizable panels are for user-controlled layouts.
  • Don't nest deeply. More than two levels of nested panel groups creates confusing resize behavior.

Developer Reference

Accessibility & Key Props

  • ResizableHandle renders with role="separator" and aria-orientation set automatically.
  • Keyboard: / (horizontal) or / (vertical) resize panels when the handle is focused.
  • defaultSize — percentage (0–100) of the group to allocate to this panel initially.
  • minSize / maxSize— clamp the panel's resizable range.
  • withHandle on ResizableHandle shows the grip dot indicator.

Usage

import {
  ResizablePanelGroup, ResizablePanel, ResizableHandle
} from "@/components/ui/resizable"

// Horizontal split
<ResizablePanelGroup orientation="horizontal" className="min-h-[200px] rounded-lg border">
  <ResizablePanel defaultSize={30} minSize={20}>
    <div className="p-4">Sidebar</div>
  </ResizablePanel>
  <ResizableHandle withHandle />
  <ResizablePanel defaultSize={70}>
    <div className="p-4">Main content</div>
  </ResizablePanel>
</ResizablePanelGroup>

// Vertical split
<ResizablePanelGroup orientation="vertical" className="min-h-[300px] rounded-lg border">
  <ResizablePanel defaultSize={40} minSize={20}>
    <div className="p-4">Top</div>
  </ResizablePanel>
  <ResizableHandle />
  <ResizablePanel defaultSize={60}>
    <div className="p-4">Bottom</div>
  </ResizablePanel>
</ResizablePanelGroup>