# Resizable _(no submodules)_ - resizable.variants — `resizablePanelGroupVariants`,… - [resizable.variants](./resizable.variants.md) — `resizablePanelGroupVariants`, `resizablePanelVariants`, `resizableHandleVariants`, and `resizableHandleGripVariants` a… - resizable.variants — `resizablePanelGroupVariants`,… - [resizable.variants](./resizable.variants.md) — `resizablePanelGroupVariants`, `resizablePanelVariants`, `resizableHandleVariants`, and `resizableHandleGripVariants` a… - resizable.variants — `resizablePanelGroupVariants`,… - [resizable.variants](./resizable.variants.md) — `resizablePanelGroupVariants`, `resizablePanelVariants`, `resizableHandleVariants`, and `resizableHandleGripVariants` a… - resizable.variants — `resizablePanelGroupVariants`,… - [resizable.variants](./resizable.variants.md) — `resizablePanelGroupVariants`, `resizablePanelVariants`, `resizableHandleVariants`, and `resizableHandleGripVariants` a… - [resizable.variants](./resizable.variants.md) — `resizablePanelGroupVariants`, `resizablePanelVariants`, `resizableHandleVariants`, and `resizableHandleGripVariants` a… ## Purpose ``, ``, and `` are the chassis split-layout primitives built on `react-resizable-panels` v4 (`Group` / `Panel` / `Separator`). The library renders a flex container with `orientation` driving `flex-direction` (`horizontal` → row, `vertical` → column) and exposes pointer + keyboard resize gestures (Arrow keys when the handle is focused). The chassis layers cva slots and an optional `withHandle` indicator on the separator. Use this primitive for split-layout surfaces (sidebar / main / preview, master-detail, code-editor + preview). Each panel sizes itself via flex-grow / flex-shrink driven by the library; consumers persist sizes via the `defaultLayout` / `onLayoutChanged` props that pass through to the library. ## Features - Built on `react-resizable-panels` v4 (`Group` / `Panel` / `Separator`). - `orientation` prop on the group: `"horizontal"` (default; row layout) or `"vertical"` (column layout). - Pointer drag + keyboard resize (ArrowLeft/Right or ArrowUp/Down when the handle is focused) supplied by the library. - `defaultSize`, `minSize`, `maxSize`, `collapsible` per panel. - `withHandle` opt-in grip indicator on `` so coarse pointers (touch) get a visible hit indicator. - `defaultLayout` + `onLayoutChanged` for persisting sizes between sessions. - Theme-driven cva overrides for `ResizablePanelGroup`, `ResizablePanel`, `ResizableHandle`, `ResizableHandleGrip`. - `data-disabled` on the handle when the group's `disabled` prop is true; the handle still mounts but the cursor and opacity collapse so users see the disabled affordance. ## Usage: Basic Example ```tsx import { ResizableHandle, ResizablePanel, ResizablePanelGroup, } from "@suaveplan/react-ui"; export function TwoPaneSplit() { return (
Sidebar
Main content
); } ``` ## Usage: Advanced Example ```tsx import { ResizableHandle, ResizablePanel, ResizablePanelGroup, } from "@suaveplan/react-ui"; import type { Layout } from "react-resizable-panels"; const STORAGE_KEY = "editor.layout"; function loadLayout(): Layout | undefined { try { const raw = localStorage.getItem(STORAGE_KEY); return raw ? (JSON.parse(raw) as Layout) : undefined; } catch { return undefined; } } function saveLayout(layout: Layout): void { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(layout)); } catch { /* ignore */ } } export function EditorSplit() { return ( ); } ``` ## API Reference ### `` Wraps `Group` from `react-resizable-panels`. | Prop | Type | Default | Description | |---|---|---|---| | `id` | `string \| number` | `useId()` | Unique identifier within the application. Falls back to React's `useId()` when omitted. | | `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Layout axis. | | `defaultLayout` | `Layout` (`{ [panelId]: number }`) | _none_ | Initial layout (percentages 0..100 keyed by panel id). | | `onLayoutChange` | `(layout: Layout) => void` | _none_ | Fires on every pointer-move during drag — debounce before persisting. | | `onLayoutChanged` | `(layout: Layout) => void` | _none_ | Fires once after the pointer is released — recommended for persistence. | | `disabled` | `boolean` | `false` | Disable resize across the entire group; the handle gets `data-disabled` and the cursor stays default. | | `disableCursor` | `boolean` | `false` | Disable the library's drag-cursor styling. | ### `` Wraps `Panel`. | Prop | Type | Default | Description | |---|---|---|---| | `id` | `string \| number` | `useId()` | Unique identifier within the group. | | `defaultSize` | `number \| string` | _auto_ | Initial size as a percentage (`0..100`) or a CSS value. | | `minSize` | `number \| string` | _none_ | Minimum size during resize. | | `maxSize` | `number \| string` | _none_ | Maximum size during resize. | | `collapsible` | `boolean` | `false` | Allow the panel to collapse below `minSize` and snap to zero. | | `onResize` | `(size, id, prev) => void` | _none_ | Fires when the panel's size changes. | ### `` Wraps `Separator`. | Prop | Type | Default | Description | |---|---|---|---| | `id` | `string \| number` | `useId()` | Unique identifier within the group. | | `withHandle` | `boolean` | `false` | Render a small grip square (using lucide's ``) centred on the handle. | | `disabled` | `boolean` | `false` | Disable this individual handle. | | `disableDoubleClick` | `boolean` | `false` | Disable double-click-to-collapse on this handle. | ## Implementation Notes - The library v4 names are `Group` / `Panel` / `Separator`; the chassis re-exports them as `` / `` / `` for naming parity with the upstream shadcn registry name and so the chassis surface reads naturally. - The library applies `display`, `flex-direction`, `flex-wrap`, and `overflow` styles inline on the group root and CANNOT be overridden via className — the chassis cva sticks to layout-neutral recipes (`h-full w-full`). - The chassis NEVER assigns a numeric `z-index` (per the shadcn skill rule). Stacking is implicit — the handle sits between two panels in document order. - Each panel renders as an OUTER `
` wrapping a chassis-className-styled INNER `
`. Tests inspect the inner element when asserting cva classes. - The handle exposes `aria-orientation` perpendicular to the resize axis (a horizontal group has a vertical separator), matching the WAI-ARIA separator pattern. - The `withHandle` grip uses lucide's ``; consumers can render a custom indicator by composing their own children inside `` instead of opting into `withHandle`. - The `disabled` group prop sets `data-disabled` on the handle; the cva collapses the cursor and reduces opacity so users see the disabled state without losing the focus ring. - Per the WAI-ARIA separator pattern, the handle is keyboard-focusable (`tabindex="0"`); ArrowLeft/Right or ArrowUp/Down resize the adjacent panels by 5% per keystroke (library default).