useResizable@astryxdesign/core v0.5.2 · useResizable

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.

Use with shadcn

Already using the shadcn registry workflow? Install the real Astryx package and a local public re-export. Component implementation source stays in Astryx. How compatibility works.

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