Command Palette

Search for a command to run...

Github

Resizable

Accessible resizable panel groups and layouts with keyboard support.

One
Two
Three
import {
	ResizableHandle,
	ResizablePanel,
	ResizablePanelGroup,
} from "@/components/ui/resizable";

export function ResizableDemo() {
	return (
		<ResizablePanelGroup
			orientation="horizontal"
			className="max-w-sm rounded-lg border"
		>
			<ResizablePanel defaultSize="50%">
				<div className="flex h-[200px] items-center justify-center p-6">
					<span className="font-semibold">One</span>
				</div>
			</ResizablePanel>
			<ResizableHandle withHandle />
			<ResizablePanel defaultSize="50%">
				<ResizablePanelGroup orientation="vertical">
					<ResizablePanel defaultSize="25%">
						<div className="flex h-full items-center justify-center p-6">
							<span className="font-semibold">Two</span>
						</div>
					</ResizablePanel>
					<ResizableHandle withHandle />
					<ResizablePanel defaultSize="75%">
						<div className="flex h-full items-center justify-center p-6">
							<span className="font-semibold">Three</span>
						</div>
					</ResizablePanel>
				</ResizablePanelGroup>
			</ResizablePanel>
		</ResizablePanelGroup>
	);
}

Installation

pnpm dlx shadcn@latest add https://herocn.dev/r/resizable.json

Usage

import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
<ResizablePanelGroup orientation="horizontal">
  <ResizablePanel defaultSize="50%">One</ResizablePanel>
  <ResizableHandle />
  <ResizablePanel defaultSize="50%">Two</ResizablePanel>
</ResizablePanelGroup>

Composition

Use the following composition to build a ResizablePanelGroup:

ResizablePanelGroup
├── ResizablePanel
├── ResizableHandle
└── ResizablePanel

Examples

Vertical

Use orientation="vertical" for vertical resizing.

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

export function ResizableVertical() {
	return (
		<ResizablePanelGroup
			orientation="vertical"
			className="min-h-[200px] max-w-sm rounded-lg border"
		>
			<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%">
				<div className="flex h-full items-center justify-center p-6">
					<span className="font-semibold">Content</span>
				</div>
			</ResizablePanel>
		</ResizablePanelGroup>
	);
}

Handle

Use the withHandle prop on ResizableHandle to show a visible handle.

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

export function ResizableHandleDemo() {
	return (
		<ResizablePanelGroup
			orientation="horizontal"
			className="min-h-[200px] max-w-sm rounded-lg border"
		>
			<ResizablePanel defaultSize="25%">
				<div className="flex h-full items-center justify-center p-6">
					<span className="font-semibold">Sidebar</span>
				</div>
			</ResizablePanel>
			<ResizableHandle withHandle />
			<ResizablePanel defaultSize="75%">
				<div className="flex h-full items-center justify-center p-6">
					<span className="font-semibold">Content</span>
				</div>
			</ResizablePanel>
		</ResizablePanelGroup>
	);
}

RTL

To enable RTL support in herocn, see the RTL configuration guide.

واحد
اثنان
ثلاثة
"use client";

import {
	type Translations,
	useTranslation,
} from "@/components/language-selector";
import {
	ResizableHandle,
	ResizablePanel,
	ResizablePanelGroup,
} from "@/components/ui/resizable";

const translations: Translations = {
	en: {
		dir: "ltr",
		values: {
			one: "One",
			two: "Two",
			three: "Three",
		},
	},
	ar: {
		dir: "rtl",
		values: {
			one: "واحد",
			two: "اثنان",
			three: "ثلاثة",
		},
	},
	he: {
		dir: "rtl",
		values: {
			one: "אחד",
			two: "שניים",
			three: "שלושה",
		},
	},
};

export function ResizableRtl() {
	const { dir, t } = useTranslation(translations, "ar");

	return (
		<ResizablePanelGroup
			orientation="horizontal"
			className="max-w-sm rounded-lg border"
			dir={dir}
		>
			<ResizablePanel defaultSize="50%">
				<div className="flex h-[200px] items-center justify-center p-6">
					<span className="font-semibold">{t.one}</span>
				</div>
			</ResizablePanel>
			<ResizableHandle withHandle />
			<ResizablePanel defaultSize="50%">
				<ResizablePanelGroup orientation="vertical" dir={dir}>
					<ResizablePanel defaultSize="25%">
						<div className="flex h-full items-center justify-center p-6">
							<span className="font-semibold">{t.two}</span>
						</div>
					</ResizablePanel>
					<ResizableHandle withHandle />
					<ResizablePanel defaultSize="75%">
						<div className="flex h-full items-center justify-center p-6">
							<span className="font-semibold">{t.three}</span>
						</div>
					</ResizablePanel>
				</ResizablePanelGroup>
			</ResizablePanel>
		</ResizablePanelGroup>
	);
}

API Reference

See the react-resizable-panels documentation.