For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. An agent skill is available at /.well-known/agent-skills/site-skill.md.
Home

Resizable

Draggable split panels for horizontal and vertical layouts, built on react-resizable-panels.

Sidebar
Content
Nav
Editor
Preview
Top panel
Bottom panel
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable";

export const ResizableDemo = () => (
    <div className="flex flex-col gap-6">
      {/* Horizontal */}
      <ResizablePanelGroup orientation="horizontal" className="min-h-40 rounded-lg border">
        <ResizablePanel defaultSize={30}><div className="flex h-full items-center justify-center p-4"><span className="text-muted-foreground text-sm">Sidebar</span></div></ResizablePanel>
        <ResizableHandle withHandle />
        <ResizablePanel defaultSize={70}><div className="flex h-full items-center justify-center p-4"><span className="text-muted-foreground text-sm">Content</span></div></ResizablePanel>
      </ResizablePanelGroup>
      {/* Three panels */}
      <ResizablePanelGroup orientation="horizontal" className="min-h-40 rounded-lg border">
        <ResizablePanel defaultSize={20} minSize={15}><div className="flex h-full items-center justify-center p-4"><span className="text-muted-foreground text-sm">Nav</span></div></ResizablePanel>
        <ResizableHandle withHandle />
        <ResizablePanel defaultSize={55}><div className="flex h-full items-center justify-center p-4"><span className="text-muted-foreground text-sm">Editor</span></div></ResizablePanel>
        <ResizableHandle withHandle />
        <ResizablePanel defaultSize={25} minSize={15}><div className="flex h-full items-center justify-center p-4"><span className="text-muted-foreground text-sm">Preview</span></div></ResizablePanel>
      </ResizablePanelGroup>
      {/* Vertical */}
      <ResizablePanelGroup orientation="vertical" className="min-h-56 rounded-lg border">
        <ResizablePanel defaultSize={60}><div className="flex h-full items-center justify-center p-4"><span className="text-muted-foreground text-sm">Top panel</span></div></ResizablePanel>
        <ResizableHandle withHandle />
        <ResizablePanel defaultSize={40}><div className="flex h-full items-center justify-center p-4"><span className="text-muted-foreground text-sm">Bottom panel</span></div></ResizablePanel>
      </ResizablePanelGroup>
    </div>
  );

Horizontal

Two side-by-side panels separated by a draggable handle.

<ResizablePanelGroup direction="horizontal" className="rounded-lg border">
  <ResizablePanel defaultSize={50}>
    <div className="p-4">Left panel</div>
  </ResizablePanel>
  <ResizableHandle />
  <ResizablePanel defaultSize={50}>
    <div className="p-4">Right panel</div>
  </ResizablePanel>
</ResizablePanelGroup>

Vertical

Stack panels top-to-bottom with direction="vertical".

<ResizablePanelGroup direction="vertical" className="rounded-lg border">
  <ResizablePanel defaultSize={50}>
    <div className="p-4">Top panel</div>
  </ResizablePanel>
  <ResizableHandle />
  <ResizablePanel defaultSize={50}>
    <div className="p-4">Bottom panel</div>
  </ResizablePanel>
</ResizablePanelGroup>

Three panels

Add more panels and handles for multi-pane layouts.

<ResizablePanelGroup direction="horizontal" className="rounded-lg border">
  <ResizablePanel defaultSize={25} minSize={15}>
    <div className="p-4">Sidebar</div>
  </ResizablePanel>
  <ResizableHandle />
  <ResizablePanel defaultSize={50}>
    <div className="p-4">Main</div>
  </ResizablePanel>
  <ResizableHandle />
  <ResizablePanel defaultSize={25} minSize={15}>
    <div className="p-4">Inspector</div>
  </ResizablePanel>
</ResizablePanelGroup>

With handle grip

Add withHandle to the ResizableHandle to show a visible drag grip icon.

<ResizableHandle withHandle />

Controlled size

Use defaultSize, minSize, and maxSize (all in percent) to constrain each panel.

