Component reference
Resizable
A workspace inspector with resizable panels.
Preview
Live previewOptional six-digit hex. Clear to restore the preset. Check contrast with your brand color.
Changes apply to this preview only.
Inspector
A canvas and a properties panel.
Diff view
Before and after, with a vertical split.
Width adapts to the available space
"use client";
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
Resizable
} from "@pimolu/react";
const splitFrame = {
border: "1px solid var(--pimolu-border)",
borderRadius: "var(--pimolu-radius-lg)",
overflow: "hidden",
background: "var(--pimolu-background)",
} as const;
export function DemoExample() {
return (
<div
className="grid grid-cols-[repeat(auto-fit,minmax(min(100%,280px),1fr))] gap-6 min-w-0 items-start"
>
<Card>
<CardHeader>
<CardTitle>Inspector</CardTitle>
<CardDescription>A canvas and a properties panel.</CardDescription>
</CardHeader>
<CardContent>
<Resizable
aria-label="Canvas and properties"
defaultSizes={[64, 36]}
minSize={25}
paneClassName="min-w-0 rounded-lg border border-border p-6"
style={{
...splitFrame,
height: 220
}}
>
<div
style={{
display: "grid",
placeItems: "center",
height: "100%",
minHeight: 120,
background: "var(--pimolu-muted)",
borderRadius: "var(--pimolu-radius-md)",
}}
>
<span className="text-sm text-muted leading-relaxed">Canvas</span>
</div>
<div className="grid gap-5 min-w-0">
<span className="text-sm text-muted leading-relaxed">PROPERTIES</span>
<span>Radius · md</span>
<span>Density · comfortable</span>
<span>Theme · light</span>
</div>
</Resizable>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Diff view</CardTitle>
<CardDescription>Before and after, with a vertical split.</CardDescription>
</CardHeader>
<CardContent>
<Resizable
aria-label="Before and after"
orientation="vertical"
defaultSizes={[
50,
50
]}
paneClassName="min-w-0 rounded-lg border border-border p-6"
style={{
...splitFrame,
height: 220
}}
>
<pre
style={{
margin: 0,
fontSize: 12,
color: "var(--pimolu-muted-foreground)",
}}
>
{`- border-radius: 8px;\n- box-shadow: none;`}
</pre>
<pre
style={{
margin: 0,
fontSize: 12,
color: "var(--pimolu-success)",
}}
>
{
`+ border-radius: var(--pimolu-radius-lg);\n+ box-shadow: var(--pimolu-shadow-md);`
}
</pre>
</Resizable>
</CardContent>
</Card>
</div>
);
}More examples
Different configurations and compositions using the real Pimolu API. Each preview runs independently and follows the site appearance.
Horizontal split
A file list next to a read-only preview. The separator keeps pointer capture during a drag and exposes aria-valuenow.
Vertical split
The same component stacked: the separator becomes horizontal and the arrow keys follow the axis.
Constraints
Each pane keeps its own minimum. The start pane also respects maxSize, so 100% is never reachable by accident.
Usage
Set useful minimum sizes and keep panel state in the surrounding workspace when persistence is needed.
API reference
Generated from the public TypeScript declarations. Native HTML attributes are inherited where the component extends them; this reference includes Pimolu props and selected common native attributes.
PimoluResizableProps
Type source| Name | Type | Default | Description |
|---|---|---|---|
childrenRequired | [ReactNode, ReactNode] | — | Exactly two panes: the start pane, then the end pane. |
orientation | PimoluResizableOrientation | undefined | "horizontal" | Layout direction. "horizontal" places the panes side by side and "vertical" stacks them. Defaults to "horizontal". |
sizes | PimoluResizableSizes | undefined | — | Controlled sizes, as percentages of the available space. |
defaultSizes | PimoluResizableSizes | undefined | [50, 50] | Initial sizes when uncontrolled. Defaults to [50, 50]. |
onSizesChange | ((sizes: PimoluResizableSizes) => void) | undefined | — | Called with the normalized sizes whenever the split changes. |
minSize | number | PimoluResizableSizes | undefined | 10 | Minimum size of each pane, as a percentage. A single number applies to both panes; a tuple sets them independently. Defaults to 10. |
maxSize | number | undefined | 90 | Maximum size of the start pane, as a percentage. Defaults to 90. |
step | number | undefined | 1 | Keyboard increment, as a percentage. Defaults to 1. |
resetSizes | PimoluResizableSizes | undefined | — | Sizes restored on a separator double-click. |
onReset | ((sizes: PimoluResizableSizes) => void) | undefined | — | Called after a double-click reset, with the restored sizes. |
separatorLabel | string | undefined | "Resize panels" | Accessible name of the separator. Defaults to "Resize panels". |
disabled | boolean | undefined | false | Disables pointer, keyboard and reset interactions. |
paneClassName | string | undefined | — | Class applied to both panes. |
separatorClassName | string | undefined | — | Class applied to the separator. |
defaultValue | string | number | readonly string[] | undefined | — | Standard React/HTML attribute. |
className | string | undefined | — | Standard React/HTML attribute. |
style | CSSProperties | undefined | — | Standard React/HTML attribute. |
aria-label | string | undefined | — | Defines a string value that labels the current element. |
onClick | MouseEventHandler<HTMLDivElement> | undefined | — | Standard React/HTML attribute. |
childrenRequired[ReactNode, ReactNode]No default extracted.
Exactly two panes: the start pane, then the end pane.
orientationPimoluResizableOrientation | undefinedDefault: "horizontal"
Layout direction. "horizontal" places the panes side by side and "vertical" stacks them. Defaults to "horizontal".
sizesPimoluResizableSizes | undefinedNo default extracted.
Controlled sizes, as percentages of the available space.
defaultSizesPimoluResizableSizes | undefinedDefault: [50, 50]
Initial sizes when uncontrolled. Defaults to [50, 50].
onSizesChange((sizes: PimoluResizableSizes) => void) | undefinedNo default extracted.
Called with the normalized sizes whenever the split changes.
minSizenumber | PimoluResizableSizes | undefinedDefault: 10
Minimum size of each pane, as a percentage. A single number applies to both panes; a tuple sets them independently. Defaults to 10.
maxSizenumber | undefinedDefault: 90
Maximum size of the start pane, as a percentage. Defaults to 90.
stepnumber | undefinedDefault: 1
Keyboard increment, as a percentage. Defaults to 1.
resetSizesPimoluResizableSizes | undefinedNo default extracted.
Sizes restored on a separator double-click.
onReset((sizes: PimoluResizableSizes) => void) | undefinedNo default extracted.
Called after a double-click reset, with the restored sizes.
separatorLabelstring | undefinedDefault: "Resize panels"
Accessible name of the separator. Defaults to "Resize panels".
disabledboolean | undefinedDefault: false
Disables pointer, keyboard and reset interactions.
paneClassNamestring | undefinedNo default extracted.
Class applied to both panes.
separatorClassNamestring | undefinedNo default extracted.
Class applied to the separator.
defaultValuestring | number | readonly string[] | undefinedNo default extracted.
Standard React/HTML attribute.
classNamestring | undefinedNo default extracted.
Standard React/HTML attribute.
styleCSSProperties | undefinedNo default extracted.
Standard React/HTML attribute.
aria-labelstring | undefinedNo default extracted.
Defines a string value that labels the current element.
onClickMouseEventHandler<HTMLDivElement> | undefinedNo default extracted.
Standard React/HTML attribute.
Accessibility
- Verify separator keyboard resizing and keep content usable at its minimum size.