Resizable
Panels the user can drag apart: a file tree next to an editor, a list next to a preview. Built on react-resizable-panels .
Live Examples
View Code
Stacked, and nested
View Code
Collapsible
View Code
Import
import {
ResizablePanelGroup,
ResizablePanel,
ResizableHandle,
} from "@jarllyng/nostromo";Props
ResizablePanelGroup
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal" | Which way the panels are laid out |
defaultLayout | Layout | - | Restore a saved layout |
onLayoutChanged | (layout: Layout) => void | - | Fires when a drag ends, for saving |
disabled | boolean | false | Nothing can be resized |
ResizablePanel
| Prop | Type | Default | Description |
|---|---|---|---|
defaultSize | number | string | Even split | A number is pixels, a bare string is percent |
minSize | number | string | 0 | Lower bound |
maxSize | number | string | "100%" | Upper bound |
collapsible | boolean | false | Can be dragged shut past minSize |
collapsedSize | number | string | 0 | Size when collapsed |
ResizableHandle
| Prop | Type | Default | Description |
|---|---|---|---|
withHandle | boolean | false | Draw a grip on the divider |
disabled | boolean | false | This divider cannot be dragged |
Sizes are numbers for pixels and strings for percent: defaultSize={200} is 200
pixels, defaultSize="50" is half. Explicit units work too, "20rem" for
instance.
Give the group’s parent a height
The group sets display, flex-direction, width: 100% and height: 100% as
inline styles. Inline styles beat classes, so this does nothing at all:
<ResizablePanelGroup className="h-96">The class lands on the element and is then overridden, with no warning. Put the height on the element around the group, which is what the examples above do, or pass it as a style, which merges:
<ResizablePanelGroup style={{ height: "24rem" }}>For the same reason ResizablePanelGroup adds no layout classes of its own. A
flex or a flex-direction switch would be dead CSS.
A class on a panel lands inside it
ResizablePanel renders a wrapper the library controls with flex, and puts your
className on a child inside it. That is deliberate upstream: it stops padding
and borders from fighting the flex sizing. A background on a panel paints the
inner box, which is what you want anyway.
Keyboard
The divider is a real separator with a tab stop and aria-valuenow. Arrow keys
resize it, Home and End send it to its limits, and Enter collapses or restores a
collapsible panel. That is the reason to use the library rather than a div with a
mousedown handler.
aria-orientation on the divider is the divider’s own axis, not the group’s: two
panels side by side are separated by a vertical line, so a horizontal group
reports aria-orientation="vertical".