Color Picker
A composable color picker component supporting multiple color models, alpha channel, and customizable UI.
1<ColorPicker2 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'23<ColorPicker>4 <ColorPicker.Area />5 <ColorPicker.Hue />6 <ColorPicker.Alpha />7 <ColorPicker.Mode />8 <ColorPicker.Input copyable />9</ColorPicker>
Usage
The picker is composed from an area pad, sliders and an input, so you can drop in the whole thing or keep only the parts you need.
Basic usage
An uncontrolled picker. Pass defaultValue for the starting color and read changes from onValueChange.
1<ColorPicker2 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<ColorPicker2 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. What the controls show depends on the mode:
hex,rgb,hsl— the area pad is the familiar HSL saturation × brightness square and the hue slider runs in HSL hue. The picker behaves like a traditional color picker and only emits colors the chosen format can represent.oklch— the pad becomes a chroma × lightness plane covering the full P3 gamut, and the hue slider runs in OKLCH hue, where equal steps are equal perceptual changes.
To start in OKLCH, pass an oklch(...) string as defaultValue and set defaultMode='oklch'.
1<ColorPicker2 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");34 return (5 <Popover>6 <Popover.Trigger7 render={8 <Button9 style={{10 width: 60,11 height: 60,12 background: color,13 }}14 />15 }
API Reference
The pad and sliders compose inside a root. formatColor turns a value into a string yourself.
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.
Slots
Every rendered part carries a stable data-slot attribute for styling and testing:
| Slot | Element |
|---|---|
color-picker | The root container (Flex column) |
color-picker-area | The 2D color area (saturation/lightness or chroma/lightness plane) |
color-picker-area-canvas | The <canvas> painting the color plane (when in oklch mode) |
color-picker-area-thumb | The draggable thumb in the color area |
color-picker-hue | The hue slider root |
color-picker-alpha | The alpha slider root |
color-picker-alpha-gradient | The gradient overlay <div> behind the alpha track |
color-picker-slider-control | The slider control (shared by hue and alpha) |
color-picker-slider-track | The slider track (shared by hue and alpha) |
color-picker-slider-range | The filled range indicator inside the track (shared by hue and alpha) |
color-picker-slider-thumb | The slider thumb (shared by hue and alpha) |
color-picker-input | The read-only color value input |
color-picker-mode | The mode select trigger |
color-picker-mode-content | The mode select dropdown content (when open) |
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'23formatColor('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, andhsloutputs, 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
oklchoutput, 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 producergba()/hsla()/oklch(... / A). - Returns
nullfor 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-labelattributes for color areas and sliders - Supports keyboard navigation for hue, saturation, and alpha controls
- Color values are announced to screen readers on change