Skip to content

Color Swatch Picker

Choose one or more colors from a list.

Anatomy

  • #item: Replace content inside each option. Receives item, option, color, value, label, isSelected, isHighlighted, isDisabled, and select.
  • #indicator: Custom selection indicator. Receives the same props as #item.
  • #empty: Content for an empty palette.

Usage

Single selection

Select a color. Screen readers can read each color's label.

Red
Orange
Yellow
Green
Blue
Indigo
Purple
#2a9d6f

Multiple selection and RTL

Toggle several colors, use Shift with navigation to extend selection, and skip disabled options.

Red
Orange
Yellow
Green
Blue
Indigo
Purple
Unavailable gray
[]

Custom item slot

Replace the option content. The wrapper still handles selection and focus.

Production
Staging
Incident

Examples

Single selection

Use #indicator to add a checkmark to the selected color. The labels remain available to screen readers.

vue
<Dialog
  :ui="{
    overlay: 'fixed inset-0 bg-black/50 backdrop-blur-sm',
    content: 'bg-white rounded-xl shadow-xl w-full max-w-md',
    header: 'flex items-center justify-between p-6 border-b',
    body: 'p-6',
    footer: 'flex justify-end gap-2 p-6 border-t',
  }"
>

Multiple selection and RTL

Toggle several colors, use Shift with navigation to extend selection, and skip disabled options.

vue
import './main.css'

Custom item slot

Replace the swatch, label, and indicator. The option wrapper still handles selection and focus.

vue
<template>
  <Accordion
    :items="items"
    type="multiple"
  />
</template>

See the live demo's code for the state and style objects used in these examples.

Formats

Set format to choose the returned color string. It does not change the palette. See supported formats. Changing the format keeps opacity and emits value-change with reason format.

HEX and RGB can lose colors outside sRGB. The picker keeps the original preset colors when you change format. CSS variables, currentColor, and relative color expressions are not supported. See precision and gamut for details.

Behavior

The picker uses Listbox for selection, keyboard navigation, and form submission. It compares colors by value, so red and #ff0000 match. Invalid colors are disabled. Duplicate colors can both appear selected; use unique colors if you need separate options.

Pass color strings or objects with { value: string; label?: string; disabled?: boolean }. Multiple selections submit one value per color under the same form name. The #item slot replaces the option content, not its wrapper.

API Reference

Props

PropTypeDefaultPurpose
modelValuestring | string[]""Use an array with multiple selection.
itemsArray<string | ColorSwatchOption>RequiredPreset colors and optional labels/disabled state.
formatColorFormat"hex"Format for selected color strings.
multiplebooleanfalseAllow multiple colors.
selectionBehavior"toggle" | "replace""toggle"How multiple selections accumulate.
orientation, dir"horizontal" | "vertical", "ltr" | "rtl""horizontal", "ltr"Keyboard direction.
loop, highlightOnHoverbooleantrueFocus wrapping and pointer highlighting.
id, name, ariaLabel, ariaLabelledby, ariaDescribedbystringFrom Field where applicableAssociation, form name, and accessible naming.
required, disabled, readOnly, invalidbooleanfalseForm and interaction state.
uiColorSwatchPickerUi-Classes for named parts.

Emits

EventPayloadMeaning
update:modelValueSelected color or color arrayVue model update.
value-change(value, details)Runs before a change. Use details.cancel() to stop it. Includes reason and the native event when available.
value-commit(value, details)Runs when an interaction ends. Canceling it does not undo the value change.

Slots

  • #item: Replace content inside each option. Receives item, option, color, value, label, isSelected, isHighlighted, isDisabled, and select.
  • #indicator: Custom selection indicator. Receives the same props as #item.
  • #empty: Content for an empty palette.

UI Options

KeyElement
rootOuter Listbox root
viewportFocusable Listbox viewport
contentOptions container
itemGenerated option
swatchDecorative color preview
labelAccessible color name
indicatorSelection indicator
inputForm input
emptyEmpty palette content

Styling Hooks

UI keyCSS classData attributes / semantics
rootakaza-color-swatch-pickerListbox form state; data-akaza-orientation
viewportakaza-color-swatch-picker-viewportrole="listbox"
contentakaza-color-swatch-picker-contentOptions wrapper
itemakaza-color-swatch-picker-item`data-akaza-state="checked
swatchakaza-color-swatch-picker-swatchColor Swatch empty state
labelakaza-color-swatch-picker-label-
indicatorakaza-color-swatch-picker-indicator`data-akaza-state="checked
inputakaza-color-swatch-picker-inputNative form attributes
emptyakaza-color-swatch-picker-empty-

The root exposes data-akaza-state="selected|empty". It also sets data-akaza-disabled, data-akaza-readonly, data-akaza-invalid, data-akaza-focused, and data-akaza-filled when true. Each item has its own selection and highlight attributes. The picker does not expose data-akaza-out-of-gamut.

Use class or ui.root to style the root. Use the other ui keys for inner parts. Set sizes, borders, and colors in your own styles.

Keyboard

KeyBehavior
Orientation arrow keysMove the highlighted option, respecting RTL, wrapping, and disabled entries.
Home / EndHighlight first/last enabled option.
Enter / SpaceSelect/toggle the highlighted color.
Shift+navigationExtend selection in multiple mode.
Ctrl/Cmd+ASelect all enabled colors in multiple mode.
Character keysTypeahead by option label.

Parity Notes

Like Reka's color swatch picker, this component supports single and multiple selection, keyboard navigation, RTL, and disabled options. Customize its items through slots. The supplied Base UI reference has no color swatch picker component.

Edit this page on GitHub ↗