Swatch
- Stable
- WCAG 2.2 evidence
- RTL
A colour sample. Inside a {@link SwatchPicker} it is an option of a React Aria
ColorSwatchPicker: arrow keys move between swatches, Enter or Space (or a click) selects, and the selected swatch
shows a text/primary ring and, from md up, a check: selection is shown by shape, not by colour (WCAG 1.4.1,
1.4.11, 2.1.1, 4.1.2). Outside a picker it is a read-only image (role="img", "color swatch"). Every swatch is named by its colour name and hex value, so colour is never the only identifier. Hover, Focused and
Selected are React Aria states (data-hovered, data-focus-visible, data-selected), not props. Consumer duties: meaningful, translated colorNames; unique colours within a picker.
import { Swatch } from "@nexera-ui/react";- 4
- examples
- 12
- props
- 3
- live controls
- 1
- platform
- 8
- WCAG criteria
- 3
- blocks use it
Try every prop. Copy the code.
Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.
import { Swatch } from "@nexera-ui/react";
<Swatch />Examples 3
The same examples as Storybook, rendered live. Open Code to copy one.
Picker
Inside a SwatchPicker the swatches are options: arrow keys move, Enter or Space selects. The selected swatch shows a ring and, from md up, a check (not colour alone).
import { useState } from "react";
import { type Color } from "react-aria-components";
import { Swatch, SwatchPicker } from "@nexera-ui/react";
const palette = [
{ color: "#04855D", name: "Emerald 600" },
{ color: "#2563EB", name: "Blue 600" },
{ color: "#D97706", name: "Amber 600" },
{ color: "#7C3AED", name: "Violet 600" },
{ color: "#0E7490", name: "Cyan 700" },
{ color: "#DB2777", name: "Pink 600" },
] as const;
export function Picker() {
const [value, setValue] = useState<string | Color>("#04855D");
return (
<div className="flex flex-col gap-3">
<SwatchPicker aria-label="Team colour" value={value} onChange={setValue}>
{palette.map((entry) => (
<Swatch
key={entry.color}
shape={args.shape ?? "circle"}
size={args.size ?? "md"}
color={entry.color}
colorName={entry.name}
isDisabled={entry.color === "#0E7490"}
/>
))}
</SwatchPicker>
<p className="m-0 text-body-small text-secondary">
Selected: {typeof value === "string" ? value : value.toString("hex")}
</p>
</div>
);
}
Shapes and sizes
Every Figma Shape and Size (26, 38 and 54 px) in a picker.
import { Swatch, SwatchPicker } from "@nexera-ui/react";
const shapes = ["circle", "square"] as const;
const sizes = ["sm", "md", "lg"] as const;
const palette = [
{ color: "#04855D", name: "Emerald 600" },
{ color: "#2563EB", name: "Blue 600" },
{ color: "#D97706", name: "Amber 600" },
{ color: "#7C3AED", name: "Violet 600" },
{ color: "#0E7490", name: "Cyan 700" },
{ color: "#DB2777", name: "Pink 600" },
] as const;
export function ShapesAndSizes() {
return (
<div className="flex flex-col gap-4">
{shapes.flatMap((shape) =>
sizes.map((size) => (
<SwatchPicker
key={`${shape}${size}`}
aria-label={`${shape} ${size}`}
defaultValue="#04855D"
>
{palette.slice(0, 4).map((entry) => (
<Swatch
key={entry.color}
shape={shape}
size={size}
color={entry.color}
colorName={entry.name}
/>
))}
</SwatchPicker>
)),
)}
</div>
);
}
Right to left
Right-to-left: the row starts on the right and the arrow keys follow the reading direction.
import { Swatch, SwatchPicker } from "@nexera-ui/react";
export function RightToLeft() {
return (
<SwatchPicker aria-label="لون الفريق" defaultValue="#2563EB">
<Swatch color="#04855D" colorName="أخضر زمردي" size="md" />
<Swatch color="#2563EB" colorName="أزرق" size="md" />
<Swatch color="#D97706" colorName="كهرماني" size="md" />
</SwatchPicker>
);
}
Props 12
Press "Try it" on a card to load that prop into the playground.
12 props shown
color*Nexerastring | ColorThe colour: a CSS colour string such as "#04855D" or a React
Aria Color. Drawn inline, because it is data. Colours inside one SwatchPicker must be unique.
colorNameNexerastringName of the colour, for example "Emerald 600". With the hex value it forms the accessible name ("Emerald 600, #04855D"), so the colour is never identified by its look alone (WCAG 1.4.1). Defaults to React Aria's localised description ("dark vibrant green"); pass your palette names and translate them.
shapeNexera"circle" | "square"Outline.
sizeNexera"sm" | "md" | "lg"Box size: 26, 38 or 54 px. The selected check is shown from md up.
isDisabledNexerabooleanWhether the swatch cannot be chosen: faded, crossed out and skipped by selection. Inside a
SwatchPicker it is announced as disabled; a standalone swatch is drawn the same way and marked aria-disabled.
classNameNexerastringExtra classes for the root, merged last so they win over the defaults.
styleNexeraCSSPropertiesInline style for the root.
onPressReact Aria(e: PressEvent) => voidHandler that is called when the press is released over the target.
onPressStartReact Aria(e: PressEvent) => voidHandler that is called when a press interaction starts.
onPressEndReact Aria(e: PressEvent) => voidHandler that is called when a press interaction ends, either over the target or when the pointer leaves the target.
onPressChangeReact Aria(isPressed: boolean) => voidHandler that is called when the press state changes.
onPressUpReact Aria(e: PressEvent) => voidHandler that is called when a press is released over the target, regardless of whether it started on the target or not.
* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.
Accessible by default.
Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.
WCAG 2.2 evidence
6 direct · 2 supporting- 1.1.1Non-text ContentLevel A · tested directly
- 1.3.1Info and RelationshipsLevel A · tested directly
- 1.4.1Use of ColorLevel A · tested directly
- 1.4.11Non-text ContrastLevel AA · supporting test
- 2.1.1KeyboardLevel A · tested directly
- 2.4.7Focus VisibleLevel AA · tested directly
- 2.5.8Target Size (Minimum)Level AA · supporting test
- 4.1.2Name, Role, ValueLevel A · tested directly
Fits any width.
Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.
Styling hooks
Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.
data-disableddata-hovereddata-selected
<Swatch className="data-disabled:opacity-90 shadow-sm" />Used in blocks
Related components
- CalendarDayOne day of a {@link CalendarMonth } grid, built on React Aria `CalendarCell`: a `gridcell` whose button is named by the full, localised date ("Wednesday, October 14, 2026"), with `aria-selected`, `aria-disabled` and the "today" and range descriptions read by screen readers (WCAG 1.3.1, 4.1.2).
- CalendarMonthA month calendar for picking a date or a date range: header with previous / next buttons and the localised month name, weekday row, and six weeks of `CalendarDay`s.
- CheckboxThe bare 18 px checkbox: one independent yes/no choice applied on submit, or a row selector in a table, list or tree.
- CheckboxCardA large checkbox option with an icon, a title and a description, for a few options that need explanation (notification channels, benefits).
- CheckboxFieldA checkbox with a label and optional helper text: the box (the same element as `Checkbox`) followed by the label and description, applied on submit.
- ColorInputA hex colour field with a swatch and a picker popover.
- ColorPickerPicks a colour.
- ColorTokenCardDocumentation card for one colour token: a 96 px colour sample with an "Aa" text sample, then the name, token path, hex value and contrast note as text.