Skip to content

HyColorPicker

Usage examples on this page are written for Lit / plain HTML (<hy-color-picker>). The same component ships as HyColorPicker in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

A color picker: trigger swatch + popover-hosted HSV selection UI with optional alpha, optional preset swatches, and multi-format readout.

State model

The canonical value is the value prop — a hex string (#RRGGBB, or #RRGGBBAA when alpha is enabled). Internally the component tracks HSV + alpha so that dragging saturation or value to zero does not lose the current hue (a pure RGB round-trip would).

Hex casing — display vs value

Hex is shown uppercase in both readouts (the trigger and the hex field), matching the design-tool convention (Figma, Sketch, Adobe) for digit-heavy color strings. value, the input / change detail, and the form value stay lowercase — the canonical form the CSS / token pipeline emits. Hex is case-insensitive in CSS, so the two never disagree in meaning. Input accepts either case, and the field is left exactly as typed while editing (rewriting mid-keystroke would fight the caret), settling to uppercase on commit. Assert on value case-insensitively.

Interaction

  • 2D area: pointer-drag in HSV saturation (x) × value (y). Arrow keys move by 1 / 0.01 steps; Shift increases to 10 / 0.1.
  • Hue slider: rainbow track, 0–360°. Arrow keys step by 1° (Shift by 10°).
  • Alpha slider (opt-in): transparent → opaque track over a checker background.
  • Hex input: accepts short (#abc), long (#aabbcc), or alpha hex. Commits on Enter / blur. Invalid entries revert.
  • Swatches: grid of preset colors below the readout. Click applies.

input fires on every interaction (drag, keystroke); change fires on commit (pointer release, Enter, blur, swatch click, popover close with a changed value). Parents that only need the committed value can ignore input.

Examples

Basic

html
<hy-color-picker value="#3b82f6"></hy-color-picker>

With alpha + swatches

html
<hy-color-picker
  value="#3b82f6"
  alpha
  swatches="#d0021b;#f5a623;#f8e71c;#7ed321;#4a90e2;#bd10e0;#000;#fff"
></hy-color-picker>

API

Properties

PropertyAttributeTypeDefaultDescription
valuevaluestring'#000000'Current color, as a hex string. Accepts #RGB, #RGBA, #RRGGBB, or #RRGGBBAA, in either case. The component normalises invalid values back to the previous valid value.
formatformat'hex' | 'rgb' | 'hsl' | 'hsv''hex'Display format for the readout and emitted hsv/rgb/hsl strings. Does NOT change value.
withoutFormatTogglewithout-format-togglebooleanfalseHide the format toggle dropdown even when more than one format is useful.
alphaalphabooleanfalseShow the alpha slider and encode alpha in the hex / format readout.
swatchesswatchesstring[][]Preset colors shown in a grid below the readout. Accepts either an array of color strings (property-only) or a ;-separated string (attribute).
disableddisabledbooleanfalseDisables all interaction.
sizesize'small' | 'medium' | 'large''medium'Size variant (affects trigger + 2D area).
labellabelstring'Color'Accessible label applied to the trigger and the popover surface. When set, also renders as a visible label above or beside the trigger.
helpTexthelp-textstring''Helper text shown below the trigger. Hidden when errorMessage is shown.
errorMessageerror-messagestring''Error message shown below the trigger when invalid.
invalidinvalidbooleanfalseVisually marks the control as invalid.
layoutlayout'block' | 'inline''block'Row layout: block (default) stacks label above the trigger; inline puts label on the left and trigger on the right. Helper/error always sits under the trigger (col 2–end), never under the label. Set --hy-color-picker-label-column-width on a wrapping container so stacked pickers align.
widthwidthstring | undefinedWidth of the color-field. Accepts any valid CSS width value (e.g. '400px', '100%', '20rem'). The host fills its container by default; set width to constrain the trigger. Mirrors hy-text-input.
placementplacement'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end''bottom-start'Popover placement — forwarded to hy-popover.
namenamestring''Form field name.
openopenbooleanfalseBound open state of the popover.
autofocusautofocusbooleanfalseMarks this color picker as the auto-focus target. Read by hy-dialog (and other overlay containers) on show to choose initial focus. The trigger button receives focus. Also focuses on first connect when used outside an overlay, mirroring native HTML autofocus but routed through JS so SSR'd HTML doesn't pull focus during hydration.
formHTMLFormElement | null
validityValidityState

Events

EventDetailDescription
inputFires continuously while the user drags a slider or area.
changeFires once the value is committed.

CSS Parts

PartDescription
baseOuter wrapper containing label, trigger, and helper/error text
labelThe visible label element
triggerThe default trigger button
trigger-swatchThe color swatch inside the trigger
trigger-readoutThe hex readout inside the trigger (uppercase; value stays lowercase)
surfaceThe popover surface containing the controls
areaThe 2D saturation × value area
area-thumbThe thumb inside the 2D area
slider-hueThe hue slider track
slider-alphaThe alpha slider track
readoutThe row with hex input + format select
readout-fieldThe hex text input (settles to uppercase; accepts either case)
swatchesThe preset swatches grid
swatchA single swatch button
helper-textHelper text below the trigger
error-messageError message below the trigger when invalid

CSS Custom Properties

PropertyDescription
--hy-color-picker-swatch-sizeVisual swatch edge length inside the trigger. Independent of the outer trigger height — the swatch sits inside with padding around it. Default: var(--hy-icon-size-md) (sm/lg variants follow icon-size-sm/lg)
--hy-color-picker-trigger-radiusCorner radius of the trigger
--hy-color-picker-surface-radiusCorner radius of the 2D area
--hy-color-picker-area-height2D area height
--hy-color-picker-area-width2D area width / minimum surface width
--hy-color-picker-track-heightSlider track height
--hy-color-picker-thumb-sizeThumb diameter
--hy-color-picker-field-heightHex input / format select height
--hy-color-picker-gapVertical gap between sections
--hy-color-picker-label-column-widthWidth of the label column in layout="inline" mode. No default — set on a wrapping container so stacked pickers align.
--hy-color-picker-height-smOuter trigger height for small size variant. Per-component override in the form-control height contract (see .claude/rules/control-heights.md). Default: var(--hy-control-height-sm)
--hy-color-picker-height-mdOuter trigger height for medium size variant. Default: var(--hy-control-height-md)
--hy-color-picker-height-lgOuter trigger height for large size variant. Default: var(--hy-control-height-lg)
--hy-color-picker-hover-durationTransition duration for hover and focus state feedback
--hy-color-picker-hover-easingTransition easing for hover and focus state feedback

Built with Lit. Documented with VitePress.