What swatchbook is
A Storybook addon and MDX doc blocks for visualising DTCG design tokens, built on Terrazzo’s parser. Your production build runs Terrazzo’s CLI against the same DTCG source; swatchbook reads it too, inside Storybook, and keeps the two aligned.
The package contains two things:
- Doc blocks. React components for MDX:
TokenDetail,TokenTable,TokenNavigator,ColorPalette,TypographyScale, and per-type previews for motion, shadow, border, gradient, stroke style. - A toolbar theme switcher. One dropdown per modifier axis in your DTCG resolver. Flip mode, brand, contrast, density (whatever your system has) and tokens repaint live.
Stories that already style with swatchbook’s token CSS variables pick up the switcher’s flips without further wiring.
Who it’s for
Section titled “Who it’s for”Design-system authors with DTCG tokens, especially systems with more than one independent dimension (brand × mode, contrast × mode, density).
Preview host, not transformer
Section titled “Preview host, not transformer”swatchbook is the preview side of a DTCG pipeline. It parses tokens, displays them inside Storybook, and reacts to axis flips from a toolbar. It does not transform tokens for production platforms; that is what a consumer’s @terrazzo/cli (or Style Dictionary, or comparable) build is for.
- Terrazzo CLI runs at build time, takes DTCG sources, and emits CSS / Swift / Android / JS / Sass for production consumption.
- swatchbook runs at Storybook preview time, reads the same DTCG sources, and renders interactive previews of what the production build produces.
A consumer maintains one DTCG source of truth, and both tools read from it. swatchbook’s preview-time loader reuses Terrazzo’s parser end-to-end, so the $value shapes, $type semantics, alias forms, and resolver schema all come from Terrazzo; swatchbook does not introduce its own DTCG dialect. The Aligning with your token build guide describes how the two coordinate through shared terrazzo.config.ts fields.
When a feature request frames swatchbook as owning transform logic, custom naming schemes, or a competing plugin protocol, the right answer is usually “point Terrazzo CLI at the same sources and read its output via the token listing.”
Tuples
Section titled “Tuples”Theming state is addressed by dimension, not by a flat ID: each independent dimension (mode, brand, contrast, density) is an axis, and picking one context per axis gives a tuple:
{ mode: 'Dark', brand: 'Brand A', contrast: 'Normal' }Resolution, CSS selectors, and panel readouts all key on the tuple itself; a label like "Dark · Brand A" is a display convenience, never an input to resolution. See Axes for how a flip works and how a partial tuple fills in.
The token graph
Section titled “The token graph”After parse and resolve, swatchbook builds a token graph, the in-memory structure every read goes through:
- One node per token path (
color.surface.default,space.md,typography.heading.font-size). - A baseline value at the project’s default tuple.
- Per-axis writes: for each non-default
(axis, context), the value this token takes when that axis is in that context. - Alias edges: when a token references another (
{color.brand.accent}or DTCG 2025.10$ref), the graph records the edge so the walker can compose values at any tuple.
project.resolveAt(tuple) resolves every token at a tuple, memoized on the canonical tuple key, so repeating a query at the same tuple is cheap. The Core reference documents the walker API.
See also
Section titled “See also”- Axes: the axis / context vocabulary, where axes come from, and per-story override mechanics.
- The token pipeline: how the virtual module ships graph + CSS to the preview, and the full load sequence.
- Aligning with your token build: the boundary between swatchbook’s preview pipeline and a production Terrazzo build.
- Diagnostics: every
swatchbook/<group>warning and error the loader can emit.