ColorPicker
Pick a color: a saturation area, hue and alpha sliders, a hex input, an eyedropper and preset swatches.
'use client';
import { ColorPicker } from '@akhatmirzo/ui';
import { useState } from 'react';
export default function ColorPickerBasic() {
const [color, setColor] = useState('#4f46e5');
return (
<div className="w-full max-w-60">
<ColorPicker value={color} onValueChange={setColor} aria-label="Asosiy rang" />
</div>
);
}
Import
import { ColorPicker } from '@akhatmirzo/ui';When to use
- Users choose their own color — a brand color, a tag or category color, theme settings.
- When the palette is limited, pass a preset palette via
swatches; free picking stays available. - When users pick from only a handful of colors (5–6), a
RadioGroupor aSegmentedControlwith color samples is simpler.
Anatomy
The trigger is a button styled like an Input: a color sample on the left and the
hex text next to it. Clicking it opens a Popover:
- Saturation area (2D) — the horizontal axis is saturation, the vertical axis is brightness.
- Hue slider — the hue (0–360°), built with the
Slidercomponent. - Alpha slider — only with
alpha. - Eyedropper — picks a color from the screen when the browser supports the
EyeDropperAPI (Chromium for now); otherwise the button is hidden. - Hex input — a full 6 (or 8) digit hex applies right away; a short
#abcapplies onEnteror blur. Invalid text shows the error state and reverts to the previous color on blur. - Preset swatches (
swatches).
The value always comes back as lowercase #rrggbb (onValueChange('#0ea5e9')). Picking white,
black or gray keeps the hue, so the slider doesn't jump.
With Field
Inside a Field the trigger is named by the label plus the current color ("Brend
rangi #0EA5E9"), and the description and error go into aria-describedby. name adds a hidden
<input> for forms.
Tugmalar va havolalarda ishlatiladi
'use client';
import { ColorPicker, Field } from '@akhatmirzo/ui';
export default function ColorPickerWithField() {
return (
<div className="w-full max-w-60">
<Field label="Brend rangi" description="Tugmalar va havolalarda ishlatiladi">
<ColorPicker name="brand" defaultValue="#0ea5e9" />
</Field>
</div>
);
}
Alpha
With alpha the panel shows an alpha slider and the value becomes #rrggbbaa (#10b98180 — 50%).
Color samples sit on a checkerboard.
Qiymat: #10b98180
'use client';
import { ColorPicker } from '@akhatmirzo/ui';
import { useState } from 'react';
export default function ColorPickerAlpha() {
const [color, setColor] = useState('#10b98180');
return (
<div className="flex w-full max-w-60 flex-col gap-2">
<ColorPicker alpha value={color} onValueChange={setColor} aria-label="Fon rangi" />
<p className="m-0 text-sm text-text-muted">
Qiymat: <span className="font-mono text-text">{color}</span>
</p>
</div>
);
}
Swatches
The default swatches are 10 colors from the library palette (exported as defaultColorSwatches).
Pass your own palette, or [] to hide them.
'use client';
import { ColorPicker } from '@akhatmirzo/ui';
// Faqat brend palitrasidagi ranglar
const brand = ['#4f46e5', '#0ea5e9', '#10b981', '#f59e0b', '#e11d48'];
export default function ColorPickerSwatches() {
return (
<div className="w-full max-w-60">
<ColorPicker swatches={brand} defaultValue="#10b981" aria-label="Teg rangi" />
</div>
);
}
Sizes and states
size matches the Input height: sm 32px, md 40px (default), lg 48px. disabled doesn't
open; invalid (or Field error) shows a red border.
'use client';
import { ColorPicker } from '@akhatmirzo/ui';
export default function ColorPickerSizes() {
return (
<div className="flex w-full max-w-60 flex-col gap-3">
<ColorPicker size="sm" aria-label="Kichik" />
<ColorPicker aria-label="O'rtacha" />
<ColorPicker size="lg" aria-label="Katta" />
<ColorPicker disabled aria-label="O'chirilgan" />
</div>
);
}
Props
Other <button> attributes and ref go to the trigger.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Color `#rrggbb` (`#rrggbbaa` with alpha) |
defaultValue | string | '#4f46e5' | Initial color |
onValueChange | (value: string) => void | — | Called when the color changes |
swatches | string[] | defaultColorSwatches | Preset colors (10) |
alpha | boolean | false | Alpha slider and an `#rrggbbaa` value |
eyeDropper | boolean | true | Eyedropper button when the EyeDropper API exists |
size | 'sm' | 'md' | 'lg' | 'md' | Trigger height 32 / 40 / 48px |
disabled | boolean | — | Disabled state |
invalid | boolean | — | Error state (automatic inside Field) |
name | string | — | Hidden input for forms |
open / defaultOpen | boolean | — | Panel state |
onOpenChange | (open: boolean) => void | — | Called when the panel opens or closes |
labels | { trigger?; saturation?; saturationValue?; hue?; alpha?; hex?; eyeDropper?; swatches? } | — | Built-in texts (Uzbek by default) — see the table below |
contentClassName | string | — | Panel class |
labels
| Prop | Type | Default | Description |
|---|---|---|---|
trigger | string | 'Rang tanlash' | Trigger name (without Field) |
saturation | string | "To'yinganlik va yorqinlik" | Name of the 2D area |
saturationValue | (s: number, v: number) => string | "to'yinganlik 80%, yorqinlik 60%" | aria-valuetext of the 2D area |
hue | string | 'Rang tusi' | Hue slider |
alpha | string | 'Shaffoflik' | Alpha slider |
hex | string | 'HEX' | Hex input |
eyeDropper | string | 'Ekrandan rang olish' | Eyedropper button |
swatches | string | 'Tayyor ranglar' | Swatch group |
Data attributes
| Attribute | Where | Value |
|---|---|---|
data-state | trigger | open · closed |
data-size | trigger | sm · md · lg |
data-invalid | trigger | present in the error state |
data-disabled | trigger | present when disabled |
data-state | swatch | on · off |
data-slot | parts | color-picker · color-picker-content · color-picker-area · color-picker-hue · color-picker-alpha |
Keyboard
| Key | Where | Action |
|---|---|---|
Enter / Space | trigger | Open the panel |
Esc | panel | Close; focus returns to the trigger |
← / → | 2D area | Saturation ±1% (±10% with Shift) |
↑ / ↓ | 2D area | Brightness ±1% (±10% with Shift) |
PageUp / PageDown | 2D area | Brightness ±10% |
Home / End | 2D area | Saturation 0% / 100% |
| arrows | hue / alpha | Slider keyboard |
Enter | hex input | Apply the typed color |
Accessibility
- Trigger — a plain
<button>; inside aFieldit's named by the label plus the current hex, otherwise"Rang tanlash, #4F46E5"(change witharia-labelorlabels.trigger). - 2D area —
role="slider"witharia-valuenow(saturation) and anaria-valuetextthat covers both axes: "to'yinganlik 80%, yorqinlik 60%". - Hue and alpha — the
Slidercomponent:role="slider"witharia-valuetext("210°", "50%"). - Swatches — buttons inside a
role="group", each named by its hex and usingaria-pressed. - Eyedropper — shown only when the API exists (hidden on the server and in unsupported
browsers),
aria-label="Ekrandan rang olish". - Color isn't the only signal — the selected swatch gets an extra ring, and the trigger also shows the hex text.