Color Picker
A real <input type="color">. Its native swatch can't be restyled consistently across browsers, so a decorative swatch sits visually on top while the real, focusable input stays underneath atopacity: 0, never hidden. Both live inside one real<label>, so clicking anywhere opens the OS picker with no click-forwarding JavaScript. The hex field beside it is a second view onto the same value, not a second source of truth — it only ever commits back through the color input's own value. Alpha isn't supported, the same as the underlying native element.
Playground
Toggle every adjustable prop and watch the component — and the code — update live.
Used across buttons and links.
showHexInput
size
invalid
hide label
label offset
Usage
<ColorPicker label="Accent color" defaultValue="#f59e0b" description="Used across buttons and links." errorMessage="Choose a valid color." /><kernel-color-picker label="Accent color" value="#f59e0b" description="Used across buttons and links." error-message="Choose a valid color."></kernel-color-picker>Props
| Prop | Type | Default |
|---|---|---|
label | ReactNode (required) | — |
hideLabel | boolean | false |
value | string | — |
defaultValue | string | "#000000" |
showHexInput | boolean | true |
description | ReactNode | — |
errorMessage | ReactNode | — |
invalid | boolean | false |
size | "sm" | "md" | "lg" | "md" |
Accessibility
- The decorative swatch is
aria-hiddenandpointer-events: none— it never intercepts a click or duplicates the accessible name. - The hex field has its own
aria-labelsince it's a secondary control for the same value; the visible label points at the color input. - Invalid hex entry is communicated via
aria-invalidon the hex field alone — it's a self-correcting draft, not a submitted validation error.