Color Picker
Pick a color by dragging over saturation and brightness, sliding hue and opacity, typing a hex or pressing a swatch, in a field that opens a popover or inline.JSX
<ColorPicker aria-label="Playground color" defaultValue="#3b82f6" />
Installation
Package
CLI (copy source)
pnpm
pnpm add @advui/corenpm
npm install @advui/coreUsage
import { ColorPicker, Field } from '@advui/core'
<Field label="Brand color">
<ColorPicker value={color} onValueChange={setColor} />
</Field>
<ColorPicker inline alpha aria-label="Tint" value={tint} onValueChange={setTint} />Examples
Basic
A field in a Field: it shows the color and opens the picker in a popover.Preview
Code
Used for buttons and links.
Inline
The picker in the page. `onValueChange` follows the drag; `onValueCommit` fires once it ends.Preview
Code
Current: #10b981Saved: #10b981
Opacity
With `alpha`, an opacity slider, and a translucent color as `#rrggbbaa`.Preview
Code
Swatches
Named preset colors; the one that matches has a check mark.Preview
Code
API reference
ColorPicker
A field-shaped button that opens the picker in a popover, or the picker itself with `inline`. Style props go to the button, or to the inline picker.| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | The color, when you control it: hex (`#3b82f6`, `#3b82f680`), `rgb()` or `hsl()`. |
defaultValue | string | '#000000' | Starting `value` when uncontrolled. |
onValueChange | (value: string) => void | — | Called as the color changes, also while dragging, with a lowercase `#rrggbb`, or `#rrggbbaa` when `alpha` is on and the color is translucent. |
onValueCommit | (value: string) => void | — | Called once a drag ends, after a key or a swatch press, and when typed text is confirmed with Enter or by leaving the field. Save the color here. |
inline | boolean | false | Shows the picker in the page (256px wide, up to the container) instead of a field that opens it. |
alpha | boolean | false | Shows the opacity slider over a transparency grid, and lets the value be translucent. Without it, colors come back opaque. |
swatches | Array<string | { value: string; label: string }> | — | Preset colors below the picker. Give them names (`{ value, label }`) for screen readers; a plain string is read as the color. The swatch that matches the color shows a check mark. |
showInput | boolean | true | Shows the text field, which takes hex with or without `#`, `rgb()` or `hsl()`. A whole hex shows as it is typed; anything else on Enter or blur, and text that is not a color is undone. |
eyeDropper | boolean | true | Shows a button that picks a color from anywhere on the screen, in browsers with the EyeDropper API (Chrome, Edge). Others show no button.Web only. |
size | 'sm' | 'md' | 'lg' | 'md' | Height of the field, as with Input. Not used with `inline`. |
open | boolean | — | Whether the popover is open, when you control it. |
defaultOpen | boolean | false | Starting `open` when uncontrolled. |
onOpenChange | (open: boolean) => void | — | Called when the popover opens or closes. |
title | string | 'Choose a color' | Title of the popover, which names it for screen readers. |
labels | Partial<ColorPickerLabels> | — | Names and value texts to translate: `area`, `areaRole`, `areaValue(saturation, brightness)`, `saturate`, `desaturate`, `hue`, `hueValue(degrees)`, `alpha`, `input`, `eyeDropper` and `swatches`. |
disabled | boolean | false | Dims the picker and ignores drags, keys and presses. Also on inside a disabled Field or Form. |
invalid | boolean | false | Error border on the field, or on the text field when `inline`. On inside a Field with an `error`. |
name | string | — | Field name for a native form: the color submits under it.Web only. |
aria-label | string | — | Names the picker. Inside a Field, the field’s label names it instead. |
Accessibility
- The field is a button named by its Field label (or
aria-label) and described by the color (#3b82f6); it opens a dialog named bytitle. Inline, the picker is arole="group"named the same way. - The saturation and brightness area is one
role="slider"witharia-roledescription="2D slider"and a value text such as "Saturation 72%, brightness 40%". Left and right change the saturation, up and down the brightness. - Hue and opacity are sliders with value texts ("200°", "50%"). The text field is named "Hex color", and the swatches are toggle buttons (
aria-pressed) in a group named "Swatches".labelstranslates every name and value text. - Every color can be set without dragging: by keys, by typing it, or with a swatch. The picked swatch has a check mark, so it does not rely on color alone.
- Thumbs are a white ring outlined in black, so they show on light and dark colors alike.
- On iOS and Android the area and sliders are adjustable: swipes change the brightness, hue or opacity by 10, and the actions menu has "More saturated" and "Less saturated". Inline, each control reads the Field’s label and help as its hint. The sliders reach a 44pt touch target with
hitSlop.
| Key | Action |
|---|---|
| ArrowRight / ArrowLeft | Area: saturation ±1%. Sliders: ±1 (degree or percent). |
| ArrowUp / ArrowDown | Area: brightness ±1%. Sliders: ±1. |
| Shift + Arrow | Steps of 10. |
| PageUp / PageDown | Area: brightness ±10%. Sliders: ±10. |
| Home / End | Area: no or full saturation. Sliders: the start or the end. |
| Enter | Text field: applies the typed color. |
| Escape | Closes the popover. |
Platform notes
Web
Dragging uses pointer capture, so it continues outside the area, and
touch-action: none keeps a touch drag from scrolling the page. The eyedropper button shows only where window.EyeDropper exists. With name, a hidden input submits the color. Phones get a bottom sheet instead of the popover.iOS
The picker opens in a bottom sheet. Dragging on the area or a slider keeps the touch from the sheet and from scroll views. Gradients use React Native’s
experimental_backgroundImage (New Architecture) and the transparency grid react-native-svg.Android
Same as iOS. The back button closes the sheet.