HySwatchGroup
Usage examples on this page are written for Lit / plain HTML (
<hy-swatch-group>). The same component ships asHySwatchGroupin@whitespaceux/harmony-react(native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.
Child components: <hy-swatch> — used only inside this one.
A width-adaptive, accessible grid of selectable HySwatch 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: containerrole="radiogroup", cellsrole="radio"+aria-checked. Arrow keys move and select.selection-mode="multiple"→ listbox: containerrole="listbox"aria-multiselectable, cellsrole="option"+aria-selected. Arrow keys move; Space/Enter toggles.selection-mode="none"→ display-onlyrole="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.
Disabled
disabled disables the whole group: every cell is aria-disabled="true" and out of the Tab order (the group has no Tab stop; focus() is a no-op), and nothing selects. The group dims once — its cells do not dim again, a cell that is itself disabled included. Same contract as the React HySwatchGroup.
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 — both ways, no floor — the shape for a ramp strip that must fit every stop in its row. A numeric group therefore needs a definite width: shrink-wrapped, its cells collapse like any 1fr grid.
When to use
- Choosing one option from a short set shown as samples: a color, a size, a material.
- A color that must come from an approved set.
Do
- Give each swatch a name, shown next to the selection.
When not to use
- Any color, not one from a fixed set:
hy-color-picker. - Options that are words rather than samples:
hy-radio-group, orhy-selectfor a longer list.
Accessibility: your part
- Give every selectable
hy-swatchalabelthat names the choice, so it is not told by color alone. Atooltiponly shows on hover and focus.
Examples
Color ramp (single-select)
<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
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
selectionMode | selection-mode | 'single' | 'multiple' | 'none' | 'single' | Selection behavior: single (radiogroup), multiple (listbox), or none. |
value | value | string | '' | Selected value in single mode. |
values | — | string[] | [] | Selected values in multiple mode (property only — arrays don't reflect). |
columns | columns | string | 'auto' | auto (a wrapping row of fixed-size cells) or a fixed column count as a string (e.g. "12") whose cells stretch to fill the width. |
size | size | 'small' | 'medium' | 'large' | 'medium' | Cell size preset — the sample size every cell renders at with columns="auto". Ignored with a numeric columns, where the track sizes the cell. |
wrap | wrap | boolean | true | Whether horizontal arrow navigation wraps at row edges. Set false via property. |
disabled | disabled | boolean | false | Disables the whole group. |
label | label | string | '' | Accessible name for the group (required when selectable). |
Events
| Event | Detail | Description |
|---|---|---|
change | — | Fired when the selection changes. Detail: { selectedValues: string[], reason: StateChangeReason } |
Slots
| Slot | Description |
|---|---|
default | The hy-swatch cells. |
CSS Parts
| Part | Description |
|---|---|
base | The grid container (carries the ARIA role). |
CSS Custom Properties
The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.
| Property | Default | Description |
|---|---|---|
--hy-swatch-group-gap-layout-2xs | var(--hy-gap-layout-2xs) | Gap between cells. |
Methods
focus()
Focus the selected cell, or the first enabled cell. A no-op while the group is disabled.