Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
Made by bvaughn
Edit on GitHub

Resizable

Accessible resizable panel groups and layouts with keyboard support.

Installation

bash
npx shadcn@latest add @redpanda/resizable
bash
pnpm dlx shadcn@latest add @redpanda/resizable
bash
yarn dlx shadcn@latest add @redpanda/resizable
bash
bunx shadcn@latest add @redpanda/resizable
bash
nubx shadcn@latest add @redpanda/resizable
bash
aube dlx shadcn@latest add @redpanda/resizable

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:

Usage

Basic Horizontal Layout

tsx
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/components/redpanda-ui/resizable';
<ResizablePanelGroup orientation="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

tsx
<ResizablePanelGroup orientation="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

tsx
<ResizablePanelGroup orientation="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

tsx
<ResizablePanelGroup orientation="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 orientation="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:

plaintext
<ResizablePanelGroup> (Container)├── orientation="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:├── [aria-orientation] - horizontal/vertical├── [data-resize-handle-active] - during resize└── [data-resize-handle-state] - drag/hover/idle

Key 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 orientation prop to set the direction of the resizable panels.

tsx
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

You can set or hide the handle by using the withHandle prop on the ResizableHandle component.

tsx
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/components/ui/resizable';
export default function Example() {  return (    <ResizablePanelGroup orientation="horizontal">      <ResizablePanel>One</ResizablePanel>      <ResizableHandle withHandle />      <ResizablePanel>Two</ResizablePanel>    </ResizablePanelGroup>  );}

Credits

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • minorv0.3.0Add theme-provider component to the registry with documentation and tests. Includes playground type improvements (export RegistryItem, remove as-const boilerplate) and docs site dark mode border color fix.#109
See full history →

Last updated on

Was this page helpful?