Color picker
A panel containing swatches for selecting colors.
import * as React from 'react';
import {
ColorBuilder,
ColorInputPanel,
ColorPicker,
ColorValue,
IconButton,
ColorSwatch,
Popover,
} from '@itwin/itwinui-react';
export default () => {
const [activeColor, setActiveColor] = React.useState(
ColorValue.create('#0073ba'),
);
const onColorChanged = (color) => {
setActiveColor(color);
};
return (
<Popover
content={
<ColorPicker
selectedColor={activeColor}
onChangeComplete={onColorChanged}
>
<ColorBuilder />
<ColorInputPanel defaultColorFormat={'hsl'} />
</ColorPicker>
}
>
<IconButton label='Show color picker'>
<ColorSwatch style={{ pointerEvents: 'none' }} color={activeColor} />
</IconButton>
</Popover>
);
};
Color pickers allow users to browse and apply a color to a selected item.
Variants
Basic
A basic color picker displays a pre-determined selection of colors. Because the colors are system-provided, each color should have a user friendly name. The user cannot add or remove swatches from what is available in the basic color picker. You may offer a transparent / no color option.
import * as React from 'react';
import {
ColorPalette,
ColorPicker,
ColorSwatch,
Button,
Popover,
} from '@itwin/itwinui-react';
export default () => {
const ColorsList = [
{ color: '#ffffff', name: 'WHITE' },
{ color: '#5a6973', name: 'GREY' },
{ color: '#00121d', name: 'KURETAKE BLACK MANGA' },
{ color: '#002a44', name: 'RHAPSODY IN BLUE' },
{ color: '#00426b', name: 'DARK IMPERIAL BLUE' },
{ color: '#005a92', name: 'JETSKI RACE' },
{ color: '#0073ba', name: 'FRENCH BLUE' },
{ color: '#008be1', name: 'BLUE COLA' },
{ color: '#30b0ff', name: 'FANTASY CONSOLE SKY' },
{ color: '#58bfff', name: 'HELLO SUMMER' },
{ color: '#7fceff', name: 'CHROMIS DAMSEL BLUE' },
{ color: '#a6ddff', name: 'DROPLET' },
{ color: '#cdecff', name: 'LUCID DREAMS' },
{ color: '#e5f5fd', name: 'KODAMA WHITE' },
{ color: '#010200', name: 'REGISTRATION BLACK' },
{ color: '#122306', name: 'YUZU SOY' },
{ color: '#23450b', name: 'FOREST GREEN' },
{ color: '#346711', name: 'TATZELWURM GREEN' },
{ color: '#458816', name: 'CHLOROPHYLL' },
{ color: '#56aa1c', name: 'PLASTIC PINES' },
{ color: '#5fbb1f', name: 'FIELD GREEN' },
{ color: '#67cc22', name: 'GREEN HIGH' },
{ color: '#91e458', name: 'LILLIPUTIAN LIME' },
{ color: '#b2ec8b', name: 'GREEN DAY' },
{ color: '#d4f4bd', name: 'TEA GREEN' },
{ color: '#eef6e8', name: 'VERDE PASTEL' },
{ color: '#9ba5af', name: 'SERYI GREY' },
{ color: '#cf0000', name: 'RED EPIPHYLLUM' },
{ color: '#ff6300', name: 'SAFETY ORANGE' },
{ color: '#ffc335', name: 'RISE-N-SHINE' },
];
const [isOpen, setIsOpen] = React.useState(false);
const [activeColor, setActiveColor] = React.useState(ColorsList[5]);
const [colorName, setColorName] = React.useState(ColorsList[5].name);
const onColorChanged = (color) => {
const hexString = color.toHexString();
const index = ColorsList.findIndex(
(swatch) => swatch.color === hexString.toLowerCase(),
);
setActiveColor(ColorsList[index]);
setColorName(ColorsList[index].name);
setIsOpen(false);
};
return (
<Popover
visible={isOpen}
onVisibleChange={setIsOpen}
content={
<ColorPicker
selectedColor={activeColor.color}
onChangeComplete={onColorChanged}
>
<ColorPalette colors={ColorsList.map(({ color }) => color)} />
</ColorPicker>
}
>
<Button
startIcon={
<ColorSwatch
className='demo-color-swatch'
color={activeColor.color}
/>
}
>
{colorName}
</Button>
</Popover>
);
};
Advanced
The advanced color picker lets the user pick any color. You may display user saved colors or recently used colors if needed. Because the colors are immensely flexible, colors are labeled with HEX, RGB/RGBA, or HSL/HSLA color code values. A clickable icon in the text field allows the user to rotate through the different color code types.
import * as React from 'react';
import {
ColorBuilder,
ColorInputPanel,
ColorPalette,
ColorPicker,
ColorValue,
} from '@itwin/itwinui-react';
export default () => {
const [selectedColor, setSelectedColor] = React.useState(
ColorValue.create({ r: 90, g: 105, b: 115, a: 0.4 }),
);
const onColorChanged = (color) => {
setSelectedColor(color);
};
return (
<ColorPicker
selectedColor={selectedColor}
onChangeComplete={onColorChanged}
showAlpha={true}
>
<ColorBuilder />
<ColorInputPanel defaultColorFormat='rgb' />
<ColorPalette
label='Saved Colors'
colors={[
{ r: 90, g: 105, b: 115, a: 1 },
{ r: 90, g: 105, b: 115, a: 0.81 },
{ r: 90, g: 105, b: 115, a: 0.4 },
]}
/>
</ColorPicker>
);
};
The color code can be displayed in editable fields for precise color selection. There are two ways to show this code: within the panel itself as seen in the example above, or in a dropdown button/input field combo, like below. If the color code is shown outside of the panel, do not include the color code within the panel at the same time.
import * as React from 'react';
import {
ColorBuilder,
ColorPalette,
ColorPicker,
ColorValue,
ButtonGroup,
ColorSwatch,
IconButton,
Button,
} from '@itwin/itwinui-react';
import { Popover } from '@itwin/itwinui-react';
import { SvgSwap } from '@itwin/itwinui-icons-react';
export default () => {
const [isOpen, setIsOpen] = React.useState(false);
const [selectedColor, setSelectedColor] = React.useState(
ColorValue.create({ h: 0, s: 100, l: 50 }),
);
const formats = ['hsl', 'rgb', 'hex'];
const [currentFormat, setCurrentFormat] = React.useState(formats[0]);
const onColorChanged = (color) => {
setSelectedColor(color);
};
const getDisplayString = (color = selectedColor) => {
switch (currentFormat) {
case 'hsl':
return color.toHslString(true);
case 'rgb':
return color.toRgbString(true);
case 'hex':
return color.toHexString(true);
}
};
return (
<>
<ButtonGroup>
<Popover
content={
<ColorPicker
selectedColor={selectedColor}
onChangeComplete={onColorChanged}
>
<ColorBuilder />
<ColorPalette
label='Saved Colors'
colors={[
{ h: 0, s: 100, l: 50 },
{ r: 255, g: 98, b: 0 },
'#fec134',
'#5A6973',
{ h: 95, s: 83, v: 72 },
{ h: 250, s: 100, l: 59 },
]}
/>
</ColorPicker>
}
portal={{ to: () => document.body }}
visible={isOpen}
onVisibleChange={setIsOpen}
placement='bottom-start'
>
<IconButton label='Show color picker'>
<ColorSwatch color={selectedColor} className='demo-color-swatch' />
</IconButton>
</Popover>
<Button
onClick={() => {
setCurrentFormat(
formats[(formats.indexOf(currentFormat) + 1) % formats.length],
);
}}
endIcon={<SvgSwap />}
>
<div className='demo-label'>
{getDisplayString() ?? 'No color selected.'}
</div>
</Button>
</ButtonGroup>
</>
);
};
Props
Prop | Description | Default |
---|---|---|
children | Content of the color palette. Pass a combination of ColorBuilder , ColorInputPanel , ColorPalette , and any custom children.ReactNode | |
selectedColor | The selected color within color picker. ColorType | ColorValue | |
onChange | Callback fired when the color value is internally updated during
operations like dragging a thumb. Use this callback with caution as a
high-volume of updates will occur when dragging. (color: ColorValue) => void | |
onChangeComplete | Callback fired when selectedColor is done changing.
This can be on pointerUp or keyUp when thumb is done dragging,
or when user clicks on color builder components, or when user clicks on color swatch. (color: ColorValue) => void | |
showAlpha | If true, ColorBuilder will show the alpha slider and ColorInputPanel will show an alpha input. boolean | false |
applyBackground | Whether there is a background, border, shadow, etc. Should be set to true if used in a popover that doesn't have its own background, or set to false if the popover has its own background or embedding within a page. boolean | true |
as | "symbol" | "object" | "search" | "big" | "link" | "small" | "sub" | "sup" | "g" | "b" | "a" | "s" | "div" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "base" | "bdi" | ... 157 more ... | FunctionComponent<...> |
Subcomponents
The color picker is extremely flexible; pieces can be used based on product requirements. If certain parts are not required for your context, they can be left out. There are no hard guidelines for what an advanced color picker contains. It should remain usable and align with the user’s workflow.
Color Builder
ColorBuilder
consists of two parts: a color canvas to adjust saturation and lightness values, and a set of sliders to adjust hue and alpha values.
Prop | Description | Default |
---|---|---|
colorFieldProps | Passes props to the color field. DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | |
colorDotProps | Passes props to the color dot. DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | |
opacitySliderProps | Passes props to the color opacity slider. Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ref?: Ref<...>; }, "as" | keyof SliderProps> & SliderProps & { ...; } | |
hueSliderProps | Passes props to the color hue slider. Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ref?: Ref<...>; }, "as" | keyof SliderProps> & SliderProps & { ...; } | |
as | "symbol" | "object" | "div" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | ... 158 more ... | FunctionComponent<...> |
Color Input Panel
ColorInputPanel
shows input fields to enter precise color values in the specified format. It also allows switching between the specified formats using a swap button.
Prop | Description | Default |
---|---|---|
defaultColorFormat | The default color format to be inputted in the panel. "hsl" | "rgb" | "hex" | |
allowedColorFormats | Color formats to switch between. The swap button will cycle between these formats. If array only has one option, then swap button will not be shown. ("hsl" | "rgb" | "hex")[] | ['hsl', 'rgb', 'hex'] |
panelLabelProps | Passes props to the color picker section label. DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | |
colorInputContainerProps | Passes props to the color input container. DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | |
inputFieldsGroupProps | Passes props to the color input fields group. DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | |
swapColorFormatButtonProps | Passes props to the swap color format button. Omit<Omit<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & { ...; }, "label" | ... 8 more ... | "iconProps"> & { ...; } & Omit<...> & { ...; } | |
as | "symbol" | "object" | "div" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | ... 158 more ... | FunctionComponent<...> |
Color Palette
ColorPalette
is used to show a group of ColorSwatch
components.
Prop | Description | Default |
---|---|---|
label | Label shown above the palette. ReactNode | |
labelProps | Passes props to the color picker section label. DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | |
colors | List of colors shown as swatches in the palette. (ColorType | ColorValue)[] | |
children | Pass any custom swatches as children. ReactNode | |
paletteContainerProps | Passes props to the color palette container. DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | |
as | "symbol" | "object" | "div" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | ... 158 more ... | FunctionComponent<...> |
Color Swatch
ColorSwatch
is a component to display within a color palette.
Prop | Description | Default |
---|---|---|
color | Color code. ColorValue | ColorType | |
isActive | Is color selected. boolean | |
as | "symbol" | "object" | "button" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "canvas" | ... 159 more ... | FunctionComponent<...> |