Skip to content

HySwatchGroup

Usage examples on this page are written for Lit / plain HTML (<hy-swatch-group>). The same component ships as HySwatchGroup in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

A width-adaptive, accessible grid of selectable [object Object] cells.

hy-swatch-group is content- and domain-agnostic — it knows nothing about color, ramps, or tokens. It lays out a reflowing grid of hy-swatch children, owns selection state and ARIA semantics, and reports the picked value(s) via a single change event. The same component backs color stop ramps and non-color ramps (spacing / radius / size rungs) alike.

Selection model (ARIA)

  • selection-mode="single" → radio-group: container role="radiogroup", cells role="radio" + aria-checked. Arrow keys move and select.
  • selection-mode="multiple" → listbox: container role="listbox"aria-multiselectable, cells role="option" + aria-selected. Arrow keys move; Space/Enter toggles.
  • selection-mode="none" → display-only role="group"; cells inert.

Keyboard

Roving tabindex (the group is a single Tab stop). Arrow keys navigate the 2D grid (←/→ within a row, ↑/↓ across rows), Home/End jump to first/last, Space/Enter select. Disabled cells are skipped. Row math tracks the live column count, so navigation stays correct as the grid reflows in a resizable panel.

Width adaptiveness

With columns="auto" (default) the cells are FIXED-SIZE — each renders at the size preset (--hy-swatch-size, pushed down to every cell) — and the row wraps to the available width, never overflowing; a swatch is a fixed-size control (Spectrum, Fluent). A numeric columns pins a column count and the cells stretch to fill the width instead — the shape for a ramp strip that must span its row.

Examples

Color ramp (single-select)

html
<hy-swatch-group label="Brand stops" value="500">
  <hy-swatch value="400" color="#7AB" label="400" aria-label="Brand 400"></hy-swatch>
  <hy-swatch value="500" color="#48A" label="500" aria-label="Brand 500"></hy-swatch>
</hy-swatch-group>

API

Properties

PropertyAttributeTypeDefaultDescription
selectionModeselection-mode'single' | 'multiple' | 'none''single'Selection behaviour: single (radiogroup), multiple (listbox), or none.
valuevaluestring''Selected value in single mode.
valuesstring[][]Selected values in multiple mode (property only — arrays don't reflect).
columnscolumnsstring'auto'auto (reflow via auto-fit) or a fixed column count as a string (e.g. "11").
sizesize'small' | 'medium' | 'large''medium'Cell size preset — the sample size every cell renders at with columns="auto", and the floor a stretched cell never goes under with a numeric columns.
wrapwrapbooleantrueWhether horizontal arrow navigation wraps at row edges. Set false via property.
disableddisabledbooleanfalseDisables the whole group.
labellabelstring''Accessible name for the group (required when selectable).

Events

EventDetailDescription
changeFired when the selection changes. Detail: { selectedValues: string[], reason: StateChangeReason }

Slots

SlotDescription
defaultThe hy-swatch cells.

CSS Parts

PartDescription
baseThe grid container (carries the ARIA role).

CSS Custom Properties

PropertyDescription
--hy-swatch-group-gapGap between cells.

Methods

focus()

Focus the selected cell, or the first enabled cell.

Built with Lit. Documented with VitePress.