On this page
Import
import {
ColorPicker,
ColorPickerButton,
ColorSwatch,
} from '@envsemble/envui/color';
Usage
ColorPicker, ColorPickerButton and ColorSwatch come from their own entry, @envsemble/envui/color, built on React Aria's color hooks, whose libraries the application installs.
- A ColorPicker takes its
label, which names it, adescriptionand anerror;visibleLabel={false}hides the label where something else names the picker, such as a popover. valueanddefaultValue,#000000by default, take a CSS color string, such as#6750a4,rgb(103, 80, 164)orhsl(256, 34%, 48%), or React Aria'sColor.onValueChangereceives the color as a string invalueFormat; the picker keeps the hue of a gray itself.valueFormatishex, the default,#rrggbbor#rrggbbaawhile translucent,rgborhsl.- With
alpha, the picker adds an alpha slider and field; without it, colors are opaque.
import { useState } from 'react';
import { ColorPicker } from '@envsemble/envui/color';
export default function MinimalPicker() {
const [color, setColor] = useState('#3b6fd4');
return (
// The picker fills its container; a sidebar or a popover gives it its width.
<div style={{ inlineSize: 'min(100%, 16rem)' }}>
<ColorPicker label="Accent color" formats={['hex']} value={color} onValueChange={setColor} />
</div>
);
}Formats
Without formats, the picker shows one format at a time, hex first, with the format menu.
formatswith one format, such as['hex'], shows it alone, with no menu.- With two or more, such as
['hex', 'rgb', 'hsl'], it shows each on a row of its own in that order, with its own copy button. - Each row is a group named after its format, so a screen reader says which Red or Alpha it is in.
Offer only the formats and the alpha the stored color can hold: a color stored as #rrggbb takes formats={['hex']} and no alpha, rather than every format and an alpha it would lose.
<ColorPicker label="Brand color" defaultValue="#6b4fa3" formats={['hex', 'rgb', 'hsl']} />
<ColorPicker label="Label color" defaultValue="#2f6f62" formats={['hex']} />
Copy, the eyedropper and swatches
copyable and eyeDropper are on by default. The eyedropper shows only where the browser has one, Chromium-based browsers on the desktop. swatches lists preset colors under the fields: CSS color strings, Colors, or { color, label } with a name.
<ColorPicker
label="Project color"
defaultValue="#6b4fa3"
swatches={[
{ color: '#3b6fd4', label: 'Blue' },
{ color: '#2f6f62', label: 'Teal' },
]}
/>
ColorPickerButton
ColorPickerButton takes the picker's props, and opens it in a popover.
sideplaces the popover,bottomby default, lined up byalign,startby default.defaultOpenstarts it open;openandonOpenChangelet the application open and close it, such as once a swatch is chosen.sizeissm,mdorlg, or its container's control height.className,style,refand the other native props, such asaria-describedby, reach the button.
<ColorPickerButton label="Label color" defaultValue="#2f6f62" />
ColorSwatch
ColorSwatch shows its color, with an optional alpha, and writes it in format, hex, rgb or hsl, after an optional label.
- Without a format and a label, the sample stands alone, named by the color's description, such as dark purple.
sizeismd, 1 rem and the default, orsm, 0.75 rem, for dense rows; as a Button's icon it takes the icon's size.- As the icon of an IconButton in its default variant, the button draws no round fill behind the square sample.
<ColorSwatch color="#6b4fa3" label="Design" format="hex" />
In a form
name submits the color as a string in valueFormat, and form ties it to a form it sits outside; a reset returns to defaultValue.
- The picker always holds a color, so it takes no
required: keep "no color yet" in the form's own state and validate it there. readOnlylets people read and copy the color but not change it.disabledtakes no input.
<form onSubmit={apply}>
<ColorPicker
label="Project color"
name="color"
defaultValue="#6b4fa3"
formats={['hex', 'rgb']}
description="Shown beside the project in lists."
/>
<Button type="submit">Apply color</Button>
</form>
Composition
The picker fills its container up to 18 rem. The picker, env-color-picker, holds its label, env-color-picker-label; the controls, env-color-picker-controls, with the area, env-color-picker-area, and the sliders, env-color-picker-sliders, the hue, env-color-picker-hue, and the alpha, env-color-picker-alpha, each an env-color-picker-slider with its track, env-color-picker-track, and a thumb, env-color-picker-thumb, like the area's; and the values, env-color-picker-values, with the format, env-color-picker-format, the eyedropper, env-color-picker-eye-dropper, copy, env-color-picker-copy, and the fields, env-color-picker-fields, each an env-color-picker-field with its letter, env-color-picker-field-label, and input, env-color-picker-input. Several formats shown together are rows, env-color-picker-row. Then come the swatches, env-color-picker-swatches, each an env-color-picker-swatch, the description, env-color-picker-description, and the error, env-color-picker-error, the shared field error, env-field-error, with its icon. data-channel names a slider's or a field's channel, and data-format a row's format.
ColorPickerButton is env-color-picker-button, with its value, env-color-picker-button-value, and its popover, env-color-picker-popover. ColorSwatch is env-color-swatch, with its sample, env-color-swatch-sample, its label, env-color-swatch-label, and its value, env-color-swatch-value.
Customize
ColorPickerButton has no fill of its own; its container color gives it one.
Its popup is frosted, as every popup is: --env-popup-opacity, --env-popup-blur and --env-popup-shadow, set on a theme, change it, as Popover describes.
Accessibility
You provide
- A
labelthat names what the color is for. - A contrast check where the color carries text, and its message in
error.
envUI provides
- A group named by
label, with the area, sliders and fields named after their channels, such as Hue and Alpha, in the EnvUIProvider's language. - Value texts that say each channel and the color's name, such as dark vibrant blue.
- A ColorSwatch alone named by its color's description; beside its value or label, the sample is hidden from assistive technology.
Props
ColorPicker
A compact color picker on React Aria's color hooks: a square saturation and brightness area with a vertical hue slider, and an alpha slider with `alpha`, at its side; under them, a format select, the browser's eyedropper where it has one, a copy button, and fields for the chosen format, or the fields of several `formats` together, each with its own copy button; and preset swatches. Every part works with the keyboard; the channels and the area are named in the EnvUIProvider's language.
| Prop | Type | Description |
|---|---|---|
visibleLabelDefault true | boolean | The label shows above the picker. false hides it where something else names the picker, such as the popover around it: the label still names the picker for assistive technology. |
description | ReactNode | Lasting guidance under the picker, such as where the color shows. |
error | ReactNode | A message under the picker that says what is wrong with the color, such as too little contrast. |
labelrequired | string | The color's name, such as Accent color; it names the picker, and ColorPickerButton's popover and button. |
value | ColorValue | The color in a controlled picker: a CSS color string, such as #6750a4, rgb(103, 80, 164) or hsl(256, 34%, 48%), or React Aria's Color; update it from onValueChange. |
defaultValueDefault '#000000' | ColorValue | The color an uncontrolled picker starts at, and that a form reset restores. |
onValueChange | ( | Receives the color as it changes, as a string in valueFormat, such as #6750a4. |
valueFormatDefault 'hex' | 'hex''rgb''hsl' | The format of the string onValueChange receives and a form submits: hex (#rrggbb, or #rrggbbaa while translucent), rgb (rgb() or rgba()) or hsl (hsl() or hsla()). |
formats | readonly ColorFormat[ | The formats whose fields show together, one under another in this order, such as `['hex', 'rgb', 'hsl']`. With one, the picker shows that format alone; without the prop, it shows one format at a time, hex first, with a select that switches to RGB or HSL. |
alphaDefault false | boolean | Whether the color has an alpha: a slider and a field for its opacity, and a value with its alpha while translucent. Without it, colors are opaque. |
eyeDropperDefault true | boolean | Whether to show the eyedropper, which picks a color from the screen, where the browser has one (Chromium-based browsers on the desktop); elsewhere it never shows. |
copyableDefault true | boolean | Whether to show the button that copies the color, as the fields show it. |
swatches | readonly ColorPickerSwatch[ | Preset colors to choose from, under the fields: CSS color strings, React Aria's Colors, or `{ color, label }` with a name, such as the colors of a brand. |
name | string | Submits the color with a form under this name, as a string in valueFormat. |
form | string | The id of the form the color submits with, where the picker sits outside it. |
disabledDefault false | boolean | Whether the picker takes no input, faded. |
readOnlyDefault false | boolean | Whether people can read and copy the color, but not change it. |
Also accepts the native props of <div>, such as ref, className and aria-* attributes.
ColorPickerButton
A compact button that shows a color as a swatch and its value, and opens a ColorPicker in a Popover: the common way to choose a color in a toolbar, a row or a form. The button is named after the label and the color, such as Accent color, #6750A4. className, style, ref and the other native props go to the button.
| Prop | Type | Description |
|---|---|---|
size | 'sm''md''lg' | The button's height, as on every control; without it, its container's. |
sideDefault 'bottom' | 'top''bottom''left''right''inline-start''inline-end' | The side of the button the picker opens on. |
alignDefault 'start' | 'start''center''end' | How the picker lines up with the button along that side. |
open | boolean | Whether the picker is open, for a picker the application controls with onOpenChange. |
defaultOpenDefault false | boolean | Whether an uncontrolled picker starts open, such as in a picture of it. |
onOpenChange | ( | Receives the requested state, and why, as Popover's onOpenChange does: such as to close the picker once a swatch is chosen. |
labelrequired | string | The color's name, such as Accent color; it names the picker, and ColorPickerButton's popover and button. |
value | ColorValue | The color in a controlled picker: a CSS color string, such as #6750a4, rgb(103, 80, 164) or hsl(256, 34%, 48%), or React Aria's Color; update it from onValueChange. |
defaultValueDefault '#000000' | ColorValue | The color an uncontrolled picker starts at, and that a form reset restores. |
onValueChange | ( | Receives the color as it changes, as a string in valueFormat, such as #6750a4. |
valueFormatDefault 'hex' | 'hex''rgb''hsl' | The format of the string onValueChange receives and a form submits: hex (#rrggbb, or #rrggbbaa while translucent), rgb (rgb() or rgba()) or hsl (hsl() or hsla()). |
formats | readonly ColorFormat[ | The formats whose fields show together, one under another in this order, such as `['hex', 'rgb', 'hsl']`. With one, the picker shows that format alone; without the prop, it shows one format at a time, hex first, with a select that switches to RGB or HSL. |
alphaDefault false | boolean | Whether the color has an alpha: a slider and a field for its opacity, and a value with its alpha while translucent. Without it, colors are opaque. |
eyeDropperDefault true | boolean | Whether to show the eyedropper, which picks a color from the screen, where the browser has one (Chromium-based browsers on the desktop); elsewhere it never shows. |
copyableDefault true | boolean | Whether to show the button that copies the color, as the fields show it. |
swatches | readonly ColorPickerSwatch[ | Preset colors to choose from, under the fields: CSS color strings, React Aria's Colors, or `{ color, label }` with a name, such as the colors of a brand. |
name | string | Submits the color with a form under this name, as a string in valueFormat. |
form | string | The id of the form the color submits with, where the picker sits outside it. |
disabledDefault false | boolean | Whether the picker takes no input, faded. |
readOnlyDefault false | boolean | Whether people can read and copy the color, but not change it. |
Also accepts the native props of <button>, such as ref, className and aria-* attributes.
ColorSwatch
A small rounded sample of a color, with a hairline edge that keeps light and dark colors visible on every surface and a checkerboard under a translucent one. With `format`, it writes the color's value beside it, and with `label`, a name. Alone, it is an image named by the color's description, such as dark purple, in the EnvUIProvider's language; as a Button's icon it is decorative, and the button's text names the color.
| Prop | Type | Description |
|---|---|---|
colorrequired | ColorValue | The color it shows: a CSS color string, such as #6750a4, rgb(103, 80, 164) or hsl(256, 34%, 48%), with an optional alpha, or React Aria's Color. |
format | 'hex''rgb''hsl' | Writes the color beside the sample in this format: hex, such as #6750A4, rgb or hsl. Without it and a label, the sample stands alone, named by the color's description, such as dark purple. |
label | ReactNode | A name beside the sample, before the value, such as the label the color belongs to. |
sizeDefault 'md' | 'sm''md' | The sample's size: sm, 0.75 rem, for dense rows; md, 1 rem, the size of an icon. As a Button's icon it takes the icon's size. |
Also accepts the native props of <span>, such as ref, className and aria-* attributes.
Part names
Each part's class and state attributes are public and versioned, for an application's CSS to style.
ColorPicker
env-color-picker- The color picker.
env-color-picker-alpha- The alpha slider.
env-color-picker-area- The square area of saturation and brightness over the hue.
env-color-picker-controls- The row of the area and the sliders at its side.
env-color-picker-copy- The copy button.
env-color-picker-description- The description under the picker.
env-color-picker-error- The error under the picker.
env-color-picker-eye-dropper- The eyedropper, where the browser has one.
env-color-picker-field- A channel's field with its letter, or the hex field.
env-color-picker-field-label- The letter of a channel's field, such as R.
env-color-picker-fields- The fields of the chosen format, or of one format's row.
env-color-picker-format- The format select.
env-color-picker-hue- The hue slider.
env-color-picker-input- The input of a field.
env-color-picker-label- The label above the picker.
env-color-picker-popover- The popover of a ColorPickerButton, around its picker.
env-color-picker-row- A format's row where several formats show together: its fields and its copy button.
env-color-picker-slider- A slider of one channel.
env-color-picker-sliders- The vertical hue and alpha sliders, side by side.
env-color-picker-swatch- A preset swatch.
env-color-picker-swatches- The preset swatches.
env-color-picker-thumb- The thumb of the area or of a slider.
env-color-picker-track- A slider's track.
env-color-picker-values- The format, the eyedropper and copy, with the fields in equal columns under them.
data-alpha- Present on env-color-picker-values
data-channelalpha·blue·brightness·green·hex·hue·lightness·red·saturationon env-color-picker-alpha, env-color-picker-field, env-color-picker-hue, env-color-picker-sliderdata-disabled- Present on env-color-picker, env-color-picker-alpha, env-color-picker-area, env-color-picker-hue, env-color-picker-slider
data-dragging- Present on env-color-picker-thumb
data-eye-dropper- Present on env-color-picker-values
data-formathex·hsl·rgbon env-color-picker-row, env-color-picker-valuesdata-formatstogetheron env-color-picker-valuesdata-invalid- Present
data-readonly- Present
data-selected- Present on env-color-picker-swatch
data-translucent- Present on env-color-picker-swatch
ColorPickerButton
env-color-picker-button- The button that shows the color and opens the picker.
env-color-picker-button-value- The color's value on the button.
data-sizelg·md·sm
ColorSwatch
env-color-swatch- A swatch of one color, with its label and value.
env-color-swatch-label- The color's name.
env-color-swatch-sample- The sample of the color.
env-color-swatch-value- The color's value in the format asked for.
data-sizemd·smon env-color-swatch, env-color-swatch-sampledata-translucent- Present on env-color-swatch, env-color-swatch-sample
Color properties
Each sets a color of one instance, through style or CSS; its hover, focus and press follow it. They are public and versioned.
--env-color-picker-button-container- The fill behind the swatch and the value, transparent by default.
Strings
EnvUIProvider's messages overrides each, and a component's own label prop wins over it.
messages.colorPicker.format"Color format"Names the menu of formats.messages.colorPicker.formatButton({ format }) => stringNames the button that opens the menu of formats, with the format it shows, such as Hex.messages.colorPicker.hex"Hex"The hexadecimal format, in the format select and before its field.messages.colorPicker.rgb"RGB"The RGB format, in the format select and before its fields.messages.colorPicker.hsl"HSL"The HSL format, in the format select and before its fields.messages.colorPicker.hexField"Hex"Names the hexadecimal field.messages.colorPicker.redShort"R"The letter beside the red channel's number.messages.colorPicker.greenShort"G"The letter beside the green channel's number.messages.colorPicker.blueShort"B"The letter beside the blue channel's number.messages.colorPicker.hueShort"H"The letter beside the hue's number.messages.colorPicker.saturationShort"S"The letter beside the saturation's number.messages.colorPicker.lightnessShort"L"The letter beside the lightness's number.messages.colorPicker.alphaShort"A"The letter beside the alpha's number.messages.colorPicker.copy"Copy color"Names the copy button.messages.colorPicker.copyFormat({ format }) => stringNames the copy button of one format where several show together, such as Copy color as RGB.messages.colorPicker.eyeDropper"Pick a color from the screen"Names the eyedropper button.messages.colorPicker.swatches"Swatches"Names the list of preset colors.messages.colorPicker.button({ label, value }) => stringNames ColorPickerButton after the picker's label and the color, such as Accent, #6750A4.
Changelog
- 1.0.0
showLabelisvisibleLabel, named after the label thatvisibleLabel={false}hides.ColorPicker, ColorPickerButton and ColorSwatch come from
@envsemble/envui/color, on React Aria's color hooks: hex, RGB and HSL fields named by their letters, with a format menu, an alpha slider and field withalpha, a copy button, the browser's eyedropper and presetswatches. Values are CSS color strings or React Aria'sColor, andonValueChangereceives both. The area is square with the hue and alpha strips upright at its side, all with square corners, and the fields are quiet. ColorSwatch is a small square that writes its color in aformat, with alabeland a small size. ColorPickerButton has no fill of its own, as fields have none. Before, the color area and the hue were envUI's own, on Base UI's Slider, with a HEX field.- 1.0.0-prerelease.6
Colors under the pointer and while pressed change with
--env-motion-ease-enter, rather than easing in slowly, so hover and press show from the first frame.ColorPickerButton's popover opens over
--env-motion-duration-medium, fading in and growing from 98 % with--env-motion-ease-enter, rather than growing from 96 % over the slow duration, so it shows from its first frames rather than late.The error shows the error icon before its message, as under every field.
- 1.0.0-prerelease.5
ColorPickerButton takes
openandonOpenChange, and passesrefand the native props on to its button.copyiscopyable, as on CodeBlock.onValueChangereceives the string alone, without React Aria'sColor.ColorPickerButton's popover is frosted: the popup's color lets a little of what is behind through, blurred, with a soft shadow and no outline edge but a faint hairline in dark, and is solid with its edge at high contrast and with reduced transparency.
- 1.0.0-prerelease.3
formatswith two or more formats shows their fields together, a row each with its own copy button, where in 1.0.0-prerelease.2 it limited the format menu to them; the format menu stays the default. Removeformatsto keep the menu, which offers every format.--env-color-picker-button-containergives one ColorPickerButton a fill.