<ResizablePanel
  defaultSize={30}
  minSize={20}
  maxSize={60}
  collapsible
  collapsedSize={5}
>
  ...
</ResizablePanel>

Props

ResizablePanelGroup

PropTypeDefaultDescription
direction"horizontal" | "vertical"—Required. Split direction
onLayout(sizes: number[]) => void—Called whenever panel sizes change
classNamestring—Additional CSS classes

ResizablePanel

PropTypeDefaultDescription
defaultSizenumber—Initial size as a percentage of the group
minSizenumber—Minimum size percentage
maxSizenumber—Maximum size percentage
collapsiblebooleanfalseAllow the panel to collapse to collapsedSize
collapsedSizenumber0Size percentage when collapsed
classNamestring—Additional CSS classes

ResizableHandle

PropTypeDefaultDescription
withHandlebooleanfalseShow a drag grip icon on the handle
classNamestring—Additional CSS classes

Usage

import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable";
 
<ResizablePanelGroup direction="horizontal" className="h-full rounded-lg border">
  <ResizablePanel defaultSize={20} minSize={15} collapsible>
    <nav className="p-2">Sidebar nav</nav>
  </ResizablePanel>
  <ResizableHandle withHandle />
  <ResizablePanel defaultSize={80}>
    <main className="p-4">Page content</main>
  </ResizablePanel>
</ResizablePanelGroup>

Specs

# Mint — Resizable Specs
 
## Component
- name: resizable
- file: registry/mint/resizable.tsx
- installs to: components/ui/resizable.tsx
- dependencies: react-resizable-panels, lucide-react
- registryDependencies: none
 
## What is it
Thin styled wrappers around react-resizable-panels that add consistent handle
styling to draggable split-panel layouts. Use it for IDE-style workspaces,
sidebar/content splits, and multi-pane dashboards. Do not use when panels have
fixed sizes — a simple CSS grid or flex layout is more appropriate.
 
## Visual identity
Minimal and unobtrusive: the separator is a 1px --border line, a soft,
translucent green line at 60% opacity, that expands its hit area via a
pseudo-element without visual noise. The optional grip pill (border
+ --border fill, rounded-xs) signals draggability while staying compact and light.
 
## Design tokens
--border: oklch(0.88 0.04 155 / 60%) / oklch(0.32 0.05 155 / 40%)   — separator line and grip pill fill/border
--ring: oklch(0.5 0.14 155) / oklch(0.62 0.15 155)         — green focus ring on the handle
 
## Sub-components
- ResizablePanelGroup  → flex container that wraps all panels; sets orientation via aria-[orientation]
- ResizablePanel       → individual resizable pane; accepts size constraints and collapsible behaviour
- ResizableHandle      → 1px separator with extended hit area; withHandle renders a visible grip pill
 
## External dependencies
- react-resizable-panels: keyboard-accessible drag-resize engine (Panel, PanelGroup, PanelResizeHandle)
- lucide-react: provides GripVerticalIcon for the withHandle grip pill
 
## States
- focus-visible: 1px --ring ring with 1px offset on the handle separator
- aria-[orientation=horizontal]: handle rotates to horizontal layout (h-px, full-width after pseudo-element, grip div rotates 90deg)
 
## Conventions
- All size values (defaultSize, minSize, maxSize, collapsedSize) are percentages (0–100), not pixels
- Always set minSize to prevent a panel from collapsing to zero unintentionally
- Use collapsible + collapsedSize for sidebar patterns that can be fully hidden
- Persist layout across sessions with onLayout + localStorage
- withHandle improves discoverability; omit it for minimal or data-dense UIs
- Sub-components expose data-slot="resizable-panel-group", data-slot="resizable-panel", and data-slot="resizable-handle" for CSS targeting
- Keyboard resize (from react-resizable-panels): Arrow keys = 1%, Shift+Arrow = 10%, Home/End = min/max

Installation

GIN Design Plugin
$ npx shadcn add https://gin-design.vercel.app/resizable