Presets
A preset is a named combination of axis contexts — a shortcut to a useful tuple. Configured in swatchbook.config.ts, rendered as a row of pills at the top of the toolbar popover, above the axis dropdowns.
Why
Even with per-axis dropdowns, "our landing page uses mode=Dark, brand=Brand A, contrast=Normal" is a combination you want named once and picked in one click. Presets give each common combination a label.
Defining presets
export default defineSwatchbookConfig({
tokens: ['tokens/**/*.json'],
resolver: 'tokens/resolver.json',
presets: [
{ name: 'Default Light', axes: { mode: 'Light', brand: 'Default' } },
{ name: 'Brand A Dark', axes: { mode: 'Dark', brand: 'Brand A' } },
{ name: 'A11y High Contrast', axes: { mode: 'Light', contrast: 'High' } },
],
});
Partial tuples
Any axis a preset omits falls back to that axis's default when the preset is applied. So:
{ name: 'Brand A', axes: { brand: 'Brand A' } }
On a project with mode × brand × contrast, clicking this pill selects { mode: <default>, brand: 'Brand A', contrast: <default> }. This keeps presets short and robust to adding axes later.
Toolbar behavior
- Active pill: when the current tuple exactly matches a preset (after filling in defaults), the pill renders highlighted.
- Modified indicator: after applying a preset, tweaking any axis dropdown shows a small dot next to the pill's name — a cue that you've diverged. There's no reset button; re-clicking the pill returns to its tuple.
- Order: pills render in
config.presetsorder.
Validation
At load time, each preset is sanitized:
- Unknown axis keys (
axes: { typo: 'Dark' }) produce awarndiagnostic in groupswatchbook/presetsand are dropped. - Invalid context values (
axes: { mode: 'NotARealContext' }) produce a diagnostic and the key is dropped. - Sanitized presets stay in
Project.presets— the pill still renders, it just resolves to fewer axis overrides than authored.
The diagnostics show up in the Design Tokens panel's diagnostics section (at the top of the panel) alongside any token-level issues.
Config over localStorage
Presets live in config, not in browser storage. That's deliberate:
- They're reviewable — PR diffs show when someone adds or edits a combination.
- They're shared — every teammate's Storybook renders the same pills.
- They're reproducible — screenshots and docs can reference a preset name ("this shot is Brand A Dark") without drifting across machines.
- There's no cross-machine-drift / lost-on-clear-cache surprise.
If you want ad-hoc in-session combinations, use the axis dropdowns directly.
See also
- Axes — the tuple model presets are built on.
- Reference: core — the
Presettype surface.