Manual UI Templates Resizable

Resizable

elements man ui/templates/resizable

Panels separated by handles you drag or move with the arrow keys.

Example
import { ResizablePanelGroup, ResizablePanel, ResizableHandle, ResizableGrid, ResizableCell, ResizableGridline, } from "@elements/ui/resizable"; <ResizablePanelGroup orientation="horizontal" autoSaveId="mail"> <ResizablePanel defaultSize="25%" minSize="15%" collapsible>Folders</ResizablePanel> <ResizableHandle withHandle /> <ResizablePanel>Messages</ResizablePanel> </ResizablePanelGroup> <!-- layout and collapsed are two-way --> <ResizablePanelGroup layout={state.layout}>...</ResizablePanelGroup> <ResizablePanel collapsible collapsed={state.sideClosed}>...</ResizablePanel> <!-- columns and rows at once --> <ResizableGrid columns={3} rows={2}> <ResizableCell column={0} row={0} columnSpan={2}>Header</ResizableCell> <ResizableCell column={2} row={0} rowSpan={2}>Inspector</ResizableCell> <ResizableCell column={0} row={1}>Files</ResizableCell> <ResizableCell column={1} row={1}>Editor</ResizableCell> <ResizableGridline type="row" row={1} columnSpan={2} /> <ResizableGridline type="column" column={1} row={1} /> <ResizableGridline type="column" column={2} /> </ResizableGrid>

Parts

Part What it is
ResizablePanelGroup The flex row or column. Owns the layout: each panel's percent of the free space.
ResizablePanel A region with a size, limits and optional collapse.
ResizableHandle The separator between two panels: drag it or focus it and use the keys.
.resizable-grip The visible grip withHandle renders.
ResizableGrid A CSS grid whose columns and rows both resize. Owns a layout per axis.
ResizableCell Occupies one or more columns and rows.
ResizableGridline Resizes the columns or rows on either side of one boundary. Where a column and a row gridline cross, a drag resizes both.

Attributes

ResizablePanelGroup

Attribute Type Default Description
orientation "horizontal" | "vertical" "horizontal" Panels side by side, or stacked.
layout number[] (two-way) [] Every panel's percent, summing to 100. Bind it to read the layout or set it; empty uses the panels' defaults.
disabled boolean false No handle resizes.
disableCursor boolean false Leave the page cursor alone while dragging.
keyboardStep number 10 Percent an arrow key moves a handle.
autoSaveId string "" Remembers the layout in localStorage under this id.
dir "ltr" | "rtl" | "" "" Reading direction; empty inherits.
onLayoutChange (layout: number[]) => void () => {} Every change, including each pointer move.
onLayoutChanged (layout: number[], meta: { isUserInteraction: boolean; requestedLayout: number[] }) => void () => {} Once a drag ends, a key moves a handle, or code sets the layout. requestedLayout is the layout before constraints; save that one.
resizePreviewMode "panel" | "separator" "panel" separator: a drag moves only the separator, and the panels resize on release.

ResizablePanel

Attribute Type Default Description
id string generated Keys the saved layout and the handle's aria-controls.
defaultSize number | string even share Starting size. A number is px; a string takes px, %, rem, em, vh, vw; a bare string is percent.
minSize number | string "0%" Smallest size.
maxSize number | string "100%" Largest size.
collapsible boolean false Pushed past its threshold below minSize, it collapses to collapsedSize.
collapsedSize number | string "0%" Size while collapsed.
collapsedThreshold number | string half of min minus collapsed How far past minSize it must go to collapse, and be pulled to expand.
collapsed boolean (two-way) false Whether it is collapsed. Set it to collapse or expand; the group writes it back as the user drags.
disabled boolean false Neither resized nor pushed by its neighbors.
groupResizeBehavior "preserve-relative-size" | "preserve-pixel-size" "preserve-relative-size" When the group resizes, keep this panel's percent or its px.
onResize (size: PanelSize, id: string, prevSize: PanelSize | undefined) => void () => {} Its size changed, as { asPercentage, inPixels }; prevSize is undefined on the first layout.
onCollapse / onExpand () => void () => {} It collapsed or expanded.

ResizableHandle

