ResizableLayout

A three-column drag-to-resize layout. Column widths are proportional (flex-based) by default so the layout responds to any container size, but the left and middle columns can each opt into a fixed pixel mode via leftFixedPx and middleFixedPx. Widths are persisted to localStorage via storageKey. Each divider reveals a cursor-following frosted pill on hover/drag.

Demo

Drag the dividers to resize. All three columns are resizable by default. Hover a divider to see the pill track the cursor.

left
middle
right

Without divider indicator

showDivider={false} hides the pill entirely. The drag area remains active — hover and drag work as before.

left
middle
right

Custom gap

gap controls the visual space between columns in pixels (default 24). With gap={0} columns sit flush; the divider's hit area stays at least 20px wide so the resize handle is always grabbable.

left
middle
right

Hidden columns + fullscreen

leftHidden, middleHidden, and rightHidden each collapse a column to zero width with an opacity fade. To make one column take the full viewport ("fullscreen"), hide the other two together — there's no dedicated fullscreen prop because two hidden columns already express the intent.

·
left
middle
right

Props

PropTypeDefaultDescription
leftReactNodeContent for the left column.
middleReactNodeContent for the middle column.
rightReactNodeContent for the right column.
topReactNodeOptional content rendered above all columns (e.g. a toolbar).
showDividerbooleantrueShow the cursor-following pill on dividers. The drag area is always active.
gapnumber24Visual width of the space between columns in px. The divider's interactive hit area stays at least 20px wide even when gap is smaller, so the resize handle is always grabbable.
paddingnumber12Outer padding from the layout's container edges in px. Set to 0 for designs where the layout sits flush with the viewport.
defaultWidths{ left?: number; middle?: number; right?: number }2/3/5Initial flex weights for each column. Ignored for any column that opts into a fixed-px mode (leftFixedPx, middleFixedPx).
minWidths{ left?: number; middle?: number; right?: number }80pxMinimum pixel width per column, enforced during drag-resize.
leftFixedPxnumberPin the left column to a fixed pixel width. The column ignores its flex ratio and never grows with the viewport.
middleFixedPxnumberPin the middle column to a fixed-but-resize-adjustable pixel width. The middle-right drag mutates the value 1:1 (clamped by minWidths.middle); the right column takes the remaining width. Pair with storageKey to persist the px value.
storageKeystringlocalStorage key to persist column widths across sessions.
leftHiddenbooleanfalseCollapse the left column.
middleHiddenbooleanfalseCollapse the middle column.
rightHiddenbooleanfalseCollapse the right column.
leftResizablebooleantrueEnable drag-to-resize on the left divider.
rightResizablebooleantrueEnable drag-to-resize on the right divider.
classNamestringExtra classes on the root element.