Swatch picker
View .mdA swatch picker lets people choose a color, image, or pattern in graphic and text editors.
Default
Loading interactive example. Full source is available below.
View example source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import * as React from 'react';
import type { SwatchPickerOnSelectEventHandler } from "@coreai-ds/react-components";
import { SwatchPicker } from "@coreai-ds/react-components";
import { ColorSwatch } from "@coreai-ds/react-components";
export const Default = () => {
const [selectedValue, setSelectedValue] = React.useState('00B053');
const [selectedColor, setSelectedColor] = React.useState('#00B053');
const handleSelect: SwatchPickerOnSelectEventHandler = (_, data) => {
setSelectedValue(data.selectedValue);
setSelectedColor(data.selectedSwatch);
};
const styles = /* css */ `
.swatch-picker-default-example__preview {
width: 100px;
height: 100px;
border: var(--strokeWidthThin) solid var(--colorNeutralStroke1);
margin: var(--spacingVerticalL) 0;
}
@media (forced-colors: active) {
.swatch-picker-default-example__preview {
forced-color-adjust: none;
}
}
`;
return (<>
<style>{styles}</style>
<div className="swatch-picker-default-example">
<SwatchPicker aria-label="SwatchPicker default" selectedValue={selectedValue} onSelectionChange={handleSelect}>
<ColorSwatch color="#FF1921" value="FF1921" aria-label="red"/>
<ColorSwatch color="#FF7A00" value="FF7A00" aria-label="orange"/>
<ColorSwatch color="#90D057" value="90D057" aria-label="light green"/>
<ColorSwatch color="#00B053" value="00B053" aria-label="green"/>
<ColorSwatch color="#00AFED" value="00AFED" aria-label="light blue"/>
<ColorSwatch color="#006EBD" value="006EBD" aria-label="blue"/>
<ColorSwatch disabled color="#011F5E" value="011F5E" aria-label="dark blue"/>
<ColorSwatch color="#712F9E" value="712F9E" aria-label="purple"/>
</SwatchPicker>
<div className="swatch-picker-default-example__preview" style={{ backgroundColor: selectedColor }}/>
</div>
</>);
};
export default Default;
Resources
Best practices
Do
- Use no more than eight swatches in a row.
- Use a grid for more than four swatches, capped at an 8×8 grid.
- Show a tooltip for each color.
- Provide labels through aria-label or a tooltip.
Don't
- Use rounded corners in grid layouts.
- Space extra-small or smaller swatches less than 4px apart.
- Display more than four disabled swatches.
Behavior and states
- The SwatchPicker can be integrated within a popover or used as a standalone feature.
API referenceGenerated CoreAI prop and type summaries
API
Generated CoreAI prop summaries, not replacement type declarations. Most native DOM/event and ARIA props are omitted. ? means optional; JSDoc shows defaults, deprecations, and conditional requirements. Defaults assume the standard CoreAI provider.
SwatchPicker API
interface SwatchPickerProps {
as?: "div";
children?: any;
className?: string;
/**
* Default selected value
*/
defaultSelectedValue?: string;
/**
* Sets the focus behavior for the SwatchPicker.
*
* `arrow`
* This behavior will cycle through all elements inside of the SwatchPicker when pressing the Arrow key.
*
* `tab`
* This behavior will cycle through all elements inside of the SwatchPicker when pressing the Tab key.
* @default 'arrow'
*/
focusMode?: "tab" | "arrow";
/**
* Whether SwatchPicker is row or grid
*/
layout?: "grid" | "row";
/**
* Triggers a callback when the value has been changed
*/
onSelectionChange?: EventHandler<SwatchPickerOnSelectionChangeData>;
ref?: Ref<HTMLDivElement>;
/**
* Controlled selected value
*/
selectedValue?: string;
/**
* Swatch shape.
* @default 'rounded'
*/
shape?: "circular" | "rounded" | "square";
/**
* Swatch size
*/
size?: "small" | "medium" | "large" | "extra-small";
/**
* Spacing between swatches
*/
spacing?: "small" | "medium";
style?: CSSProperties;
}
ColorSwatch API
ColorSwatch component is used to render a colors, icons and gradients.
interface ColorSwatchProps {
as?: "button";
/**
* Border color when contrast is low
*/
borderColor?: string;
children?: any;
className?: string;
/**
* Swatch color
*/
color?: string;
/**
* Whether the swatch is disabled
*/
disabled?: boolean;
disabledIcon?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
icon?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
ref?: Ref<HTMLButtonElement>;
/**
* Swatch shape
*/
shape?: "circular" | "rounded" | "square";
/**
* Swatch size
*/
size?: "small" | "medium" | "large" | "extra-small";
style?: CSSProperties;
/**
* Swatch value
*/
value?: string | number | readonly string[];
}
EmptySwatch API
EmptySwatch component is used for adding new color swatches.
interface EmptySwatchProps {
as?: "button";
children?: any;
className?: string;
ref?: Ref<HTMLButtonElement>;
/**
* Swatch shape
*/
shape?: "circular" | "rounded" | "square";
/**
* Swatch size
*/
size?: "small" | "medium" | "large" | "extra-small";
style?: CSSProperties;
}
ImageSwatch API
ImageSwatch component is used to render an images, patterns and textures.
interface ImageSwatchProps {
as?: "button";
children?: any;
className?: string;
ref?: Ref<HTMLButtonElement>;
/**
* Swatch shape
*/
shape?: "circular" | "rounded" | "square";
/**
* Swatch size
*/
size?: "small" | "medium" | "large" | "extra-small";
/**
* Swatch color
*/
src: string;
style?: CSSProperties;
/**
* Swatch value
*/
value?: string | number | readonly string[];
}
SwatchPickerRow API
SwatchPickerRow component is used to render a row of swatches.
interface SwatchPickerRowProps {
as?: "div";
children?: any;
className?: string;
ref?: Ref<HTMLDivElement>;
style?: CSSProperties;
}
Implementation
CoreAI 0.12.0; Fluent 9.74.9.
Import components from @coreai-ds/react-components. CoreAI guidance above takes precedence over API demonstration examples.
Color Swatch Variants
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { ColorSwatch } from "@coreai-ds/react-components";
import { HeartFilled } from "@fluentui/react-icons";
import * as React from 'react';
const useStyles = makeStyles({
example: {
display: 'flex',
gap: '8px',
},
icon: {
'@media (forced-colors: active)': {
forcedColorAdjust: 'none',
},
},
});
export const ColorSwatchVariants = (): JSXElement => {
const styles = useStyles();
return (<div className={styles.example}>
<ColorSwatch color="#E3008C" value="hot-pink-color" aria-label="Hot pink"/>
<ColorSwatch color="linear-gradient(0deg, #E3008C, #fff232)" value="gradient" aria-label="Gradient yellow pink"/>
<ColorSwatch color="#c8eeff" icon={<HeartFilled color="red" className={styles.icon}/>} value="icon" aria-label="heart icon"/>
<ColorSwatch color="#016ab0" disabled value="blue" aria-label="blue"/>
<ColorSwatch color="#ff659a" value="initials" aria-label="initials">
A
</ColorSwatch>
<ColorSwatch disabled color="#c8eeff" value="light-blue" aria-label="light blue"/>
</div>);
};
export default ColorSwatchVariants;
Empty Swatch Example
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import * as React from 'react';
import { tinycolor } from "@ctrl/tinycolor";
import type { ColorPickerProps } from "@coreai-ds/react-components";
import type { SwatchPickerOnSelectEventHandler } from "@coreai-ds/react-components";
import { SwatchPicker } from "@coreai-ds/react-components";
import { ColorSwatch } from "@coreai-ds/react-components";
import { EmptySwatch } from "@coreai-ds/react-components";
import { Popover } from "@coreai-ds/react-components";
import { PopoverTrigger } from "@coreai-ds/react-components";
import { Tooltip } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { PopoverSurface } from "@coreai-ds/react-components";
import { ColorPicker } from "@coreai-ds/react-components";
import { ColorArea } from "@coreai-ds/react-components";
import { ColorSlider } from "@coreai-ds/react-components";
import { AlphaSlider } from "@coreai-ds/react-components";
const useStyles = makeStyles({
example: {
width: '300px',
display: 'flex',
flexDirection: 'column',
gap: '10px',
},
selectedColor: {
width: '100px',
height: '100px',
border: '1px solid #ccc',
margin: '20px 0',
'@media (forced-colors: active)': {
forcedColorAdjust: 'none',
},
},
button: {
marginRight: '8px',
},
previewColor: {
margin: '10px 0',
width: '50px',
height: '50px',
borderRadius: '4px',
border: '1px solid #ccc',
},
previewButton: {
minWidth: '50px',
height: '50px',
display: 'block',
margin: '10px 0',
},
rowWrapper: {
display: 'flex',
gap: '10px',
},
sliders: {
display: 'flex',
flexDirection: 'column',
},
});
const DEFAULT_COLOR_HSV = tinycolor('#2be700').toHsv();
const defaultItems = [
{ color: '#FF1921', value: 'FF1921', 'aria-label': 'red' },
{ color: '#FF7A00', value: 'FF7A00', 'aria-label': 'dark orange' },
{ color: '#90D057', value: '90D057', 'aria-label': 'light green' },
{ color: '#00B053', value: '00B053', 'aria-label': 'green' },
];
const ITEMS_LIMIT = 8;
export const EmptySwatchExample = (): JSXElement => {
const styles = useStyles();
const [selectedValue, setSelectedValue] = React.useState('00B053');
const [selectedColor, setSelectedColor] = React.useState('#00B053');
const [popoverOpen, setPopoverOpen] = React.useState(false);
const [previewColor, setPreviewColor] = React.useState(DEFAULT_COLOR_HSV);
const [color, setColor] = React.useState(DEFAULT_COLOR_HSV);
const colorFocusTargetRef = React.useRef<HTMLButtonElement>(null);
const [colorFocusTarget, setColorFocusTarget] = React.useState<string | null>(null);
const [items, setItems] = React.useState<Array<{
color: string;
value: string;
'aria-label': string;
}>>(defaultItems);
const emptyItems = new Array(ITEMS_LIMIT - items.length).fill(null);
const handleChange: ColorPickerProps['onColorChange'] = (_, data) => {
setPreviewColor({ ...data.color, a: data.color.a ?? 1 });
};
const handleSelect: SwatchPickerOnSelectEventHandler = (_, data) => {
setSelectedValue(data.selectedValue);
setSelectedColor(data.selectedSwatch);
};
const handleAddColor = () => {
const newColor = tinycolor(color).toRgbString();
// "value" should be unique as it's used as a key and for selection
const newValue = `custom-${newColor} [${items.length - ITEMS_LIMIT}]`;
setItems([...items, { color: newColor, value: newValue, 'aria-label': newColor }]);
setColorFocusTarget(newValue);
};
const resetColors = () => {
setItems(defaultItems);
setColorFocusTarget(selectedValue);
};
React.useEffect(() => {
if (colorFocusTarget) {
colorFocusTargetRef.current?.focus();
}
}, [colorFocusTarget]);
return (<>
<SwatchPicker aria-label="SwatchPicker with empty swatches" selectedValue={selectedValue} onSelectionChange={handleSelect}>
{items.map(item => (<ColorSwatch key={item.value} ref={item.value === colorFocusTarget ? colorFocusTargetRef : null} {...item}/>))}
{emptyItems.map((_, index) => (<EmptySwatch disabled key={index} aria-label="empty swatch"/>))}
</SwatchPicker>
<h4>Selected swatch</h4>
<div className={styles.selectedColor} style={{ backgroundColor: selectedColor }}/>
<Popover open={popoverOpen} trapFocus onOpenChange={(_, data) => setPopoverOpen(data.open)}>
<PopoverTrigger disableButtonEnhancement>
<Tooltip content="Custom color" relationship="label">
<Button className={styles.previewButton} style={{ backgroundColor: tinycolor(color).toRgbString() }}/>
</Tooltip>
</PopoverTrigger>
<PopoverSurface>
<ColorPicker color={previewColor} onColorChange={handleChange}>
<ColorArea />
<div className={styles.rowWrapper}>
<div className={styles.sliders}>
<ColorSlider />
<AlphaSlider />
</div>
<div className={styles.previewColor} style={{ backgroundColor: tinycolor(previewColor).toRgbString() }}/>
</div>
</ColorPicker>
<div className={styles.rowWrapper}>
<Button appearance="primary" onClick={() => {
setColor(previewColor);
setPopoverOpen(false);
}}>
Ok
</Button>
<Button onClick={() => {
setPopoverOpen(false);
}}>
Cancel
</Button>
</div>
</PopoverSurface>
</Popover>
<Button id="components-swatchpicker--empty-swatch-example-add-new-color" className={styles.button} appearance="primary" disabled={items.length >= ITEMS_LIMIT} onClick={handleAddColor}>
Add new color
</Button>
<Button id="components-swatchpicker--empty-swatch-example-reset-example" className={styles.button} onClick={resetColors}>
Reset example
</Button>
</>);
};
export default EmptySwatchExample;
Swatch Picker Focus Mode
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { SwatchPickerOnSelectEventHandler } from "@coreai-ds/react-components";
import { SwatchPicker } from "@coreai-ds/react-components";
import { ColorSwatch } from "@coreai-ds/react-components";
const colors = [
{ color: '#FF1921', value: 'FF1921', 'aria-label': 'red' },
{ color: '#FF7A00', value: 'FF7A00', 'aria-label': 'orange' },
{ color: '#90D057', value: '90D057', 'aria-label': 'light green' },
{ color: '#00B053', value: '00B053', 'aria-label': 'green' },
{ color: '#00AFED', value: '00AFED', 'aria-label': 'light blue' },
{ color: '#006EBD', value: '006EBD', 'aria-label': 'blue' },
];
export const SwatchPickerFocusMode = (): JSXElement => {
const [selectedValue, setSelectedValue] = React.useState('00B053');
const handleSelect: SwatchPickerOnSelectEventHandler = (_, data) => {
setSelectedValue(data.selectedValue);
};
return (<>
<h3>Arrow navigation (default)</h3>
<SwatchPicker focusMode="arrow" aria-label="SwatchPicker with arrow navigation" selectedValue={selectedValue} onSelectionChange={handleSelect}>
{colors.map(color => (<ColorSwatch key={color.value} {...color}/>))}
</SwatchPicker>
<h3>Tab navigation</h3>
<SwatchPicker focusMode="tab" aria-label="SwatchPicker with tab navigation" selectedValue={selectedValue} onSelectionChange={handleSelect}>
{colors.map(color => (<ColorSwatch key={color.value} {...color}/>))}
</SwatchPicker>
</>);
};
export default SwatchPickerFocusMode;
Swatch Picker Image
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { SwatchPickerOnSelectEventHandler } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { SwatchPicker } from "@coreai-ds/react-components";
import { ImageSwatch } from "@coreai-ds/react-components";
const DEFAULT_IMAGE = 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/bridge-full-img.jpg';
const images = [
{
swatchSrc: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/sea-swatch.jpg',
value: '0',
label: 'sea',
fullImageSrc: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/sea-full-img.jpg',
},
{
swatchSrc: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/bridge-swatch.jpg',
value: '1',
label: 'bridge',
fullImageSrc: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/bridge-full-img.jpg',
},
{
swatchSrc: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/park-swatch.jpg',
value: '2',
label: 'park',
fullImageSrc: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/park-full-img.jpg',
},
];
const useStyles = makeStyles({
example: {
width: '100%',
height: '466px',
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
margin: '20px 0',
},
swatch: {
width: '100px',
height: '100px',
'@media (max-width: 768px)': {
width: '50px',
height: '50px',
},
},
});
export const SwatchPickerImage = (): JSXElement => {
const [selectedValue, setSelectedValue] = React.useState('1');
const [selectedImage, setSelectedImage] = React.useState(DEFAULT_IMAGE);
const handleSelect: SwatchPickerOnSelectEventHandler = (_, data) => {
setSelectedValue(data.selectedValue);
const image = images.find(img => img.value === data.selectedValue) || images[0];
setSelectedImage(image.fullImageSrc);
};
const styles = useStyles();
return (<>
<SwatchPicker aria-label="SwatchPicker with images" selectedValue={selectedValue} onSelectionChange={handleSelect}>
{images.map(image => (<ImageSwatch className={styles.swatch} key={image.value} src={image.swatchSrc} value={image.value} aria-label={image.label}/>))}
</SwatchPicker>
<div className={styles.example} style={{
backgroundImage: `url(${selectedImage})`,
}}/>
</>);
};
export default SwatchPickerImage;
Swatch Picker Layout
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { SwatchPickerOnSelectEventHandler } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { SwatchPicker } from "@coreai-ds/react-components";
import { ColorSwatch } from "@coreai-ds/react-components";
import { renderSwatchPickerGrid } from "@coreai-ds/react-components";
const useStyles = makeStyles({
example: {
width: '100px',
height: '100px',
border: '1px solid #ccc',
margin: '20px 0',
'@media (forced-colors: active)': {
forcedColorAdjust: 'none',
},
},
});
const colors = [
{ color: '#FF1921', value: 'FF1921', 'aria-label': 'red' },
{ color: '#FF7A00', value: 'FF7A00', 'aria-label': 'orange' },
{ color: '#90D057', value: '90D057', 'aria-label': 'light green' },
{ color: '#00B053', value: '00B053', 'aria-label': 'green' },
{ color: '#00AFED', value: '00AFED', 'aria-label': 'light blue' },
{ color: '#006EBD', value: '006EBD', 'aria-label': 'blue' },
{ color: '#011F5E', value: '011F5E', 'aria-label': 'dark blue' },
{ color: '#712F9E', value: '712F9E', 'aria-label': 'purple' },
{ color: '#FF0099', value: 'FF0099', 'aria-label': 'pink' },
];
export const SwatchPickerLayout = (): JSXElement => {
const [selectedValue, setSelectedValue] = React.useState('00B053');
const [selectedSwatch, setSelectedSwatch] = React.useState('#00B053');
const handleSelect: SwatchPickerOnSelectEventHandler = (_, data) => {
setSelectedValue(data.selectedValue);
setSelectedSwatch(data.selectedSwatch);
};
const styles = useStyles();
return (<>
<h3>Row</h3>
<SwatchPicker aria-label="SwatchPicker row layout" selectedValue={selectedValue} onSelectionChange={handleSelect}>
{colors.map(color => {
return <ColorSwatch key={color.value} {...color}/>;
})}
</SwatchPicker>
<h3>Grid</h3>
<SwatchPicker layout="grid" aria-label="SwatchPicker grid layout" selectedValue={selectedValue} onSelectionChange={handleSelect}>
{renderSwatchPickerGrid({
items: colors,
columnCount: 3,
})}
</SwatchPicker>
<div className={styles.example} style={{
background: selectedSwatch,
}}/>
</>);
};
export default SwatchPickerLayout;
Swatch Picker Mixed Swatches
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { SwatchPickerOnSelectEventHandler } from "@coreai-ds/react-components";
import type { SwatchProps } from "@coreai-ds/react-components";
import type { ColorSwatchProps } from "@coreai-ds/react-components";
import type { ImageSwatchProps } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { SwatchPicker } from "@coreai-ds/react-components";
import { renderSwatchPickerGrid } from "@coreai-ds/react-components";
const colors: ColorSwatchProps[] = [
{ color: '#FF1921', value: 'FF1921', 'aria-label': 'red' },
{ color: '#FF7A00', value: 'FF7A00', 'aria-label': 'orange' },
{ color: '#90D057', value: '90D057', 'aria-label': 'light green' },
{ color: '#00B053', value: '00B053', 'aria-label': 'green' },
{ color: '#00AFED', value: '00AFED', 'aria-label': 'light blue' },
{ color: '#006EBD', value: '006EBD', 'aria-label': 'blue' },
];
const images: ImageSwatchProps[] = [
{
src: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/sea-swatch.jpg',
value: 'sea',
'aria-label': 'sea',
},
{
src: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/bridge-swatch.jpg',
value: 'bridge',
'aria-label': 'bridge',
},
{
src: 'https://fabricweb.azureedge.net/fabric-website/assets/images/swatch-picker/park-swatch.jpg',
value: 'park',
'aria-label': 'park',
},
];
const items: SwatchProps[] = [...colors, ...images];
const useStyles = makeStyles({
example: {
width: '100px',
height: '100px',
border: '1px solid #ccc',
margin: '20px 0',
'@media (forced-colors: active)': {
forcedColorAdjust: 'none',
},
},
});
export const SwatchPickerMixedSwatches = (): JSXElement => {
const [selectedValue, setSelectedValue] = React.useState('00B053');
const [selectedSwatch, setSelectedSwatch] = React.useState('#00B053');
const handleSelect: SwatchPickerOnSelectEventHandler = (_, data) => {
setSelectedValue(data.selectedValue);
const swatch = items.find(item => item.value === data.selectedValue) || items[0];
const src = (swatch as ImageSwatchProps).src;
if (swatch.color) {
setSelectedSwatch(swatch.color);
}
else if (src) {
setSelectedSwatch(`url(${src}`);
}
};
const styles = useStyles();
return (<>
<SwatchPicker layout="grid" aria-label="SwatchPicker with both colors and images" selectedValue={selectedValue} onSelectionChange={handleSelect}>
{renderSwatchPickerGrid({
items,
columnCount: 3,
})}
</SwatchPicker>
<div className={styles.example} style={{
background: selectedSwatch,
}}/>
</>);
};
export default SwatchPickerMixedSwatches;
Swatch Picker Popup
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { SwatchPickerOnSelectEventHandler } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Popover } from "@coreai-ds/react-components";
import { PopoverTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { PopoverSurface } from "@coreai-ds/react-components";
import { SwatchPicker } from "@coreai-ds/react-components";
import { ColorSwatch } from "@coreai-ds/react-components";
import { renderSwatchPickerGrid } from "@coreai-ds/react-components";
const useStyles = makeStyles({
example: {
width: '100px',
height: '100px',
border: '1px solid #ccc',
margin: '20px 0',
'@media (forced-colors: active)': {
forcedColorAdjust: 'none',
},
},
});
const colorSet1 = [
{ color: '#FF1921', value: 'FF1921', 'aria-label': 'red' },
{ color: '#00B053', value: '00B053', 'aria-label': 'green' },
{ color: '#00AFED', value: '00AFED', 'aria-label': 'light blue' },
{ color: '#006EBD', value: '006EBD', 'aria-label': 'blue' },
{ color: '#712F9E', value: '712F9E', 'aria-label': 'purple' },
];
const colorSet2 = [
{ color: '#FF7A00', value: 'FF7A00', 'aria-label': 'dark orange' },
{ color: '#90D057', value: '90D057', 'aria-label': 'light green' },
{ color: '#3BC4F5', value: '3BC4F5', 'aria-label': 'light blue 10' },
{ color: '#1F93E6', value: '1F93E6', 'aria-label': 'blue 10' },
{ color: '#A01CFa', value: 'A01CFa', 'aria-label': 'bright purple' },
{
color: 'linear-gradient(0deg, #FF1921, #FFB92E)',
value: 'orange-red',
'aria-label': 'gradient orange-red',
},
{
color: 'linear-gradient(0deg, #00B053, #90D057)',
value: 'light-green-gradient',
'aria-label': 'gradient light green',
},
{
color: 'linear-gradient(0deg, #006EBD, #00AFED)',
value: 'blue gradient',
'aria-label': 'gradient blue',
},
{
color: 'linear-gradient(0deg, #712F9E, #00AFED)',
value: 'blue-purple',
'aria-label': 'gradient blue-purple',
},
{
color: 'linear-gradient(0deg, #fA1CBC, #A01CFa)',
value: 'blue-purple',
'aria-label': 'gradient pink-purple',
},
{
color: 'linear-gradient(0deg, #FFC12E, #FEFF37)',
value: 'yellow-orange',
'aria-label': 'gradient yellow-orange',
},
{
color: 'linear-gradient(0deg, #90D057, #FEFF37)',
value: 'yellow-green',
'aria-label': 'gradient yellow-green',
},
{
color: 'linear-gradient(0deg, #00B053, #00AFED)',
value: 'green-blue',
'aria-label': 'gradient green-blue',
},
{
color: 'linear-gradient(0deg, #A01CFA, #00AFED)',
value: 'blue-purple gradient',
'aria-label': 'gradient blue',
},
{
color: 'linear-gradient(0deg, #FF1921 0%, #FFC12E 10%, #FEFF37 20%, #90D057 30%, #00B053 40%, #00AFED 50%, #006EBD 60%, #011F5E 70%, #712F9E 80%)',
value: 'gradient',
'aria-label': 'gradient rainbow',
},
];
export const SwatchPickerPopup = (): JSXElement => {
const [selectedValue, setSelectedValue] = React.useState('00B053');
const [selectedColor, setSelectedColor] = React.useState('#00B053');
const [popoverOpen, setPopoverOpen] = React.useState(false);
const handleSelect: SwatchPickerOnSelectEventHandler = (_, data) => {
setSelectedValue(data.selectedValue);
setSelectedColor(data.selectedSwatch);
setPopoverOpen(false);
};
const styles = useStyles();
return (<>
<Popover open={popoverOpen} trapFocus onOpenChange={(_, data) => setPopoverOpen(data.open)}>
<PopoverTrigger disableButtonEnhancement>
<Button>Choose color</Button>
</PopoverTrigger>
<PopoverSurface>
<h3>Color set 1</h3>
<SwatchPicker aria-label="SwatchPicker set 1" selectedValue={selectedValue} onSelectionChange={handleSelect}>
{colorSet1.map((color, index) => {
return <ColorSwatch key={`${color.value}-${index}`} {...color}/>;
})}
</SwatchPicker>
<h3>Color set 2</h3>
<SwatchPicker layout="grid" aria-label="SwatchPicker set 2" selectedValue={selectedValue} onSelectionChange={handleSelect}>
{renderSwatchPickerGrid({
items: colorSet2,
columnCount: 5,
})}
</SwatchPicker>
</PopoverSurface>
</Popover>
<div className={styles.example} style={{
background: selectedColor,
}}/>
</>);
};
export default SwatchPickerPopup;
Swatch Picker Shape
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { SwatchPicker } from "@coreai-ds/react-components";
import { ColorSwatch } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
example: {
display: 'flex',
flexDirection: 'column',
gap: '10px',
},
});
const colors = [
{ color: '#FF1921', value: 'FF1921', 'aria-label': 'red' },
{ color: '#FF7A00', value: 'FF7A00', 'aria-label': 'dark orange' },
{ color: '#FFC12E', value: 'FFC12E', 'aria-label': 'orange' },
{ color: '#90D057', value: '90D057', 'aria-label': 'light green' },
{ color: '#00B053', value: '00B053', 'aria-label': 'green' },
{ color: '#00AFED', value: '00AFED', 'aria-label': 'light blue' },
{ color: '#006EBD', value: '006EBD', 'aria-label': 'blue' },
{ color: '#011F5E', value: '011F5E', 'aria-label': 'dark blue' },
{ color: '#712F9E', value: '712F9E', 'aria-label': 'purple' },
];
export const SwatchPickerShape = (): JSXElement => {
const styles = useStyles();
return (<div className={styles.example}>
<h3>Square</h3>
<SwatchPicker aria-label="SwatchPicker square shape">
{colors.map(color => (<ColorSwatch key={color.value} {...color}/>))}
</SwatchPicker>
<h3>Circular</h3>
<SwatchPicker aria-label="SwatchPicker circular shape" shape="circular">
{colors.map(color => (<ColorSwatch key={color.value} {...color}/>))}
</SwatchPicker>
<h3>Rounded</h3>
<SwatchPicker aria-label="SwatchPicker rounded shape" shape="rounded">
{colors.map(color => (<ColorSwatch key={color.value} {...color}/>))}
</SwatchPicker>
</div>);
};
export default SwatchPickerShape;
Swatch Picker Size
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { SwatchPicker } from "@coreai-ds/react-components";
import { ColorSwatch } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
example: {
display: 'flex',
flexDirection: 'column',
gap: '10px',
},
});
const colors = [
{ color: '#FF1921', value: 'FF1921', 'aria-label': 'red' },
{ color: '#FF7A00', value: 'FF7A00', 'aria-label': 'orange' },
{ color: '#90D057', value: '90D057', 'aria-label': 'light green' },
{ color: '#00B053', value: '00B053', 'aria-label': 'green' },
{ color: '#00AFED', value: '00AFED', 'aria-label': 'light blue' },
{ color: '#006EBD', value: '006EBD', 'aria-label': 'blue' },
{ color: '#011F5E', value: '011F5E', 'aria-label': 'dark blue' },
{ color: '#712F9E', value: '712F9E', 'aria-label': 'purple' },
];
export const SwatchPickerSize = (): JSXElement => {
const styles = useStyles();
return (<div className={styles.example}>
<h3>Large</h3>
<SwatchPicker aria-label="SwatchPicker large size" size="large">
{colors.map(color => {
return <ColorSwatch key={color.value} {...color}/>;
})}
</SwatchPicker>
<h3>Medium</h3>
<SwatchPicker aria-label="SwatchPicker medium size">
{colors.map(color => {
return <ColorSwatch key={color.value} {...color}/>;
})}
</SwatchPicker>
<h3>Small</h3>
<SwatchPicker aria-label="SwatchPicker small size" size="small">
{colors.map(color => {
return <ColorSwatch key={color.value} {...color}/>;
})}
</SwatchPicker>
<h3>Extra small</h3>
<SwatchPicker aria-label="SwatchPicker extra small size" size="extra-small">
{colors.map(color => {
return <ColorSwatch key={color.value} {...color}/>;
})}
</SwatchPicker>
</div>);
};
export default SwatchPickerSize;
Swatch Picker Spacing
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { SwatchPicker } from "@coreai-ds/react-components";
import { renderSwatchPickerGrid } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
example: {
display: 'flex',
flexDirection: 'column',
gap: '10px',
},
});
const colors = [
{ color: '#FF1921', value: 'FF1921', 'aria-label': 'red' },
{ color: '#FF7A00', value: 'FF7A00', 'aria-label': 'dark orange' },
{ color: '#FFC12E', value: 'FFC12E', 'aria-label': 'orange' },
{ color: '#90D057', value: '90D057', 'aria-label': 'light green' },
{ color: '#00B053', value: '00B053', 'aria-label': 'green' },
{ color: '#00AFED', value: '00AFED', 'aria-label': 'light blue' },
{ color: '#006EBD', value: '006EBD', 'aria-label': 'blue' },
{ color: '#011F5E', value: '011F5E', 'aria-label': 'dark blue' },
{ color: '#712F9E', value: '712F9E', 'aria-label': 'purple' },
];
export const SwatchPickerSpacing = (): JSXElement => {
const styles = useStyles();
return (<div className={styles.example}>
<h3>Medium</h3>
<SwatchPicker layout="grid" aria-label="SwatchPicker medium spacing">
{renderSwatchPickerGrid({
items: colors,
columnCount: 3,
})}
</SwatchPicker>
<h3>Small</h3>
<SwatchPicker layout="grid" aria-label="SwatchPicker small spacing" spacing="small">
{renderSwatchPickerGrid({
items: colors,
columnCount: 3,
})}
</SwatchPicker>
</div>);
};
export default SwatchPickerSpacing;
Swatch Picker With Tooltip
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import type { SwatchPickerOnSelectEventHandler } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { SwatchPicker } from "@coreai-ds/react-components";
import type { ColorSwatchProps } from "@coreai-ds/react-components";
import { Tooltip } from "@coreai-ds/react-components";
import { ColorSwatch } from "@coreai-ds/react-components";
import { renderSwatchPickerGrid } from "@coreai-ds/react-components";
import type { SwatchProps } from "@coreai-ds/react-components";
const useStyles = makeStyles({
example: {
width: '100px',
height: '100px',
border: '1px solid #ccc',
margin: '20px 0',
'@media (forced-colors: active)': {
forcedColorAdjust: 'none',
},
},
});
const colors = [
{ color: '#FF1921', value: 'FF1921', 'aria-label': 'red' },
{ color: '#FF7A00', value: 'FF7A00', 'aria-label': 'orange' },
{ color: '#90D057', value: '90D057', 'aria-label': 'light green' },
{ color: '#00B053', value: '00B053', 'aria-label': 'green' },
{ color: '#00AFED', value: '00AFED', 'aria-label': 'light blue' },
{ color: '#006EBD', value: '006EBD', 'aria-label': 'blue' },
{ color: '#011F5E', value: '011F5E', 'aria-label': 'dark blue' },
{ color: '#712F9E', value: '712F9E', 'aria-label': 'purple' },
{ color: '#FF0099', value: 'FF0099', 'aria-label': 'pink' },
];
const ColorSwatchWithTooltip = (props: ColorSwatchProps) => {
const { color, value } = props;
const label = props['aria-label'] ?? 'color swatch';
return (<Tooltip withArrow content={label} relationship="label">
<ColorSwatch color={color} value={value}/>
</Tooltip>);
};
export const SwatchPickerWithTooltip = (): JSXElement => {
const [selectedValue, setSelectedValue] = React.useState('00B053');
const [selectedColor, setSelectedColor] = React.useState('#00B053');
const handleSelect: SwatchPickerOnSelectEventHandler = (_, data) => {
setSelectedValue(data.selectedValue);
setSelectedColor(data.selectedSwatch);
};
const styles = useStyles();
return (<>
<h3>Row layout</h3>
<SwatchPicker aria-label="SwatchPicker row layout" selectedValue={selectedValue} onSelectionChange={handleSelect}>
{colors.map(color => {
return <ColorSwatchWithTooltip key={color.value} {...color}/>;
})}
</SwatchPicker>
<h3>Grid layout</h3>
<SwatchPicker layout="grid" aria-label="SwatchPicker grid layout" selectedValue={selectedValue} onSelectionChange={handleSelect}>
{renderSwatchPickerGrid({
items: colors,
columnCount: 3,
renderSwatch: ({ color = '', ...item }: SwatchProps) => (<ColorSwatchWithTooltip key={item.value} color={color} {...item}/>),
})}
</SwatchPicker>
<div className={styles.example} style={{
backgroundColor: selectedColor,
}}/>
</>);
};
export default SwatchPickerWithTooltip;