Prototype Library

Color Picker

Form-associated color picker — native color input, hex text field, and an optional swatch grid. A Lit Web Component migrated from the Angular esa-color-picker.

Inherited wc import '@esa/ecology/esa-color-picker';

Preview

<esa-color-picker label="Brand color" value="#43608a"></esa-color-picker>

Swatches

Pass preset colors as a JSON-encoded swatches attribute (or an array property). The selected swatch is highlighted.

<esa-color-picker label="Pick a brand color" value="#43608a" swatches='["#43608a","#5787b9","#f9a134","#ef4444","#3b82f6","#22c55e"]'></esa-color-picker>

Name the swatches when they stand for something

An entry can be { value, label } instead of a bare hex. The label becomes the swatch tooltip and its accessible name, so it announces as Select color Danger #ef4444 rather than a hex nobody can picture. Reach for it whenever the presets are a palette the system already has words for — a brand ramp, the utility intentions, the Radix hues on the theme maker. A one-off set of arbitrary colours has no name to give, and a bare string is right there.

<esa-color-picker label="Pick an intention" value="#43608a" swatches='[{"value":"#43608a","label":"Brand"},{"value":"#f9a134","label":"Warning"},{"value":"#ef4444","label":"Danger"}]'></esa-color-picker>

Sizes

<esa-color-picker label="Extra small" size="xs" value="#43608a"></esa-color-picker>
<esa-color-picker label="Small" size="sm" value="#5787b9"></esa-color-picker>
<esa-color-picker label="Medium" size="md" value="#f9a134"></esa-color-picker>
<esa-color-picker label="Large" size="lg" value="#ef4444"></esa-color-picker>

States

Hide the hex input with show-input={false}; disable the whole control with disabled.

<esa-color-picker label="No hex input" value="#3b82f6" show-input="false" swatches="…"></esa-color-picker>
<esa-color-picker label="Disabled" value="#22c55e" disabled swatches="…"></esa-color-picker>

API

PropTypeDefaultDescription
label string '' Field label above the control.
size 'xs' | 'sm' | 'md' | 'lg' 'md' Control size (reflected attribute).
swatches ColorSwatch[] [] Preset colors, as a property or a JSON-encoded attribute. Each entry is a hex string, or an object carrying a name: { value, label }. A named swatch announces the name instead of the hex.
disabled boolean false Disables interaction (reflected attribute).
name string | undefined — Form field name — the key this control submits under.
show-input boolean true Show the hex text input next to the preview. Property: `showInput`. On by default. Write `="false"` to turn it off — unusually for a boolean attribute, this one reads the value.
value string '#000000' Current color as a hex string.

Events

EventTypeDefaultDescription
change CustomEvent<{ value: string }> — Fired when the color commits (native picker, valid hex input, or swatch click). Hex input validates #rgb / #rrggbb. Composed and bubbles.
Binding these events from Angular

Every one of these is a CustomEvent, so the payload is on $event.detail — $event.target.value reads empty, with no error. The names are lowercase and Angular passes them to addEventListener verbatim, so camel-casing one means it never fires.

  • (change)="onChange($event.detail)"

Accessibility

  • The native <input type="color"> provides the OS color dialog and keyboard handling.
  • Swatches are a role="listbox" group; each swatch is role="option" with aria-selected and an aria-label — "Select color {label} {hex}" when the entry carries a label, "Select color {hex}" when it is a bare string.
  • Hex input only commits valid #rgb / #rrggbb values, preventing invalid form state.
  • Form-associated via ElementInternals — value submits with the enclosing form.