Skip to content
Home Theme Gallery

Resizable

The custom element is <hui-resizable>.

Overview

A group of panes with draggable, keyboard-operable separators. The sizes are viewer-owned, reflected as an attribute and announced, never stored.

Example

Two panes
Source
<hui-resizable orientation="horizontal" sizes="30,70" style="width:100%;height:6rem;border:1px solid var(--hui-border);border-radius:var(--hui-radius-lg);overflow:hidden">
<div data-size="30" data-min-size="10" style="background:var(--hui-muted);padding:.5rem">Left</div>
<div data-size="70" data-min-size="10" style="background:var(--hui-card);padding:.5rem">Right</div>
</hui-resizable>

The Go template that renders it:

<hui-resizable orientation="horizontal" sizes="{{ .Sizes }}">
<div data-size="30" data-min-size="10">Left</div>
<div data-size="70" data-min-size="10">Right</div>
</hui-resizable>

API

Attributes2
Attributes
NameTypeDefaultDescription
orientation"horizontal" | "vertical""horizontal"Which way the panes divide.
sizescomma-separated percentages""The current sizes. Reflected; the server may render persisted sizes.
Properties2
Properties
NameTypeDefaultDescription
orientationstring'horizontal'Reflects to orientation.
sizesstring''Reflects to sizes.
Events1
Events
NameDescription
hui-resizeA drag or key press settled, after sizes is set. Detail: { sizes }.
Slots1
Slots
NameDescription
(default)The panes. Each has data-size, data-min-size and optional data-collapsible.
CSS custom properties2
CSS custom properties
NameDefaultDescription
--hui-borderoklch(0.922 0.005 325.62)Handle hairline.
--hui-focus-ring-width3pxFocus ring on the handle.

States

This element has no states beyond its default.

Server-side mechanics

The server owns only the initial sizes, which it may render from whatever it persisted. The element is not form-associated and submits nothing. The current sizes are viewer-owned: reflected to sizes and announced with hui-resize, so the host can persist them if it cares. An hx-swap re-renders the panes and re-reads sizes; a drag in progress is discarded and no pointer capture or document listener survives.

Accessibility

  • Each handle is a role="separator" with aria-valuenow, aria-valuemin and aria-valuemax.
  • The handle has an accessible name from the host’s aria-label.
  • Dragging and the arrow keys produce the same sizes for the same movement, so the pointer is not the only way.

Keyboard

Keyboard
KeysAction
Arrow keysMove the focused separator by 2 percent.
Home, EndMove to the minimum or maximum.
EnterCollapses or restores a collapsible pane.

Gotchas

  • It is a light-DOM behaviour element: the panes are its direct children, and it injects a .hui-resizable__handle between each pair. There is no shadow root and no ::part.
  • A drag uses setPointerCapture rather than listeners on document, so a swap during a drag leaves nothing behind.