Attribute Type Default Description
withHandle boolean false Shows a grip on the hairline.
disabled boolean false This handle does not resize.
fixed boolean false APG fixed size splitter: no arrow keys or dragging; Enter or a click toggles the panel before it between its size and collapsed.
disableDoubleClick boolean false A double click no longer resets the panel before it to its default size.
label string "Resize" The separator's accessible name. Pass "" with attrs aria-labelledby to name it by the pane's visible label.
preview "panel" | "separator" | "" "" Overrides the group's resizePreviewMode for this handle.
onDragging (dragging: boolean) => void () => {} A pointer drag started or ended.

ResizableGrid

Attribute Type Default Description
columns, rows number | TrackSpec[] 2, 1 A track count, or one { id, defaultSize, minSize, maxSize, collapsible, collapsedSize, collapsedThreshold, disabled } per track, in the panel units.
layout { columns: number[]; rows: number[] } (two-way) { columns: [], rows: [] } Every track's percent per axis. Its initial value is the default layout; bind it to read or set.
disabled, disableCursor, keyboardStep, autoSaveId, dir as on the group false, false, 10, "", "" As on ResizablePanelGroup; disableCursor also drops the gridlines' resize cursors.
onLayoutChange / onLayoutChanged (layout, meta?) => void () => {} Every change, and once a drag ends, a key moves a gridline or code sets the layout.

ResizableCell

Attribute Type Default Description
column, row number 0 The first column and row it occupies, from 0.
columnSpan, rowSpan number 1 How many tracks it spans.

ResizableGridline

Attribute Type Default Description
type "column" | "row" "column" A column gridline is vertical and resizes columns; a row gridline resizes rows.
column, row number 0 The boundary it sits on (the leading edge of that track) and the first track of the other axis it runs beside.
rowSpan / columnSpan number 0 (all) How many tracks it runs beside. Never beside a cell that spans its boundary.
withHandle, disabled, disableDoubleClick, label, onDragging as on the handle as on the handle As on ResizableHandle.

all

Attribute Type Default Description
class, attrs string, Record "", {} Extra classes and attributes on the element.

Slots

Slot Part Content
default ResizablePanelGroup Panels and handles, alternating.
default ResizablePanel The panel's content; may hold another group.

Keyboard

Keys Action
ArrowLeft / ArrowRight Horizontal group: moves the focused handle by keyboardStep.
ArrowUp / ArrowDown Vertical group: moves the focused handle by keyboardStep.
Home The panel before the handle to its smallest size, collapsed if it can.
End The panel before the handle to its largest size.
Enter Collapses the panel before the handle, or restores it.
Arrows, Home, End, Enter (gridline) A column gridline takes Left and Right, a row gridline Up and Down; Home, End and Enter act on the track before it.
F6 / Shift + F6 Moves focus through the window panes: from a handle to the pane after it (Shift: before it), from a pane to the next or previous pane.

Data attributes

Attribute Values On Description
data-orientation "horizontal" | "vertical" root
data-group, data-panel-group present root
data-panel-size percent .resizable-panel
data-collapsible present .resizable-panel
data-collapsed present .resizable-panel While collapsed.
data-state "inactive" | "hover" | "drag" .resizable-handle
data-preview present .resizable-handle While a separator preview is shown (resizePreviewMode separator).
data-dragging present .resizable-handle While dragged.
data-disabled present root, .resizable-panel, .resizable-handle
data-fixed present .resizable-handle A fixed size splitter.
data-edge-hover, data-edge-dragging present root The pointer is on, or dragging, an edge where two panels meet without a separator.
data-grid present .resizable-grid
data-cursor "move" | "col-resize" | "row-resize" .resizable-grid The pointer is on a resize target; move where two axes meet.
data-dragging present .resizable-grid While a pointer drag runs.
data-cell, data-column, data-row, data-column-span, data-row-span present, index .resizable-cell
data-type "column" | "row" .resizable-gridline
data-state "inactive" | "hover" | "drag" .resizable-gridline

Accessibility

  • Each handle is a focusable separator (WAI-ARIA window splitter) with aria-orientation, aria-controls naming the panel before it, and aria-valuenow, aria-valuemin and aria-valuemax in percent.
  • Arrow keys move it, Home and End go to the limits, Enter collapses and restores, F6 moves between the window panes. A fixed handle takes only Enter. Separators are optional: without one, the edge between two panels is the drag target.
  • The focus ring is a box-shadow on the hairline; the hit area is wider than the line, wider still on touch screens.
  • A grid's gridlines are separators too, with aria-controls naming the cells on their leading side. F6 moves through the cells.

See also