Workspace
Panel groups
N panes in a row or column, each resizable
split-pane.tsxpanel-group.tsxdock-layout.tsx
// one reducer for every pane
<PanelGroup
layout={layout}
onLayoutChange={setLayout}
/>orientation
"horizontal"panels
3collapsible
sidebarsidebar 22% · editor 50% · inspector 28%
Usage
import { PanelGroup, PanelLayout, Panel } from "@gpuixui/dock";
import { useState } from "react";
const initial = new PanelLayout({
orientation: "horizontal",
panels: [
new Panel({ id: "sidebar", label: "Sidebar", size: 0.2, collapsible: true }),
new Panel({ id: "editor", label: "Editor", size: 0.8 }),
],
});
const [layout, setLayout] = useState(initial);
<PanelGroup
layout={layout}
onLayoutChange={setLayout}
renderPanel={(id) => <Pane id={id} />}
/>;API
| Prop | Type | Default | Consequence |
|---|---|---|---|
layout | PanelLayout | — | the persisted shape; controlled |
onLayoutChange | (layout: PanelLayout) => void | — | the next shape after a resize or a collapse |
renderPanel | (id: string) => ReactNode | — | one pane's content |
dividerLabel | (index: number) => string | undefined | Resize <left panel> | one gap's accessible name |
className | string | — | joined after the recipe |
Resizable
The same group answers to shadcn's names. ResizablePanelGroup declares its
panes and handles, builds the PanelLayout they describe, and renders
PanelGroup — one divider, one keyboard step, one persisted shape.
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@gpuixui/dock";
<ResizablePanelGroup direction="horizontal" defaultLayout={saved}>
<ResizablePanel defaultSize={20} id="sidebar" label="Sidebar" collapsible>
<Explorer />
</ResizablePanel>
<ResizableHandle label="Resize the explorer" />
<ResizablePanel defaultSize={80} id="editor" label="Editor">
<Editor />
</ResizablePanel>
</ResizablePanelGroup>;| Part | Props | Consequence |
|---|---|---|
ResizablePanelGroup | direction, layout, defaultLayout, onLayoutChange, className, testId, children | the axis and the shape; a controlled layout wins, and an omitted one is held by the group |
ResizablePanel | id, defaultSize, label, collapsible, children | one pane; defaultSize is a share, and label defaults to id |
ResizableHandle | label | one gap's accessible name; the divider itself is the group's |
defaultSize is a fraction, not a percentage that must sum to 100: 20 and
80 mean the same shares as 0.2 and 0.8, and normalizePanels rescales a
set that does not add up. The parts are declarations — they paint nothing — so
the group keeps the single tab stop a divider needs.
Edit this page on GitHubpackages/dock/docs/panel-group.mdx