Resizable
A group of panels that users resize by dragging the handle between them.
A resizable panel group divides an area into panels and places a handle between them. Users drag a handle to give one panel more room and its neighbor less, or they focus the handle and press the arrow keys. A double-click on a handle returns a panel that has a default size to that size. The group fills the width and the height of the element around it, so that element sets the size of the whole area.
Usage
Examples
Horizontal
Side-by-side panels suit layouts in which content benefits from width, such as a navigation next to the content it opens. The group uses this arrangement by default, and orientation set to "horizontal" states it explicitly.
Vertical
Stacked panels suit content that benefits from height, such as a chart above the figures behind it. With orientation set to "vertical", users divide the height between the panels, so the element around the group needs a height of its own.
With Handle
A visible grip makes the handle easy to find for users who rarely change a layout. The grip appears through withHandle and marks the place where a drag begins.
Nested
A panel can hold a group of its own and divide its area along the other axis. Users then resize each level independently, for example the width of a sidebar and the height of two areas beside it.
Minimum Size
Some content loses its use below a certain size. Through minSize a panel keeps at least that size, and the handle stops as soon as the panel reaches it.
Maximum Size
A panel that grows without limit can push its neighbors out of view. Through maxSize it stops at a largest size, and the panels beside it keep the remaining space.
Panel Preview Mode
Users judge a new layout best while they are still dragging. The panels therefore follow every movement of the pointer, which is the default behavior of resizePreviewMode with the value "panel".
Separator Preview Mode
Panels with extensive content, such as large tables or charts, react more calmly when they change size only once. With the value "separator" of resizePreviewMode, a preview of the handle follows the pointer, and the panels take their new size when users release it.
Custom Preview
In separator mode, a drag shows a translucent copy of the handle by default. The preview prop of the handle replaces it with an element of its own, so the preview fits the product and marks where the panels will divide.
Larger Resize Target
A thin handle is hard to hit, especially on a touch screen. Through resizeTargetMinimumSize the area that starts a resize grows beyond the visible line, with separate sizes for a mouse and for touch input.
Without Resize Cursor
The group shows a resize cursor over a handle so that users recognize it as something to drag. Through disableCursor it keeps the regular pointer instead, and resizing works as before.
Without Double-Click Reset
A double-click on a handle returns a panel to its default size and lets users undo their changes in one step. Where a layout should stay exactly as users left it, disableDoubleClick turns this reset off.
Layout While Resizing
Some interfaces react to the layout while users are still dragging, for example to adapt content to the space it receives. For this purpose, onLayoutChange reports the size of every panel with each movement of the pointer.
Layout After Resizing
A layout that users have arranged deserves to be kept for their next visit. The final layout arrives through onLayoutChanged once users release the pointer, so the application saves it once per change.
Current Panel Size
Content can adapt to the room its panel offers, for example with more columns in a wider panel. Through onResize a panel reports its size in pixels and as a percentage whenever it changes.
Disabled Group
Some layouts must stay fixed, for example while a process works on the data they show. The disabled prop of the group then locks every panel, for the pointer as well as for the keyboard.
Disabled Panel
Within a flexible layout, one area can keep its size, such as a navigation with a fixed width. Set on a single panel, disabled holds that size whichever handle users drag, and the other panels share the remaining space.
Disabled Handle
Sometimes only one boundary of a layout should stay in place. Users can no longer drag a handle that carries disabled, and keyboard focus passes over it, while the other handles still resize their panels.
API Reference
ResizablePanelGroup
| Prop | orientation |
|---|---|
| Type | "horizontal" | "vertical" |
| Default | "horizontal" |
| Description | Sets the axis along which the panels are laid out and resized. A horizontal group places the panels side by side, and users change their widths. A vertical group stacks them, and users change their heights. |
| Prop | defaultLayout |
|---|---|
| Type | Layout |
| Default | – |
| Description | Sets the sizes of the panels at first render as an object that maps each panel id to a percentage from 0 to 100. The group applies it only when its keys are exactly the ids of the panels, and it then takes precedence over defaultSize. |
| Prop | onLayoutChange |
|---|---|
| Type | (layout: Layout) => void |
| Default | – |
| Description | Runs when the layout changes and receives the layout that follows. During a drag, it runs on every pointer move. It also runs once with the first layout after the group mounts. |
| Prop | onLayoutChanged |
|---|---|
| Type | (layout: Layout, meta: LayoutChangedMeta) => void |
| Default | – |
| Description | Runs after the layout has changed. During a drag, it waits until users release the pointer, which suits saving a layout. In meta, isUserInteraction tells whether pointer or keyboard input caused the change, and requestedLayout holds the layout before the constraints of the current group size were applied. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from resizing the panels of the group with the pointer or the keyboard. |
| Prop | disableCursor |
|---|---|
| Type | boolean |
| Default | false |
| Description | Turns off the resize cursors that the group sets while the pointer is over a handle or drags it. |
| Prop | resizePreviewMode |
|---|---|
| Type | "panel" | "separator" |
| Default | "panel" |
| Description | Sets what a drag changes before users release the pointer. With "panel", the panels resize at once. With "separator", a preview of the handle follows the pointer, and the panels resize when users release it. |
| Prop | resizeTargetMinimumSize |
|---|---|
| Type | { coarse: number; fine: number } |
| Default | { coarse: 20, fine: 10 } |
| Description | Sets the smallest size, in pixels, of the area around a handle or a panel edge that starts a resize. coarse applies when the primary pointer is coarse, as on a touch screen, and fine applies otherwise, as with a mouse. A handle that is thinner than the value responds within that area. |
| Prop | groupRef |
|---|---|
| Type | Ref<GroupImperativeHandle | null> |
| Default | – |
| Description | Receives the imperative API of the group. getLayout returns the current layout, and setLayout applies a layout and returns the layout that results from the constraints of the panels. |
| Prop | elementRef |
|---|---|
| Type | Ref<HTMLDivElement | null> |
| Default | – |
| Description | Receives the div that the group renders. |
| Prop | id |
|---|---|
| Type | string | number |
| Default | – |
| Description | Identifies the group. The group also sets it as the id and data-testid attributes of its div. Without it, the group generates an id. |
ResizablePanel
| Prop | defaultSize |
|---|---|
| Type | number | string |
| Default | – |
| Description | Sets the size of the panel at first render. A number counts as pixels, a string without a unit as a percentage of the group, and a string with a unit as that unit: %, px, em, rem, vh or vw. Panels without it share the remaining space equally. |
| Prop | minSize |
|---|---|
| Type | number | string |
| Default | "0%" |
| Description | Sets the smallest size that the panel can take. It accepts the same formats as defaultSize. |
| Prop | maxSize |
|---|---|
| Type | number | string |
| Default | "100%" |
| Description | Sets the largest size that the panel can take. It accepts the same formats as defaultSize. |
| Prop | collapsible |
|---|---|
| Type | boolean |
| Default | false |
| Description | Lets the panel collapse to collapsedSize when users resize it below minSize. Users expand it by dragging the handle back. While a handle has focus, Enter collapses or expands the collapsible panel before it. |
| Prop | collapsedSize |
|---|---|
| Type | number | string |
| Default | "0%" |
| Description | Sets the size of the panel while it is collapsed. It accepts the same formats as defaultSize. |
| Prop | collapsedThreshold |
|---|---|
| Type | number | string |
| Default | – |
| Description | Sets how far users drag a collapsible panel below minSize before it collapses, and above collapsedSize before it expands. Without it, the threshold is half the distance between collapsedSize and minSize. It accepts the same formats as defaultSize. |
| Prop | groupResizeBehavior |
|---|---|
| Type | "preserve-relative-size" | "preserve-pixel-size" |
| Default | "preserve-relative-size" |
| Description | Sets what the panel keeps when the group itself changes size. With "preserve-relative-size", the panel keeps its percentage of the group. With "preserve-pixel-size", it keeps its size in pixels as far as minSize and maxSize allow. A group needs at least one panel with "preserve-relative-size". |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents the panel from changing size, whether users drag a handle beside it or resize another panel. |
| Prop | onResize |
|---|---|
| Type | (panelSize: PanelSize, id: string | number | undefined, prevPanelSize: PanelSize | undefined) => void |
| Default | – |
| Description | Runs when the size of the panel changes, and once after the panel mounts. It receives the size as an object with asPercentage and inPixels, the id of the panel if the id prop is set, and the previous size, which is undefined at the first call. |
| Prop | panelRef |
|---|---|
| Type | Ref<PanelImperativeHandle | null> |
| Default | – |
| Description | Receives the imperative API of the panel. collapse and expand change a collapsible panel, isCollapsed tells whether it is collapsed, getSize returns the size with asPercentage and inPixels, and resize sets a size in the formats of defaultSize. |
| Prop | elementRef |
|---|---|
| Type | Ref<HTMLDivElement | null> |
| Default | – |
| Description | Receives the outer div of the panel, which the group sizes. |
| Prop | id |
|---|---|
| Type | string | number |
| Default | – |
| Description | Identifies the panel within its group. The keys of defaultLayout and of the layouts that the callbacks receive are panel ids. The panel also sets it as the id and data-testid attributes of its outer div. Without it, the panel generates an id. |
| Prop | className |
|---|---|
| Type | string |
| Default | – |
| Description | Adds classes to the inner div that holds the content. The outer div is the flex item that the group sizes, and it takes no classes. |
| Prop | style |
|---|---|
| Type | CSSProperties |
| Default | – |
| Description | Sets inline styles on the inner div that holds the content. That div scrolls its content with overflow "auto" unless style sets another value. |
ResizableHandle
| Prop | withHandle |
|---|---|
| Type | boolean |
| Default | false |
| Description | Shows a grip in the middle of the handle, so that users see where to drag. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from resizing the neighboring panels with this handle and removes the handle from the tab order. The panels can still change size when users drag another handle. |
| Prop | disableDoubleClick |
|---|---|
| Type | boolean |
| Default | false |
| Description | Turns off the reset on double-click. Without it, a double-click on the handle returns the first neighboring panel that has a defaultSize to that size. |
| Prop | preview |
|---|---|
| Type | ReactNode |
| Default | – |
| Description | Sets the element that follows the pointer while users drag this handle in a group with resizePreviewMode set to "separator". Without it, the group shows a translucent copy of the handle. |
| Prop | elementRef |
|---|---|
| Type | Ref<HTMLDivElement> |
| Default | – |
| Description | Receives the div that the handle renders. |
| Prop | id |
|---|---|
| Type | string | number |
| Default | – |
| Description | Identifies the handle within its group. The handle also sets it as the id and data-testid attributes of its div. Without it, the handle generates an id. |