ColorPicker
A ColorPicker combines a swatch with a customizable popover for editing a color.
install | yarn add @react-spectrum/color |
---|---|
version | 3.0.0-rc.1 |
usage | import {ColorPicker, ColorEditor} from '@react-spectrum/color' |
Example#
<ColorPicker label="Fill" defaultValue="#5100FF">
<ColorEditor />
</ColorPicker>
<ColorPicker label="Fill" defaultValue="#5100FF">
<ColorEditor />
</ColorPicker>
<ColorPicker
label="Fill"
defaultValue="#5100FF"
>
<ColorEditor />
</ColorPicker>
Value#
A ColorArea requires either an uncontrolled default value or a controlled value, provided using the defaultValue
or value
props respectively. The value provided to either of these props should be a color string or Color
object.
In the example below, the parseColor
function is used to parse the initial color from a HSL string so that value
's type remains consistent.
import {ColorPicker} from '@react-spectrum/color';
import {Flex} from '@react-spectrum/layout';
import {parseColor} from '@react-spectrum/color';
function Example() {
let [value, setValue] = React.useState(parseColor('hsl(25, 100%, 50%)'));
return (
<Flex gap="size-300" wrap>
<ColorPicker
label="Color Picker (uncontrolled)"
defaultValue="hsl(25, 100%, 50%)"> <ColorEditor />
</ColorPicker>
<ColorPicker
label="Color Picker (controlled)"
value={value}
onChange={setValue}> <ColorEditor />
</ColorPicker>
</Flex>
);
}
import {ColorPicker} from '@react-spectrum/color';
import {Flex} from '@react-spectrum/layout';
import {parseColor} from '@react-spectrum/color';
function Example() {
let [value, setValue] = React.useState(
parseColor('hsl(25, 100%, 50%)')
);
return (
<Flex gap="size-300" wrap>
<ColorPicker
label="Color Picker (uncontrolled)"
defaultValue="hsl(25, 100%, 50%)"
> <ColorEditor />
</ColorPicker>
<ColorPicker
label="Color Picker (controlled)"
value={value}
onChange={setValue}
> <ColorEditor />
</ColorPicker>
</Flex>
);
}
import {ColorPicker} from '@react-spectrum/color';
import {Flex} from '@react-spectrum/layout';
import {parseColor} from '@react-spectrum/color';
function Example() {
let [value, setValue] =
React.useState(
parseColor(
'hsl(25, 100%, 50%)'
)
);
return (
<Flex
gap="size-300"
wrap
>
<ColorPicker
label="Color Picker (uncontrolled)"
defaultValue="hsl(25, 100%, 50%)"
> <ColorEditor />
</ColorPicker>
<ColorPicker
label="Color Picker (controlled)"
value={value}
onChange={setValue}
> <ColorEditor />
</ColorPicker>
</Flex>
);
}
Labeling#
A visual label should be provided for the ColorPicker using the label
prop.
<ColorPicker label="Stroke color" defaultValue="#345">
<ColorEditor />
</ColorPicker>
<ColorPicker label="Stroke color" defaultValue="#345">
<ColorEditor />
</ColorPicker>
<ColorPicker
label="Stroke color"
defaultValue="#345"
>
<ColorEditor />
</ColorPicker>
Accessibility#
If a visible label isn't specified, an aria-label
should be provided to the ColorPicker for
accessibility. If the field is labeled by a separate element, an aria-labelledby
prop must be provided using
the id
of the labeling element instead.
<ColorPicker aria-label="Fill color" defaultValue="#184">
<ColorEditor />
</ColorPicker>
<ColorPicker aria-label="Fill color" defaultValue="#184">
<ColorEditor />
</ColorPicker>
<ColorPicker
aria-label="Fill color"
defaultValue="#184"
>
<ColorEditor />
</ColorPicker>
In addition to the visible or accessibility label, a ColorPicker also announces a description of the current color value (e.g. "dark vibrant blue") as a part of the label.
Internationalization#
For languages that are read right-to-left (e.g. Hebrew and Arabic), the layout of the ColorPicker is automatically flipped.
Events#
ColorPicker accepts an onChange
prop which is triggered whenever the value is edited by the user. It receives a Color
object as a parameter.
The example below uses onChange
to update a separate element with the color value as a string.
import {parseColor} from '@react-spectrum/color';
function Example() {
let [value, setValue] = React.useState(parseColor('hsl(50, 100%, 50%)'));
return (
<div>
<ColorPicker
label="Color"
value={value}
onChange={setValue}>
<ColorEditor />
</ColorPicker>
<p>Selected color: {value.toString('hsl')}</p>
</div>
);
}
import {parseColor} from '@react-spectrum/color';
function Example() {
let [value, setValue] = React.useState(
parseColor('hsl(50, 100%, 50%)')
);
return (
<div>
<ColorPicker
label="Color"
value={value}
onChange={setValue}
>
<ColorEditor />
</ColorPicker>
<p>Selected color: {value.toString('hsl')}</p>
</div>
);
}
import {parseColor} from '@react-spectrum/color';
function Example() {
let [value, setValue] =
React.useState(
parseColor(
'hsl(50, 100%, 50%)'
)
);
return (
<div>
<ColorPicker
label="Color"
value={value}
onChange={setValue}
>
<ColorEditor />
</ColorPicker>
<p>
Selected color:
{' '}
{value.toString(
'hsl'
)}
</p>
</div>
);
}
Custom color editor#
ColorEditor
provides a default color picker layout including a color area for saturation and brightness, and color sliders for hue and alpha. It also includes ColorFields to view and enter an exact color value by number.
ColorPicker can be customized by providing any combination of color components as children, including ColorArea, ColorField, ColorSlider, ColorSwatchPicker, and ColorWheel.
import {ColorWheel, ColorArea} from '@react-spectrum/color';
<ColorPicker label="Fill" defaultValue="#08f">
<ColorWheel />
<ColorArea
colorSpace="hsb"
xChannel="saturation"
yChannel="brightness"
size="size-400"
position="absolute"
top="calc(50% - size-400)"
left="calc(50% - size-400)" />
</ColorPicker>
import {ColorWheel, ColorArea} from '@react-spectrum/color';
<ColorPicker label="Fill" defaultValue="#08f">
<ColorWheel />
<ColorArea
colorSpace="hsb"
xChannel="saturation"
yChannel="brightness"
size="size-400"
position="absolute"
top="calc(50% - size-400)"
left="calc(50% - size-400)" />
</ColorPicker>
import {
ColorArea,
ColorWheel
} from '@react-spectrum/color';
<ColorPicker
label="Fill"
defaultValue="#08f"
>
<ColorWheel />
<ColorArea
colorSpace="hsb"
xChannel="saturation"
yChannel="brightness"
size="size-400"
position="absolute"
top="calc(50% - size-400)"
left="calc(50% - size-400)"
/>
</ColorPicker>
Props#
ColorPicker#
Name | Type | Default | Description |
label | ReactNode | — | A visual label for the color picker. |
children | ReactNode | — | The contents of the color picker popover, e.g. <ColorEditor /> . |
size | 'XS'
| 'S'
| 'M'
| 'L' | "M" | The size of the color swatch. |
rounding | 'default'
| 'none'
| 'full' | "default" | The corner rounding of the color swatch. |
value | string | Color | — | The current value (controlled). |
defaultValue | string | Color | — | The default value (uncontrolled). |
Events
Name | Type | Description |
onChange | (
(value: Color
)) => void | Handler that is called when the value changes. |
Accessibility
Name | Type | Description |
aria-label | string | Defines a string value that labels the current element. |
aria-labelledby | string | Identifies the element (or elements) that labels the current element. |
aria-describedby | string | Identifies the element (or elements) that describes the object. |
aria-details | string | Identifies the element (or elements) that provide a detailed, extended description for the object. |
ColorEditor#
Name | Type | Description |
hideAlphaChannel | boolean | Whether to hide the alpha channel color slider and color field. |
Visual options#
Hide alpha channel#
By default, ColorEditor
includes a ColorSlider and ColorField for editing the alpha channel. This can be hidden with the hideAlphaChannel
prop.
<ColorPicker label="Color" defaultValue="#f80">
<ColorEditor hideAlphaChannel />
</ColorPicker>
<ColorPicker label="Color" defaultValue="#f80">
<ColorEditor hideAlphaChannel />
</ColorPicker>
<ColorPicker
label="Color"
defaultValue="#f80"
>
<ColorEditor
hideAlphaChannel
/>
</ColorPicker>
Swatches#
A ColorEditor
can be combined with additional color components such as a ColorSwatchPicker to choose from a list of pre-defined colors.
import {ColorSwatchPicker, ColorSwatch} from '@react-spectrum/color';
<ColorPicker label="Color" defaultValue="#A00">
<Flex direction="column" gap="size-300">
<ColorEditor />
<ColorSwatchPicker>
<ColorSwatch color="#A00" />
<ColorSwatch color="#f80" />
<ColorSwatch color="#080" />
<ColorSwatch color="#08f" />
<ColorSwatch color="#088" />
<ColorSwatch color="#008" />
</ColorSwatchPicker>
</Flex>
</ColorPicker>
import {
ColorSwatch,
ColorSwatchPicker
} from '@react-spectrum/color';
<ColorPicker label="Color" defaultValue="#A00">
<Flex direction="column" gap="size-300">
<ColorEditor />
<ColorSwatchPicker>
<ColorSwatch color="#A00" />
<ColorSwatch color="#f80" />
<ColorSwatch color="#080" />
<ColorSwatch color="#08f" />
<ColorSwatch color="#088" />
<ColorSwatch color="#008" />
</ColorSwatchPicker>
</Flex>
</ColorPicker>
import {
ColorSwatch,
ColorSwatchPicker
} from '@react-spectrum/color';
<ColorPicker
label="Color"
defaultValue="#A00"
>
<Flex
direction="column"
gap="size-300"
>
<ColorEditor />
<ColorSwatchPicker>
<ColorSwatch color="#A00" />
<ColorSwatch color="#f80" />
<ColorSwatch color="#080" />
<ColorSwatch color="#08f" />
<ColorSwatch color="#088" />
<ColorSwatch color="#008" />
</ColorSwatchPicker>
</Flex>
</ColorPicker>
Channel sliders#
This example uses ColorSlider to allow a user to adjust each channel of a color value, with a Picker to switch between color spaces.
import type {ColorSpace} from '@react-spectrum/color';
import {ColorSlider, getColorChannels} from '@react-spectrum/color';
import {Item, Picker} from '@react-spectrum/picker';
function Example() {
let [space, setSpace] = React.useState<ColorSpace>('rgb');
return (
<ColorPicker label="Color" defaultValue="#184">
<Flex direction="column" gap="size-100">
<Picker
aria-label="Color space"
isQuiet
selectedKey={space}
onSelectionChange={(s) => setSpace(s as ColorSpace)}
>
<Item key="rgb">RGB</Item>
<Item key="hsl">HSL</Item>
<Item key="hsb">HSB</Item>
</Picker>
{getColorChannels(space).map((channel) => (
<ColorSlider key={channel} colorSpace={space} channel={channel} />
))}
<ColorSlider channel="alpha" />
</Flex>
</ColorPicker>
);
}
import type {ColorSpace} from '@react-spectrum/color';
import {
ColorSlider,
getColorChannels
} from '@react-spectrum/color';
import {Item, Picker} from '@react-spectrum/picker';
function Example() {
let [space, setSpace] = React.useState<ColorSpace>('rgb');
return (
<ColorPicker label="Color" defaultValue="#184">
<Flex direction="column" gap="size-100">
<Picker
aria-label="Color space"
isQuiet
selectedKey={space}
onSelectionChange={(s) =>
setSpace(s as ColorSpace)}
>
<Item key="rgb">RGB</Item>
<Item key="hsl">HSL</Item>
<Item key="hsb">HSB</Item>
</Picker>
{getColorChannels(space).map((channel) => (
<ColorSlider
key={channel}
colorSpace={space}
channel={channel}
/>
))}
<ColorSlider channel="alpha" />
</Flex>
</ColorPicker>
);
}
import type {ColorSpace} from '@react-spectrum/color';
import {
ColorSlider,
getColorChannels
} from '@react-spectrum/color';
import {
Item,
Picker
} from '@react-spectrum/picker';
function Example() {
let [space, setSpace] =
React.useState<
ColorSpace
>('rgb');
return (
<ColorPicker
label="Color"
defaultValue="#184"
>
<Flex
direction="column"
gap="size-100"
>
<Picker
aria-label="Color space"
isQuiet
selectedKey={space}
onSelectionChange={(s) =>
setSpace(
s as ColorSpace
)}
>
<Item key="rgb">
RGB
</Item>
<Item key="hsl">
HSL
</Item>
<Item key="hsb">
HSB
</Item>
</Picker>
{getColorChannels(
space
).map(
(channel) => (
<ColorSlider
key={channel}
colorSpace={space}
channel={channel}
/>
)
)}
<ColorSlider channel="alpha" />
</Flex>
</ColorPicker>
);
}
Rounding#
The rounding of the color swatch can be controlled with the rounding
prop.
<Flex direction="column" gap="size-100">
<ColorPicker label="None" rounding="none" defaultValue="#A00">
<ColorEditor />
</ColorPicker>
<ColorPicker label="Default" rounding="default" defaultValue="#080">
<ColorEditor />
</ColorPicker>
<ColorPicker label="Full" rounding="full" defaultValue="#00F">
<ColorEditor />
</ColorPicker>
</Flex>
<Flex direction="column" gap="size-100">
<ColorPicker
label="None"
rounding="none"
defaultValue="#A00"
>
<ColorEditor />
</ColorPicker>
<ColorPicker
label="Default"
rounding="default"
defaultValue="#080"
>
<ColorEditor />
</ColorPicker>
<ColorPicker
label="Full"
rounding="full"
defaultValue="#00F"
>
<ColorEditor />
</ColorPicker>
</Flex>
<Flex
direction="column"
gap="size-100"
>
<ColorPicker
label="None"
rounding="none"
defaultValue="#A00"
>
<ColorEditor />
</ColorPicker>
<ColorPicker
label="Default"
rounding="default"
defaultValue="#080"
>
<ColorEditor />
</ColorPicker>
<ColorPicker
label="Full"
rounding="full"
defaultValue="#00F"
>
<ColorEditor />
</ColorPicker>
</Flex>
Size#
The size of the color swatch can be controlled with the size
prop. The default size is "S".
<Flex direction="column" gap="size-100">
<ColorPicker label="Extra small" size="XS" defaultValue="#A00">
<ColorEditor />
</ColorPicker>
<ColorPicker label="Small" size="S" defaultValue="#080">
<ColorEditor />
</ColorPicker>
<ColorPicker label="Medium" size="M" defaultValue="#FB0">
<ColorEditor />
</ColorPicker>
<ColorPicker label="Large" size="L" defaultValue="#00F">
<ColorEditor />
</ColorPicker>
</Flex>
<Flex direction="column" gap="size-100">
<ColorPicker
label="Extra small"
size="XS"
defaultValue="#A00"
>
<ColorEditor />
</ColorPicker>
<ColorPicker label="Small" size="S" defaultValue="#080">
<ColorEditor />
</ColorPicker>
<ColorPicker
label="Medium"
size="M"
defaultValue="#FB0"
>
<ColorEditor />
</ColorPicker>
<ColorPicker label="Large" size="L" defaultValue="#00F">
<ColorEditor />
</ColorPicker>
</Flex>
<Flex
direction="column"
gap="size-100"
>
<ColorPicker
label="Extra small"
size="XS"
defaultValue="#A00"
>
<ColorEditor />
</ColorPicker>
<ColorPicker
label="Small"
size="S"
defaultValue="#080"
>
<ColorEditor />
</ColorPicker>
<ColorPicker
label="Medium"
size="M"
defaultValue="#FB0"
>
<ColorEditor />
</ColorPicker>
<ColorPicker
label="Large"
size="L"
defaultValue="#00F"
>
<ColorEditor />
</ColorPicker>
</Flex>