Color swatch
ColorSwatch is a focusable grid of color cells the user picks from with the arrow keys or the mouse. Each color is a 3-column block; the cell whose color equals the bound value is marked with a ◘ glyph. Every arrow key, click, and drag updates value immediately (arrow navigation wraps around the palette ends) and fires the optional onInput; Enter, Space, or a mouse-up over a cell fires the optional onChange — the discrete commit a hosting ColorPicker uses to close its dropdown. The swatch draws only its cells; a hosting popup or window supplies any border.
Usage
import { ColorSwatch, signal } from '@jsvision/ui';
import type { Color } from '@jsvision/core';
const value = signal<Color>('cyan');
const swatch = new ColorSwatch({
value,
columns: 4,
onInput: (c) => preview(c), // live: every arrow / click / drag
onChange: (c) => commit(c), // commit: Enter / Space / mouse-up
});
swatch.setLayout({ position: 'absolute', rect: { x: 0, y: 0, width: 12, height: 4 } });Live example
Compare live palette movement with an explicit committed color using keyboard and mouse.
Props
new ColorSwatch(options).
The public surface is ColorSwatch, ColorSwatchOptions, the core Color type, and the default ANSI16_ORDER palette.
| Prop | Type | Default | Description |
|---|---|---|---|
value | Signal<Color> | — | Two-way selected color. |
colors | readonly Color[] | ANSI16_ORDER | Palette to display (the DOS-16 colors by default). |
columns | number | 4 | Columns per row. |
onInput | (c: Color) => void | — | Fired on every live change (arrow / click / drag). |
onChange | (c: Color) => void | — | Fired on the discrete commit (Enter / Space / mouse-up). |
nameFor | (c: Color) => string | — | Color-name accessor a hosting ColorPicker uses to caption its chip. |
Live selection and commit
| Input | Result |
|---|---|
| ← / → / ↑ / ↓ | Move the selection (wraps around the palette ends). |
| Enter / Space | Commit the current cell (fires onChange). |
| Click / drag | Select live (fires onInput); dragging outside reverts. |
| Mouse-up over a cell | Commit that cell (fires onChange). |
If value is an off-palette color (e.g. a custom hex from a hosting picker), no marker shows, but arrow navigation still works from an internal cursor. On a near-black cell the marker is drawn in a contrasting colour so it stays visible.
Palette geometry
Every palette entry occupies a three-cell block. columns controls wrapping and measure() reports the resulting width and row count, including a safe one-row minimum for an empty palette. An off-palette custom value keeps the grid usable: no marker is drawn, but the internal cursor provides a stable starting point for the next arrow movement.
Sizing & layout
Its measure() sizes it to columns × rows of 3-wide cells. The swatch has no frame — host it in a popup or window that supplies the border.
Best practices
- Split live vs. committed. Use
onInputfor a live preview (recolour as the cursor moves) andonChangefor the expensive commit — a drag fires manyonInputs and oneonChangeon release. - Default to the DOS-16 palette.
ANSI16_ORDERis the classic set; pass a customcolorsarray only when you need a specific palette.
Theming
Each cell draws its own color as the foreground over a black background. The ◘ marker uses the colorMarker role (black on lightGray) — forced onto a near-black cell so it stays visible.
Related
- Color picker — a one-line field that opens a swatch in a popup.
- API reference — the generated
ColorSwatchsignature.