Skip to content
WANCRAFT

F.84Forms & Inputs

Color Picker

An accessible colour picker: 2D saturation area, hue and alpha sliders, validated hex / RGB / HSL input, swatches and eyedropper.

NewReactCSSTailwindadvanced

Overview

Color Picker covers the whole job without a dependency. A saturation / brightness area works as a 2D slider: arrows move both axes and screen readers hear “Saturation 60%, brightness 80%”. Hue and optional opacity sliders sit beside a live preview chip, and a text field accepts hex, RGB or HSL with inline validation. Swatches give one-click presets, and where the browser offers the EyeDropper API a button samples any pixel on screen. Colour is stored as HSVA so the hue survives greys and black, drags are batched to one update per frame, and the value stays a plain hex string you can control.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/color-picker.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/color-picker.json

Method 02 · Copy and paste

  1. 1. No extra dependencies — React and Tailwind CSS only.
  2. 2. Copy the source from the Code tab into components/ui/color-picker.tsx.
  3. 3. Import it and adjust props.
Dependencies
None
Peer
react ≥ 18, tailwindcss ≥ 4
Added
13 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { ColorPicker } from "@/components/ui/color-picker";

export function ColorPickerExample() {
  return (
    <ColorPicker
      defaultValue="#FF7448"
      onValueChange={(hex) => console.log(hex)}
    />
  );
}

03Props

PropTypeDefaultDescription
value / defaultValuestring— / "#FF7448"Controlled colour, or the initial colour. Hex, rgb() and hsl() strings are accepted.
onValueChange(hex: string) => void—Called with "#RRGGBB" ("#RRGGBBAA" when alpha < 1) on every change.
onValueCommit(hex: string) => void—Called when a drag ends and after keyboard, text, swatch or eyedropper changes.
labelstring"Colour"Accessible name of the group and prefix for each part's name.
alphabooleanfalseShow the opacity slider and allow 8-digit hex.
format"hex" | "rgb" | "hsl""hex"Initial format of the text field; users can switch it.
showInputbooleantrueShow the text field and its format switcher.
swatchesstring[]8 presetsPreset colours; pass [] to hide them.
eyeDropperbooleantrueShow the eyedropper button when window.EyeDropper exists.
areaHeightnumber168Height of the saturation / brightness area in px.
accentstring"#FF7448"Focus ring and active swatch colour.
disabledbooleanfalseDisable all input.
namestring—Submits the hex value with a form via a hidden input.
...propsHTMLAttributes<HTMLDivElement>—Forwarded to the root role="group".

04Features

  • 012D saturation / brightness area with pointer capture
  • 02Hue and optional alpha sliders over a checkerboard
  • 03Hex, RGB and HSL text input with live validation (comma or space syntax)
  • 04Swatches with a pressed state for the current colour
  • 05Native eyedropper where supported, feature-detected after hydration
  • 06HSVA state keeps the hue for greys; pure inline colour math, no dependencies
  • 07Drags update at most once per animation frame
input · draginput · pointerinput · keyboardinput · clickinput · focus

05Accessibility

  • The area is a focusable role="slider" (aria-roledescription “2D slider”): left / right change saturation, up / down change brightness, Shift for steps of 10, and aria-valuetext reads both values.
  • Hue and opacity are separate role="slider" elements with aria-valuetext like “15°, red” and “80% opacity”.
  • The text field is labelled, sets aria-invalid on bad input and announces the expected format through a polite live region.
  • Swatches are buttons named by their hex value with aria-pressed; the eyedropper button has an explicit label.
  • Every part shows a visible focus ring in the accent colour; there is no motion beyond a small hover scale, which is removed with prefers-reduced-motion.

06Limitations

  • The eyedropper only appears in browsers with the EyeDropper API (Chromium on desktop).
  • Colours are sRGB; wide-gamut (Display P3, oklch) input is not supported.