Resizable
Drag-to-resize panel groups. Supports horizontal, vertical, and nested layouts.
Examples
Vertical split
Stack panels and resize along the vertical axis.
import { ResizableGroup, ResizablePanel, ResizableSeparator } from "@codefast/ui/resizable";
export function ResizableVertical() {
return (
<ResizableGroup orientation="vertical" className="min-h-50 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>
<ResizableSeparator />
<ResizablePanel defaultSize="75%">
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Content</span>
</div>
</ResizablePanel>
</ResizableGroup>
);
}
Handle
Use the withHandle prop on ResizableSeparator to show a visible handle.
import { ResizableGroup, ResizablePanel, ResizableSeparator } from "@codefast/ui/resizable";
export function ResizableSeparatorDemo() {
return (
<ResizableGroup orientation="horizontal" className="min-h-50 max-w-md rounded-lg border md:min-w-112.5">
<ResizablePanel defaultSize="25%">
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Sidebar</span>
</div>
</ResizablePanel>
<ResizableSeparator withHandle />
<ResizablePanel defaultSize="75%">
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Content</span>
</div>
</ResizablePanel>
</ResizableGroup>
);
}
RTL
Right-to-left layout support for languages such as Arabic and Hebrew.
Translations are AI-generated for demonstration and may be imperfect.
import { ResizableGroup, ResizablePanel, ResizableSeparator } from "@codefast/ui/resizable";
import type { Translations } from "#/features/components-catalog/components/detail/language";
import { useTranslation } from "#/features/components-catalog/components/detail/language-context";
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 (
<ResizableGroup orientation="horizontal" className="max-w-sm rounded-lg border" dir={dir}>
<ResizablePanel defaultSize="50%">
<div className="flex h-50 items-center justify-center p-6">
<span className="font-semibold">{t.one}</span>
</div>
</ResizablePanel>
<ResizableSeparator withHandle />
<ResizablePanel defaultSize="50%">
<ResizableGroup 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>
<ResizableSeparator withHandle />
<ResizablePanel defaultSize="75%">
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">{t.three}</span>
</div>
</ResizablePanel>
</ResizableGroup>
</ResizablePanel>
</ResizableGroup>
);
}
Usage
The minimal import and composition — see Examples below for styled, real-world variants.
import { ResizableGroup, ResizablePanel, ResizableSeparator } from "@codefast/ui/resizable";
export function ResizableUsage() {
return (
<ResizableGroup className="max-w-md rounded-lg border">
<ResizablePanel defaultSize={50}>
<div className="flex h-32 items-center justify-center p-6">One</div>
</ResizablePanel>
<ResizableSeparator />
<ResizablePanel defaultSize={50}>
<div className="flex h-32 items-center justify-center p-6">Two</div>
</ResizablePanel>
</ResizableGroup>
);
}
Anatomy
How the parts nest — every slot the component exposes, in composition order.
Features
- Built on react-resizable-panels — defaultSize/minSize/maxSize are percentages of the group, not pixels.
- withHandle on ResizableSeparator adds a small visible grip in the middle of the drag handle.
- Nest a ResizableGroup inside a ResizablePanel to combine horizontal and vertical splits in one layout.
API reference
Props for each part of the component. All native element props are also forwarded.
ResizableGroup
A row or column of resizable panels.
orientation"horizontal" | "vertical"Axis the panels are laid along.
Default
"horizontal"
ResizablePanel
defaultSizenumber (percent)The panel's initial size.
minSizenumber (percent)The panel's minimum size.
Default
0maxSizenumber (percent)The panel's maximum size.
Default
100
ResizableSeparator
The draggable handle placed between two panels.
withHandlebooleanShows a small visible grip in the middle of the drag handle.
Default
false
Accessibility
Built to be keyboard-navigable and screen-reader friendly out of the box.
| Key | Function |
|---|---|
| Tab | Moves focus to a separator handle. |
| Arrow+Left | Resizes the panels by a step. |
| Arrow+Right | Resizes the panels by a step. |
- Each handle is a focusable separator with aria-valuenow for its position.
- Set sensible minSize so panels can’t collapse to nothing by accident.
- Provide a non-drag fallback layout on touch where resizing is awkward.
Guidelines
Conventions that keep usage consistent across an app.
Do
- Use for app shells — sidebars, editors, split views.
- Set min/max sizes to keep panels usable.
Don’t
- Don’t use for simple content that doesn’t need resizing.
- Don’t allow a panel to shrink below a readable size.
Explore further
Ready to integrate?
Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.