Usage
Resizable composes an alternating sequence of panels and separators. It keeps ordered sizes as normalized percentages of the usable axis, excluding the fixed handle tracks, and applies minimum, maximum, and collapse constraints without moving consumer content.
Importing the group, panel, and handle modules registers their custom elements:
import "@nordhealth/components/lib/Resizable"
import "@nordhealth/components/lib/ResizablePanel"
import "@nordhealth/components/lib/ResizableHandle"
Composition
Resizable uses an alternating sequence of Panels and Handles. Panels own sizing constraints and content; each Handle controls the adjacent regions and exposes separator semantics and input behavior.
- Resizable Panel defines a constrained region in the group.
- Resizable Handle provides the accessible separator interaction between panels.
Examples
Vertical layouts
Set orientation="vertical" to resize on the block axis. Separator ARIA orientation and keyboard behavior update automatically.
Visible handle
Set with-handle on a separator to show a centered grip without changing its minimal layout track or token-derived pointer target.
Right-to-left layouts
Set dir="rtl" on the group or an ancestor. Horizontal panel order follows the document direction, Arrow Left and Arrow Right keep logical resizing intent, and pointer deltas are mirrored. Vertical behavior remains direction-independent.
Nested layouts
A panel can contain another Resizable group. Registration is direct-child only, so nested state and interaction remain independent.
Constraints and collapse
Panel default-size, min-size, max-size, and collapsed-size values are percentages. Home and End move the primary panel before a focused separator to the nearest boundary feasible through that separator. Enter toggles a panel with collapsible and restores its latest expanded size when constraints still permit it.
Keyboard interaction
- Orientation-appropriate Arrow keys resize by
keyboard-step. - Shift plus Arrow uses
large-keyboard-step. - Home and End move to the feasible minimum/collapsed or maximum.
- Enter toggles the collapsible primary panel.
Controlled state
Supply layout as a JavaScript array for controlled state. nord-resize proposes immutable { id, size } records, but the rendered panels change only after the consumer echoes the next size array back to layout. Without layout, interactions commit internal state; defaultLayout can provide its initial value.
Events and methods
nord-resize-startis cancelable and fires after usable geometry and pointer capture succeed.nord-resizeis cancelable and carries ordered layout records plus the interaction source.nord-resize-endcloses every accepted pointer lifecycle, including cancellation and capture loss.getLayout(),setLayout(),resizePanel(),collapsePanel(), andexpandPanel()expose the same validation and event model programmatically.
Accessibility
Each enabled handle is a focusable ARIA window splitter with a localized label, controlled panel references, matching orientation, and actual feasible percentage values. aria-valuenow is rounded to at most two decimal places for concise announcements; canonical layouts and resize events retain their six-decimal precision. Collapsed state is reported at collapsed-size, including zero, rather than clamped to the expanded minimum. The visible track stays thin while its calc(var(--n-space-xl) + var(--n-space-s)) target is at least 44 CSS pixels.
Use stable panel IDs, keep controls usable at every allowed size, and add a specific handle label when the default “Resize panels” does not identify the affected region. Logical styling and interactions support RTL, zoom, high contrast, and reduced motion.
API reference
Resizable
Resizable coordinates an alternating sequence of panels and handles using immutable percentage layouts and native pointer/keyboard interactions.
<nord-resizable></nord-resizable>Props
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
orientation | orientation | Axis along which panels resize. | ResizableOrientation | 'horizontal' |
keyboardStep | keyboard-step | Percentage changed by an orientation-appropriate Arrow key. | number | 5 |
largeKeyboardStep | large-keyboard-step | Percentage changed by Shift plus an orientation-appropriate Arrow key. | number | 10 |
disabled | disabled | Disables every handle in the group. | boolean | false |
Slots
| Slot name | Description |
|---|---|
Default slot | Alternating Resizable Panel and Resizable Handle direct children. |
| Event | Detail Type | Description |
|---|---|---|
nord-resize-start | ResizableResizeStartEvent | Cancelable event dispatched before a pointer drag starts. |
nord-resize | ResizableResizeEvent | Cancelable event carrying an immutable ordered layout and interaction source. |
nord-resize-end | ResizableResizeEndEvent | Event dispatched whenever an accepted pointer drag terminates. |
CSS Properties
CSS Custom Properties provide more fine grain control over component presentation. We advise utilizing existing properties on the component before using these.
| Property | Description | Default |
|---|---|---|
--n-resizable-inline-size | Controls the group inline size. | 100% |
--n-resizable-block-size | Controls the group block size. | 100% |
Parts
This component is made up of the following parts.
Resizable Handle
Resizable Handle is an accessible window splitter placed between two direct Resizable Panels.
<nord-resizable-handle></nord-resizable-handle>Props
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
disabled | disabled | Disables pointer and keyboard resizing and removes the handle from tab order. | boolean | false |
withHandle | with-handle | Shows a centered Nord-token grip in addition to the minimal divider. | boolean | false |
label | label | Accessible label. Defaults to a localized “Resize panels”. | string | '' |
CSS Properties
CSS Custom Properties provide more fine grain control over component presentation. We advise utilizing existing properties on the component before using these.
| Property | Description | Default |
|---|---|---|
--n-resizable-handle-color | Controls the divider color. | var(--n-color-border) |
--n-resizable-handle-active-color | Controls hover, focus, and drag color. | var(--n-color-accent) |
--n-resizable-handle-target-size | Controls the interactive hit target without changing the layout track. | calc(var(--n-space-xl) + var(--n-space-s)) |
Resizable Panel
Resizable Panel contains consumer-owned content whose percentage size is coordinated by its direct Resizable parent.
<nord-resizable-panel></nord-resizable-panel>Props
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
panelId | panel-id | Stable state identifier. Defaults to the panel's DOM id or a generated id. | string | undefined | — |
defaultSize | default-size | Initial percentage used when no group default layout supplies this panel. | number | undefined | — |
minSize | min-size | Minimum expanded percentage. | number | 0 |
maxSize | max-size | Maximum percentage. | number | 100 |
collapsible | collapsible | Allows the panel to snap below its minimum to collapsed-size. | boolean | false |
collapsedSize | collapsed-size | Percentage used while collapsed. | number | 0 |
Slots
| Slot name | Description |
|---|---|
Default slot | Consumer-owned panel content. |
CSS Properties
CSS Custom Properties provide more fine grain control over component presentation. We advise utilizing existing properties on the component before using these.
| Property | Description | Default |
|---|---|---|
--n-resizable-panel-overflow | Controls overflow of panel content. | auto |
Design guidelinesFor designers
Usage
This section includes guidelines for designers and developers about using this component in different contexts.
Do
- Use Resizable when two or more persistent regions benefit from user-controlled space.
- Give every panel a stable
panel-idand realistic percentage constraints. - Place panels and handles as a direct alternating sequence.
- Keep important controls usable at every permitted size and provide a meaningful handle
labelwhen “Resize panels” is too general. - Echo
event.layout.map(({ size }) => size)back to thelayoutproperty when using controlled state.
Don’t
- Don’t use Resizable for disclosure that should be a Drawer, Collapsible, or responsive layout change.
- Don’t put panels or handles inside wrapper elements; registration is intentionally direct-child only.
- Don’t add mouse-only drag instructions. Every enabled handle implements the keyboard window-splitter pattern.
- Don’t assume
nord-resizecommitted a controlled layout until the consumer supplies the nextlayoutvalue.
Composition and sizing
Panel sizes are normalized percentages of the usable group axis after fixed handle tracks are excluded. min-size, max-size, default-size, and collapsed-size are percentages. Constraints are applied deterministically and the last valid layout is retained if a dynamic composition becomes unsatisfiable.
Set --n-resizable-inline-size and --n-resizable-block-size when the surrounding layout does not already give the group definite dimensions. Panel content remains consumer-owned light DOM and is never stamped, moved, or recreated.
Controlled state and events
Omit layout for uncontrolled state, optionally supplying defaultLayout through JavaScript. Setting the layout property enables controlled state: pointer, keyboard, and programmatic interactions emit a proposed immutable layout while rendered sizes wait for the next property value.
nord-resize-start and nord-resize are cancelable. nord-resize-end pairs every accepted pointer lifecycle, including cancellation, capture loss, window blur, disabled state, or disconnect. Resize event records contain stable panel IDs, percentage sizes, and a source of pointer, keyboard, or programmatic.
Accessibility
Handles expose role="separator", the correct ARIA orientation, controlled panel IDs, and feasible current/minimum/maximum values. The rendered aria-valuenow is rounded to at most two decimals for concise announcements while canonical layouts and resize events keep their six-decimal precision. Arrow keys resize by keyboard-step; Shift uses large-keyboard-step; Home and End move the primary panel to its nearest feasible boundary; Enter toggles a collapsible primary panel.
The visible divider remains minimal while a calc(var(--n-space-xl) + var(--n-space-s)) pseudo-element supplies an at-least-44 CSS pixel pointer target. Focus, hover, and active states use Nord semantic tokens, and horizontal pointer/keyboard behavior follows RTL direction. Set dir="rtl" on the group or an ancestor; panel order and horizontal pointer/Arrow intent mirror while vertical interaction stays direction-independent. Disabled handles are removed from sequential focus and expose disabled semantics.