Swatch Grid

Pro

A grid of pickable samples, a color or a glyph over a color, of which at most one is chosen. The arrow keys move through it in two dimensions and only a click, Enter or Space chooses, so a pick with side effects never fires on a focus move.

Label colorBlue

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Activate your Pro license (once per machine)npx koalaui-cli@latest login <key># Add this component (its dependencies come along)npx koalaui-cli@latest add swatch-grid

Usage#

This example is part of Koala UI Pro

The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.

Have a license? Unlock it here

Anatomy#

import { SwatchGrid, SwatchGridItem } from "@/components/ui/swatch-grid"<SwatchGrid>  <SwatchGridItem /></SwatchGrid>

Glyphs over a color#

size="md" makes 2rem cells with the glyph inset 0.1875rem, for an icon, a sprite <img> or a Koala icon <svg>; sm (the default) makes 1.75rem cells for plain colors. Here the icon grid is painted in the color chosen above it, so every cell shows the marker as it will look. A cell without color paints nothing, which suits the "Automatic" way back to a default.

Unit marker

Automatic

Translucent colors#

checkered lays a checkerboard under the cell's color. An opaque color hides it; a translucent one lets it through, so 50% black reads as half-transparent rather than as a dim grey.

Disabled#

A disabled cell dims, takes no press and is skipped by the arrow keys. Say why in its label, since that is all a screen reader gets.

Keyboard#

The grid is one stop in the Tab order. Moving never chooses: a pick can cost a request, so only a deliberate key does. ↑ and ↓ read the rows from the layout, so they follow whatever column count the grid has at that width.

KeyAction
← →Move to the previous or next cell, wrapping at the ends.
↑ ↓Move to the nearest cell in the row above or below.
Home EndMove to the first or last cell.
Enter SpaceChoose the focused cell.

API reference#

SwatchGrid

The root: Radix ToggleGroup.Root with type="single", laid out as a CSS grid. Set the columns with className (e.g. grid-cols-8), merged last. Name it with aria-label.

PropTypeDefaultDescription
valuestring-The chosen cell's value; "" for none.
defaultValuestring""The chosen cell when uncontrolled.
onValueChange(value: string) => void-Called with the newly chosen cell, never with "": pressing the chosen cell again keeps it. Listen to the cell's onClick to act on a repeat press.
size"sm" | "md""sm"Reaches every cell: sm (1.75rem) for colors, md (2rem, the glyph inset 0.1875rem) for glyphs.
disabledbooleanfalseDisables every cell.
loopbooleantrue←/→ wrap from the last cell to the first.
rovingFocusbooleantrueRadix roving focus: the grid is one Tab stop and the arrow keys move inside it.
dir"ltr" | "rtl"-The reading direction ←/→ follow.
staticbooleanfalseKept for compatibility; controls no longer scale on press.
Data attributeDescription
data-slot"swatch-grid".

SwatchGridItem

A cell: a Radix ToggleGroup.Item (role="radio"). Every button prop is forwarded; children are a glyph (an <img> or an <svg>, sized to the cell).

PropTypeDefaultDescription
value*string-The cell's value.
label*string-The accessible name: a swatch carries no visible text.
colorstring-The fill: any CSS color, set as --swatch. Without it, no fill.
checkeredbooleanfalseLays a checkerboard under the color, so a translucent one reads as translucent, not dim.
disabledbooleanfalseTakes the cell out of the roving focus and dims it.
staticboolean-Kept for compatibility; controls no longer scale on press.
Data attributeDescription
data-slot"swatch-grid-item".
data-state"on" on the chosen cell, "off" on the rest.
data-disabledPresent when the cell is disabled.
CSS variableDescription
--swatchThe cell's color, from color. transparent on the root, so a cell without one inherits nobody's.
--surfaceRead for the gap between the cell and its selection ring: the ground the grid sits on (falls back to --background).

FAQ#

RadioSwatch is for a handful of product colors in a form, where the arrow keys choosing as they move is the radio convention. Swatch Grid is for dozens of samples where a pick has effects, so moving never chooses, ↑ and ↓ move by rows, and a cell can hold a glyph.