Color swatch picker
Picks a colour from a fixed set, for a mail tag or a select option. People pick a hue to tell things apart; they never type a hex.
Playground
Change the controls to try each prop. The code under the preview updates as you go and lists only the props you changed; copy it into your page.
import { ColorSwatchPicker } from '@/ui/color-swatch-picker';<ColorSwatchPicker label="Colour" />Swatch row
Where the colour is one field among others, as in the tag form: eight 16px dots on 24px targets. The picked one carries a white check, and the preview shows the tag as it will read.
import { useState } from 'react';
import { ColorSwatchPicker } from '@/ui/color-swatch-picker';
import { Field, FieldLabel } from '@/ui/field';
import { Input } from '@/ui/input';
import { Tag, type TagColor } from '@/ui/tag';
// The tag form: name, colour, and a preview of the tag as it will read.
export default function TagColour() {
const [name, setName] = useState('Work permit');
const [color, setColor] = useState<TagColor>('teal');
return (
<div className="flex w-full max-w-125 flex-col gap-150">
<div className="flex flex-wrap items-end gap-200">
<Field className="w-50">
<FieldLabel htmlFor="new-tag-name">New tag</FieldLabel>
<Input id="new-tag-name" value={name} onChange={(event) => setName(event.target.value)} />
</Field>
<ColorSwatchPicker value={color} onValueChange={setColor} />
</div>
<div className="flex items-center gap-100 text-body-small leading-body-small font-medium text-text-subtle">
Preview
<Tag color={color}>{name.trim() || 'Untitled tag'}</Tag>
</div>
</div>
);
}Option colour
Where the colour belongs to a pill already on screen, as a select option in field settings: the pill opens a radio list of the six option colours, each drawn as the pill would read and named by its hue.
import { OptionColorPicker } from '@/ui/color-swatch-picker';
// Field settings: each select option's pill opens its colours.
export default function OptionColour() {
return (
<div className="flex flex-wrap gap-200">
<OptionColorPicker name="Permanent" defaultValue="blue" />
<OptionColorPicker name="Contract" defaultValue="green" />
<OptionColorPicker name="Retained search" defaultValue="plum" />
</div>
);
}States
Disabled fades to 50% while the tag saves. A long option name ends in an ellipsis in its pill, with the full name in a tooltip; names in any script keep their characters.
import { ColorSwatchPicker, OptionColorPicker } from '@/ui/color-swatch-picker';
// While the tag saves, the row waits at 50%. A long option name ends in an ellipsis in its pill.
export default function States() {
return (
<div className="flex flex-col items-start gap-200">
<ColorSwatchPicker label="Colour of Visa sponsor" defaultValue="amber" disabled />
<OptionColorPicker name="Retained search with exclusivity and a staged fee" defaultValue="amber" />
<OptionColorPicker name="Nguyễn Thị Minh Khai" defaultValue="red" disabled />
</div>
);
}Code input
Six boxes for a one-time code: two-step sign-in, and the step-up check before a sensitive change. It reads as one field; typing or pasting fills the boxes in order.
Date time picker
A day and a start time as two fields side by side: the date picker and the time picker. Meetings use it, with the length beside it; times are in the agency's time zone.