/ component

Color Picker

Oklch Lร—C pad, hue + alpha strips, 6-mode round-trip (oklch, oklab, hex, rgb, hsl, hwb). Three usage tiers from casual to strict.

/ auto-mode

Basic Usage

Mode unset โ†’ switcher visible โ†’ onChange emits whichever mode the user last selected.

oklch(0.628 0.258 29.234)
/ mode-locked

Mode-Locked

Setting mode hides the switcher and locks onChange to that format.

โ†’ oklch
oklch(0.628 0.258 29.234)
โ†’ oklab
oklab(0.628 0.225 0.126)
โ†’ hex
#ff0000
โ†’ rgb
rgb(255 0 0)
โ†’ hsl
hsl(0 100% 50%)
โ†’ hwb
hwb(0 0% 0%)
/ presets

Custom Presets

Pass presets as an array of color values or CSS variables like var(--color-primary). Var swatches display the resolved theme token and emit a concrete color on click. Omit the prop for the built-in palette; pass [] for none.

oklch(0.85 0.15 290)
/ recents

Recents (controlled)

Pass history + onHistoryChange to control the recents row โ€” a color commits once when the popover closes, deduped, most-recent first, capped at 8. Drop both props (or seed with defaultHistory) for the uncontrolled variant.

oklch(0.628 0.258 29.234)
history[2]:oklch(0.85 0.15 290)#22c55e
/ native

Native Variant

Falls back to the browser's <input type="color">. sRGB-only, no alpha โ€” wide-gamut and transparent values lose information on edit.

#ff0000
/ api

API

Public surface โ€” component props, runtime helpers, and the type exports.

ยง Component

<ColorPicker<TMode extends ColorMode | undefined>
  value: ColorString | (string & {})
  onChange: (next: ColorValue<TMode>) => void
  mode?: TMode
  presets?: ReadonlyArray<ColorString | (string & {})>
  history?: ReadonlyArray<ColorValue<TMode>>
  defaultHistory?: ReadonlyArray<ColorValue<TMode>>
  onHistoryChange?: (history: ColorValue<TMode>[]) => void
  native?: boolean
  className?: string
  aria-label?: string
/>
PropTypeDescription
valueColorString | (string & {})Current color. Any string accepted; IntelliSense suggests literal shapes.
onChange(next) => voidEmits next color. Return type discriminated by `mode` prop.
modeColorMode | undefinedLock output format. When unset, in-picker mode switcher is shown.
presetsReadonlyArray<ColorString | (string & {})>Preset swatches: color values or CSS vars (var(--token)). undefined = built-in palette; [] = none. Vars display resolved and emit a concrete color on click.
historyReadonlyArray<ColorValue<TMode>>Controlled recents. Element type mirrors onChange. Pair with onHistoryChange.
defaultHistoryReadonlyArray<ColorValue<TMode>>Uncontrolled initial recents. Ignored when history is provided.
onHistoryChange(history: ColorValue<TMode>[]) => voidFires when recents change โ€” a color commits on popover close (deduped, capped at 8).
nativebooleanRender the browser's <input type="color"> instead of the popover.
classNamestringApplied to the trigger swatch (popover) or wrapper (native).
aria-labelstringTrigger label. Defaults to "Pick a color".

ยง Runtime helpers

color<S extends string>(value: S & ColorLiteral<S>): S

Validate a color literal at the call site. Range violations type-error.

isColorString(value: string): value is ColorString
isColorString<S extends string>(value: S): value is S & ColorLiteral<S>

Runtime type guard. Narrows wide strings to ColorString; narrows a literal S to S & ColorLiteral<S>.

ยง Types

ColorString
Union of all suggestion-string literal types. Used as the IntelliSense surface and the default `onChange` return type.
ColorStringMap
{ hex: HexString, rgb: RgbString, hsl: HslString, oklch: OklchString, oklab: OklabString, hwb: HwbString }
ColorMode
"oklch" | "oklab" | "hex" | "rgb" | "hsl" | "hwb"
ColorValue<TMode>
TMode extends ColorMode ? ColorStringMap[TMode] : ColorString. The onChange payload type and the recents (history) element type.
ColorLiteral<S>
Strict template-literal validator. Range-checks every token (bytes 0โ€“255, percents 0โ€“100%, hue 0โ€“360deg, etc.). Returns `S` if valid, `never` otherwise.
ModeOf<S>
Extract the mode tag from a color literal. ModeOf<"#ff0000"> = "hex".
WithAlpha<S, A>
Add or replace the alpha tag on a functional-notation color literal. WithAlpha<"rgb(255 0 0)", 50> = "rgb(255 0 0 / 50%)".
WithoutAlpha<S>
Strip the alpha tag from a functional-notation color literal.
/ install

Drop it in

One command. Resolves button + popover against the shadcn-ui registry automatically.

$ pnpm dlx shadcn@latest add https://ridiculous.turtlesocks.dev/r/color-picker.json