Color Picker

Pick a color from a panel, in the format an app asks for, with an optional opacity slider and preset swatches.

import { ColorPicker } from "@hel/ui/color-picker"

export function ColorPickerDemo() {

When to use it

Use the color picker when someone needs to choose a color that is not from a short fixed list: a brand color, a label color, a chart series. It gives them a square for saturation and brightness, a hue slider, typed fields in the format they know, and a row of presets for the common cases.

If there are only a handful of allowed colors, show them as swatches people click, and skip the panel.

Import

import { ColorPicker, ColorPanel } from "@hel/ui/color-picker"
import { ColorSwatch } from "@hel/ui/color-swatch"

ColorPicker is a button or field that opens the panel in a popover. ColorPanel is the same panel drawn inline, for a settings page where it is always visible.

Examples

As a field

variant="field" swaps the button for a field with the swatch in front and the value typed in it, which suits forms. Turn on alpha to add the opacity slider and an opacity field, and the value gets an alpha part, like #1a73e880.

Banner overlay

50%
import { ColorPicker } from "@hel/ui/color-picker"
import { Stack } from "@hel/ui/stack"
import { Text } from "@hel/ui/text"

Always visible

ColorPanel has no trigger, so it takes the same props but sits right in the page. formats lists the formats people can switch between and defaultFormat picks the first one: hex, rgb, hsl, hwb, lab, lch, oklab and oklch are available.

import { ColorPanel } from "@hel/ui/color-picker"

export function ColorPickerPanel() {

Controlled

Pass value and onValueChange when the color is used elsewhere on the page. The value comes back written in the current format, so it may be hex text one moment and an rgb(...) string the next. Anything that reads it should accept any CSS color.

readableTextColor from @hel/ui/color answers the next question, which is whether text on that color should be black or white. The badge below uses it, so the label stays readable whatever color is picked.

Paid

#22c55e

import * as React from "react"

import { Badge } from "@hel/ui/badge"

Swatch

ColorSwatch shows a color as a small square or circle, in four sizes. Transparent colors show a checkerboard behind them. A swatch is decoration by default. Give it a label when the color carries meaning on its own, and prefer putting the meaning in text next to it, since color alone is not enough for everyone.

import { ColorSwatch } from "@hel/ui/color-swatch"
import { Flex } from "@hel/ui/flex"

For a row of colors people choose between, use ColorSwatchButton. It takes selected for the chosen one and requires an aria-label as its name.

Settings in your config

The defaults for format, formats, alpha and the preset swatches come from the color section of your Hel config, so every picker in the app agrees. Set them on a single picker to override. An empty swatches list hides the row. Text for screen readers is English only in the package. Add other languages under messages in the config, with the key colorPicker, or pass messages to one picker.

States

disabled turns the picker off, and invalid draws the error ring. A picker inside a form can carry its value in a hidden input if you give it a name.

Props

ColorPicker

PropTypeDefault
variant"button" | "field""button"
valueCSS color textnone
defaultValueCSS color text"#000000"
onValueChange(value: string) => voidnone
format / defaultFormat"hex" | "rgb" | "hsl" | "hwb" | "lab" | "lch" | "oklab" | "oklch"from the config
formatsThe formats people can switch betweenfrom the config
alphabooleanfrom the config
swatchesstring[], any CSS colorsfrom the config
disabledbooleanfalse
invalidbooleanfalse
namestring, for a hidden form inputnone
open / onOpenChangeboolean / (open: boolean) => voidnone
localestringthe config's locale
messagesPartial<ColorPickerMessages>English

Give every picker an aria-label or aria-labelledby, since the button has no text of its own to name it.

ColorPanel takes the same props, apart from variant, open and the aria labels.

ColorSwatch

PropTypeDefault
colorAny CSS colorrequired
size"sm" | "md" | "lg" | "xl""sm"
shape"square" | "round""square"
labelstring, read by screen readersnone