Color Picker
Choose a color with an interactive picker, text input, or preset swatches.
ColorPicker provides a trigger and popup for choosing a color. Users can adjust saturation and brightness, set hue and opacity, enter a CSS color value, or choose from preset swatches.
Import
import { ColorPicker } from "@puzzle-ui/ui";Basic usage
Provide a visible label and optionally an initial defaultValue. Add preset colors with colors; a swatch can be a color string or an object with a value and optional accessible label.
Preset swatches
Use labeled swatch objects when the color value alone is not a useful accessible name. CSS color values such as variables can also be used as swatches; the picker returns the original value when a swatch is selected.
Controlled value and format
Use value with onChange when the parent owns the selected color; otherwise, use defaultValue for an uncontrolled picker. The callback receives the color string, or undefined when the color is cleared.
format determines the string produced when users adjust the picker controls. It supports "hex", "hexa", "rgb", and "hsl"; the default is "hexa". Selecting a swatch or applying a valid text value preserves that input string rather than converting it to the selected format.
import { useState } from "react";
const ColorSetting = () => {
const [color, setColor] = useState<string | undefined>("#6750a4");
return (
<ColorPicker
label="Accent color"
value={color}
onChange={setColor}
format="hex"
/>
);
};Clearing and disabled state
The picker is clearable by default. Set clearable={false} to remove the clear action; customize its accessible name with clearLabel. Clearing calls onChange with undefined. Set disabled to prevent opening the picker.
Popup placement
position selects the preferred side of the trigger (top, right, bottom, or left); align selects start, center, or end alignment. The popup closes when users press Escape or click outside. Use open with onOpenChange to control popup visibility, or defaultOpen for its initial state.
API
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | - | Visible label and accessible name for the trigger and popup. |
description | ReactNode | - | Supporting text associated with the trigger. |
value | string | undefined | - | Controlled color value. Pass undefined to represent no selection. |
defaultValue | string | - | Initial color for an uncontrolled picker. |
onChange | (value: string | undefined) => void | - | Called when a color is chosen, adjusted, applied, or cleared. |
placeholder | string | "Select color" | Trigger text when no color is selected. |
colors | readonly ColorPickerSwatch[] | [] | Preset strings or { value, label? } swatches. |
format | "hex" | "hexa" | "rgb" | "hsl" | "hexa" | Output format for colors adjusted with the picker controls. |
clearable | boolean | true | Whether to show the clear-color action. |
clearLabel | string | "Clear color" | Accessible name for the clear action. |
disabled | boolean | false | Disables the trigger. |
open | boolean | - | Controlled popup visibility. |
defaultOpen | boolean | false | Initial popup visibility when uncontrolled. |
onOpenChange | (open: boolean) => void | - | Called when popup visibility changes. |
position | "top" | "right" | "bottom" | "left" | "bottom" | Preferred popup side. |
align | "start" | "center" | "end" | "start" | Popup alignment relative to the trigger. |
className, style | Native button props | - | Applied to the trigger button. |
rootClassName | string | - | Additional class for the root wrapper. |
popoverClassName | string | - | Additional class for the popup container. |
Other native button attributes, including id, name, and aria-*, are forwarded to the trigger.
Accessibility
- Always provide a
label; without one, the trigger uses the generic accessible name “Choose color.” - Preset swatches are buttons with accessible names and pressed states. Give swatches a descriptive
labelwhen the raw color value is not meaningful. - The saturation/brightness area supports arrow keys; hold Shift to adjust in larger increments. Hue and opacity use native range inputs and support their standard keyboard controls.
- Use Escape to close the popup; clicking outside also closes it.