Color Picker

A composable color picker component supporting multiple color models, alpha channel, and customizable UI.
1<ColorPicker
2 defaultValue="#DA2929"
3 style={{
4 width: "240px",
5 height: "320px",
6 padding: 12,
7 background: "white",
8 }}
9>
10 <ColorPicker.Area />
11 <ColorPicker.Hue />
12 <ColorPicker.Alpha />
13 <Flex direction="row" gap={2}>
14 <ColorPicker.Mode />
15 <ColorPicker.Input copyable />

Anatomy

Import and assemble the component:

1import { ColorPicker } from '@raystack/apsara'
2
3<ColorPicker>
4 <ColorPicker.Area />
5 <ColorPicker.Hue />
6 <ColorPicker.Alpha />
7 <ColorPicker.Mode />
8 <ColorPicker.Input copyable />
9</ColorPicker>

API Reference

Root

The ColorPicker is composed of several subcomponents, each responsible for a specific aspect of color selection. The root component acts as a data provider for its children.

Prop

Type

Area

Enables users to select a color from a 2D palette. The surface adapts to the active mode: in hex, rgb, and hsl modes it renders the classic saturation × brightness gradient square; in oklch mode it renders a chroma × lightness plane covering the full P3 gamut.

Hue

Provides a slider for selecting the hue value of the color.

Alpha

Provides a slider for selecting the alpha value of the color.

Mode

Lets users switch between different color models (HEX, RGB, HSL, OKLCH) via a dropdown menu.

Prop

Type

Input

Displays the current color value in the selected color model as a read-only string. The value is updated automatically as the user interacts with the area, hue, or alpha controls. Pass copyable to render a copy-to-clipboard button in the input's trailing slot.

Examples

Basic Usage

1<ColorPicker
2 defaultValue="#00bcd4"
3 style={{
4 width: "240px",
5 height: "220px",
6 padding: 12,
7 background: "white",
8 }}
9>
10 <ColorPicker.Area />
11 <ColorPicker.Hue />
12</ColorPicker>

Copy to Clipboard

Pass the copyable prop on ColorPicker.Input to render a copy-to-clipboard button in the input's trailing slot. The button copies the formatted color string in the active mode (e.g. #FF0000, rgb(...), or oklch(...)) and shows a brief confirmation icon after a successful copy.

1<ColorPicker
2 defaultValue="#5B8DEF"
3 style={{
4 width: "240px",
5 height: "300px",
6 padding: 12,
7 background: "white",
8 }}
9>
10 <ColorPicker.Area />
11 <ColorPicker.Hue />
12 <Flex direction="row" gap={2}>
13 <ColorPicker.Mode />
14 <ColorPicker.Input copyable />
15 </Flex>

OKLCH Mode

The picker stores color internally in OKLCH. In hex, rgb, and hsl modes the area pad is the familiar HSL saturation × brightness square and the hue slider runs in HSL hue — so the picker behaves like a traditional color picker and only emits colors representable in the chosen format. Pass an oklch(...) string as defaultValue and set defaultMode='oklch' to switch to a chroma × lightness plane covering the full P3 gamut; the hue slider then runs in OKLCH hue, where equal steps correspond to equal perceptual changes.

1<ColorPicker
2 defaultValue="oklch(0.5438 0.191 267.01)"
3 defaultMode="oklch"
4 style={{
5 width: "240px",
6 height: "320px",
7 padding: 12,
8 background: "white",
9 }}
10>
11 <ColorPicker.Area />
12 <ColorPicker.Hue />
13 <ColorPicker.Alpha />
14 <Flex direction="row" gap={2}>
15 <ColorPicker.Mode />

Popover Integration

The ColorPicker can be embedded within a Popover component to create a more interactive and space-efficient color selection experience.

1(function PopoverColorPicker() {
2 const [color, setColor] = useState("#DA2929");
3
4 return (
5 <Popover>
6 <Popover.Trigger
7 render={
8 <Button
9 style={{
10 width: 60,
11 height: 60,
12 background: color,
13 }}
14 />
15 }

Utilities

formatColor

Converts any CSS color string to the requested format. Useful when consuming apsara color tokens (which are authored in OKLCH) from APIs that need a specific format — chart libraries, SVG attributes, canvas fills, design exports, and similar.

1import { formatColor } from '@raystack/apsara'
2
3formatColor('oklch(0.5438 0.191 267.01)', 'hex') // '#3E63DD'
4formatColor('oklch(0.7 0.32 30)', 'hex') // '#FF5843' (gamut-mapped)
5formatColor('red', 'rgb') // 'rgb(255, 0, 0)'
6formatColor('rgba(255, 0, 0, 0.5)', 'hsl') // 'hsla(0, 100%, 50%, 0.5)'
7formatColor('#FF0000', 'oklch') // 'oklch(0.6279 0.2577 29.23)'
8formatColor('not a color', 'hex') // null

Behavior

  • Accepts any CSS color string: oklch(), rgb()/rgba(), hsl()/hsla(), hex, named colors, transparent.
  • For hex, rgb, and hsl outputs, wide-gamut OKLCH inputs are gamut-mapped into sRGB by reducing chroma while preserving lightness and hue, so the returned string is the closest sRGB representation rather than a per-channel-clipped one (which would distort hue).
  • For oklch output, the full color is preserved — OKLCH can express the wide gamut natively. Output matches the design system's token format (4-decimal L/C, 2-decimal H, hue pinned to 0 when achromatic).
  • Hex is uppercase; uses 8-digit form (#rrggbbaa) when alpha < 1. Translucent rgb/hsl/oklch produce rgba() / hsla() / oklch(... / A).
  • Returns null for unparseable input rather than throwing — safe to call on user-supplied strings.

Signature

1function formatColor(
2 value: string,
3 format: 'hex' | 'rgb' | 'hsl' | 'oklch'
4): string | null

Accessibility

  • Provides aria-label attributes for color areas and sliders
  • Supports keyboard navigation for hue, saturation, and alpha controls
  • Color values are announced to screen readers on change