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.

When to use

  • Choosing any color: a brand color, a label color, a theme setting.
  • A free choice with a few suggested colors, with swatches.

Do

  • Set format to the notation people work with: hex, RGB or HSL.

When not to use

  • Only colors from an approved set are valid: hy-swatch-group.
  • Tuning one channel such as hue or lightness: hy-color-slider.
  • A color that must stay opaque: leave alpha off.

Accessibility: your part ​

  • Set label to the thing being colored. The default "Color" names nothing. Where the words around it already say so (a row named "Stop 1"), hide the label with label="" and name the picker with aria-label / aria-labelledby on the host; a host name wins over label.
  • When the picked color will sit behind or beside text, show its contrast next to the picker, or limit the choice with hy-swatch-group.

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>

Helper text, warning and error ​

html
<hy-color-picker label="Accent" helper-text="Used for links and focus"></hy-color-picker>
<hy-color-picker
  label="Accent"
  value="#f8e71c"
  warning-message="Low contrast on white"
></hy-color-picker>
<hy-color-picker
  label="Accent"
  value="#ffffff"
  error-message="Pick a color other than white"
></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 normalizes 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.
strings—Partial<ColorPickerStrings>{}The built-in strings, merged over DEFAULT_COLOR_PICKER_STRINGS — set only the keys you translate. Use for internationalization.
helperTexthelper-textstring''Helper text shown below the trigger. Replaced by the error or warning message while one shows.
errorMessageerror-messagestring''Error message shown below the trigger (replaces the helper text). Setting it raises error.
errorerrorbooleanfalseError state: the color is not accepted and has to change. Paints the trigger border in the danger color and sets aria-invalid.
warningMessagewarning-messagestring''Warning message shown below the trigger (replaces the helper text). Setting it raises warning.
warningwarningbooleanfalseWarning state: the color is accepted but worth a second look. Paints the warning color and shows warning-message; never sets aria-invalid and never touches form validity. error wins when both are set.
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 | undefined—Width 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.
form—HTMLFormElement | null——
validity—ValidityState——

Events ​

EventDetailDescription
input—Fires continuously while the user drags a slider or area.
change—Fires 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 in the error state
warning-messageWarning message below the trigger in the warning state
message-iconThe icon starting the error or warning message

CSS Custom Properties ​

The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.

PropertyDefaultDescription
--hy-color-picker-icon-size-mdvar(--hy-icon-size-md)Visual swatch edge length inside the trigger.
--hy-color-picker-icon-size-smvar(--hy-icon-size-sm)Visual swatch edge length inside the trigger.
--hy-color-picker-icon-size-lgvar(--hy-icon-size-lg)Visual swatch edge length inside the trigger. Independent of the outer trigger height — the swatch sits inside with padding around it. (sm/lg variants follow icon-size-sm/lg)
--hy-color-picker-radius-form-mdvar(--hy-radius-form-md)Corner radius of the trigger
--hy-color-picker-radius-overlay-floating-mdvar(--hy-radius-overlay-floating-md)Corner radius of the 2D area
--hy-color-picker-area-height—2D area height
--hy-color-picker-area-width—2D area width / minimum surface width
--hy-color-picker-track-height—Slider track height
--hy-color-picker-thumb-size—Thumb diameter
--hy-color-picker-field-height—Hex input / format select height
--hy-color-picker-gap-form-mdvar(--hy-gap-form-md)Vertical gap between sections
--hy-color-picker-label-column-width—Width of the label column in layout="inline" mode. No default — set on a wrapping container so stacked pickers align.
--hy-color-picker-control-height-smvar(--hy-control-height-sm)Outer trigger height for small size variant. Per-component override in the form-control height contract.
--hy-color-picker-control-height-mdvar(--hy-control-height-md)Outer trigger height for medium size variant.
--hy-color-picker-control-height-lgvar(--hy-control-height-lg)Outer trigger height for large size variant.
--hy-color-picker-motion-transition-hover-durationvar(--hy-motion-transition-hover-duration)Transition duration for hover and focus state feedback
--hy-color-picker-motion-transition-hover-easingvar(--hy-motion-transition-hover-easing)Transition easing for hover and focus state feedback
--hy-color-picker-foreground-warning-restvar(--hy-foreground-warning-rest)Warning message text and icon color, and the trigger border in the warning state.
--hy-color-picker-foreground-icon-default-disabledvar(--hy-foreground-icon-default-disabled)The message line's icon color when the picker is disabled
--hy-color-picker-gap-layout-2xsvar(--hy-gap-layout-2xs)Gap between the message icon and its text
--hy-color-picker-swatch-columns—Number of columns in the swatch grid (8 unless set)

Built with Lit. Documented with VitePress.