Resizable panels
FreeTwo panels separated by a draggable, keyboard-operable divider.
pnpm dlx shadcn@latest add https://caliperui.site/r/resizable-panels.jsonNotes have 58% of the width.
When to use #
Use it for
- Editors and previews side by side.
- Master-detail layouts where people choose the split.
Skip it when
- The layout should never change; use a fixed grid.
Installation #
terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/resizable-panels.json
Adds its 2 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
example.tsx
import { useState } from "react" import { ResizablePanels } from "@/components/ui/resizable-panels" export function NotesAndPreview() { const [size, setSize] = useState(58); return ( <div className="grid w-full max-w-xl gap-3"> <ResizablePanels defaultSize={58} onSizeChange={setSize} start={<div><p className="text-sm font-medium">Notes</p><p className="mt-2 text-sm text-muted-foreground">Drag the divider to give this note more room.</p></div>} end={<div><p className="text-sm font-medium">Preview</p><p className="mt-2 text-sm text-muted-foreground">Arrival sequence</p></div>} /> <p role="status" className="text-sm text-muted-foreground">Notes have {size}% of the width.</p> </div> ); }
API reference #
ResizablePanels
component
PropTypeDefault
start *ReactNode—
end *ReactNode—
labelstring"Resize panels"
defaultSizenumber58
minnumber28
onSizeChange((size: number) => void)—
classNamestring—
Accessibility #
It exposes separator semantics, with aria-orientation, aria-valuemin, aria-valuemax, aria-valuenow, aria-label and aria-hidden kept in step with state.
KeyBehaviour
←Moves to the previous item or value.
→Moves to the next item or value.
HomeJumps to the first item or the minimum.
EndJumps to the last item or the maximum.
Motion #
Transitions use the shared duration and easing tokens. Under prefers-reduced-motion those tokens collapse to instant and travel distances go to zero, so state changes still happen without movement.