useResizable@astryxdesign/core v0.5.2 · useResizable

Install with shadcn

Experimental compatibility. This installs the real Astryx package and creates a local public re-export; it does not copy component implementation source. How compatibility works.

This install URL expires with the draft preview.
bash
npx shadcn@latest add https://astryx-2z5i6c2u1-fbopensource.vercel.app/r/astryx-component-use-resizable.json
Install the editable showcase composition
bash
npx shadcn@latest add https://astryx-2z5i6c2u1-fbopensource.vercel.app/r/astryx-showcase-resizable-showcase.json

Usage

Hook for adding drag-to-resize behavior to layout regions. Supports single-region and multi-region configurations with snap points, collapsible panels, localStorage persistence, and cascade resize ordering.

ts
import {useResizable} from '@astryxdesign/core/Resizable'

Best practices

GuidancePractices
Do

Use percent(40, {min: pixel(333)}) for a 40% size with a 333px floor, or percent(10, {max: pixel(400)}) for a 10% size with a 400px ceiling. The options argument is required and carries a floor XOR a ceiling.

Do

A structured default is an initial choice only; a structured minSize or maxSize remains live. State, persistence, callbacks, resize(), paint, and ARIA all use resolved pixel numbers.

Do

Import percent and Table’s same pixel binding from @astryxdesign/core/Resizable/utils when constructing configuration in a Server Component; the root package exposes one pixel symbol and one percent symbol without collision.

Do

Use with Layout or AppShell sidebar for resizable navigation panels.

Do

Set autoSaveId to persist user-chosen sizes across page reloads.

Don't

Set minSize too small; content becomes unreadable. Prefer collapsible for panels that can hide entirely.

Parameters

ParamTypeDescription
defaultSize
|
(default: 250)

Initial size. Numbers, exact "Npx", and pixel(value) are pixels. Exact "N%" has no additional pixel bound. percent(value, {min: pixel(value)}) or percent(value, {max: pixel(value)}) adds one pixel floor or ceiling. A percentage resolves ONCE into pixels — against containerRef when supplied, against the viewport otherwise — and does not track its basis afterwards. The released broad number | string type remains compatible; runtime validation is authoritative.

minSize
(default: 50)

Minimum size. Numbers, exact "Npx", and pixel(value) remain pixels; exact "N%" has no additional pixel bound; percent(value, {min: pixel(value)}) or percent(value, {max: pixel(value)}) adds exactly one. Percentage minimums re-resolve when their basis changes and clamp the current pixel selection.

maxSize
(default: Infinity)

Maximum size. Numbers, exact "Npx", and pixel(value) remain pixels; exact "N%" has no additional pixel bound; percent(value, {min: pixel(value)}) or percent(value, {max: pixel(value)}) adds exactly one. Percentage maximums re-resolve when their basis changes and clamp the current pixel selection.

containerRef
RefObject<HTMLElement | null>

The element a percentage is a share of. Caller-owned: the hook never infers one. Omitted, percentages use the viewport, which is the released behaviour. The ref may point at a different element over time — the basis follows it. Until that element is actually laid out (not yet mounted, display:none, detached) percentages use a temporary 1200px basis rather than its zero measurement, and nothing is persisted from it.

direction
'horizontal' | 'vertical' (default: 'horizontal')

Which axis this region resizes along. Selects the container's inline or block content-box size as the percentage basis, and must match the direction given to ResizeHandle.

minSizePx
number

Deprecated. Use minSize, which also accepts a percentage. Supplying both is a type error; if untyped code supplies both, minSize wins.

maxSizePx
number

Deprecated. Use maxSize, which also accepts a percentage. Explicit Infinity remains valid.

collapsible
boolean (default: false)

Whether dragging below the collapsed threshold collapses the region to zero.

snaps
number[]

Pixel values to snap to during drag.

autoSaveId
string

Key for localStorage persistence of size and collapse state across sessions.

defaultIsCollapsed
boolean (default: false)

Initial collapse state (uncontrolled). A persisted entry wins over it.

isCollapsed
boolean

Controlled collapse state. collapse(), expand() and a drag past the threshold then report through onCollapseChange instead of changing state internally.

onCollapseChange
(isCollapsed: boolean) => void

Called once per collapse state change, via drag or programmatically.

Returns

FieldTypeDescription
sizenumber

Current size in pixels.

isCollapsedboolean

Whether the region is currently collapsed.

collapse() => void

Programmatically collapse the region.

expand() => void

Expand from collapsed state.

resize(size: number) => void

Resize to a specific pixel value.

propsResizableProps

Props to spread on the resizable component or pass to ResizeHandle.

Examples

Common configurations, variations, and states.
Resizable
Open in Playground

Horizontal resizable split with a draggable handle between two panels.

Resizable — Collapsible with snap points
Open in Playground

A collapsible sidebar with snap points, driven by useResizable. Dragging snaps to preset widths, dragging past the minimum collapses the panel, and the expand method restores it programmatically.