apps/storybook (@datler/storybook) shows components in isolation under the token system: Storybook 10 on the Vite builder (@storybook/react-vite), with the accessibility and docs addons. pnpm run storybook serves it on port 6006, and pnpm run storybook:build builds the static site.
Wiring
- Theme axes.
.storybook/preview.tsxbuilds itsglobalTypesfromdatlerThemeAxesin@datler/design-tokens(Design Tokens), so there is one toolbar control per axis (mode, palette, accent, radius, density and font) and the options cannot differ from the CSS. Its decorator writes each axis as itsdata-*attribute on<html>and wraps every story inbg-background text-foreground p-6. A mode ofsystemis resolved to dark or light againstprefers-color-schemebefore it reaches the attribute, by@jeliroco-multimedia/blunt-tokens’resolveMode, the resolver the app’s theme runtime applies, becausesystemis a preference, not a value the CSS knows. - CSS.
.storybook/preview.cssreproduces the renderer’s CSS entry in the same order: Tailwind,datler-theme.css(which owns the attribute-keyeddark:variant), the library’sbridge.cssand the library’sstyles.css. Without the last two, library components render with their utility classes compiling to nothing, and the file says not to re-declare thedark:variant after the tokens, since a class-based one would win and no story adds a.darkclass. - Tailwind v4 runs as a Vite plugin added in
viteFinal. Tailwind scans from its CSS file’s own directory, which would cover onlyapps/storybook, so@sourcepoints it atapps/renderer/src,packages/andapps/storybook/src. The@alias resolves to the renderer’ssrc, as the renderer’s own Vite config does, so stories beside renderer components import as the components do. - Stories live next to the components they show (
*.stories.tsxinapps/renderer/src), with the foundations and a Welcome page inapps/storybook/src; thestoriesglobs cover those trees andpackages/.
What has stories
| where | stories |
|---|---|
apps/storybook/src/foundations/ | Color, Typography, Spacing, Radius, Motion, Icons, and JelirocoContract, which reads every contract token off the live document and lists any that resolve to nothing |
apps/renderer/src/components/ | the quick-add palette, the entry panel, the trackable card, the trackable calendar, the shared charts, the Term component, the Series editor, the primitives (icon, add and text buttons, the wordmark, icon tiles, colour dots, eyebrows), the form section, the save error, a catalog item’s attribute values, the note controls, and the reading picker |
A component earns a story when more than one route uses it, or when it draws a state a screen rarely reaches (an error, an empty list, a farewell), and the story shows those states (empty, filled, error) so the toolbar has something to re-skin. A component used once, inside one route, does not. A story is a component and a few props: one that needs the database is the wrong candidate, which is why the entry dialog, the Achievement toast and the getting-started farewell, all of which read it, have none yet.
Related
Design Tokens · Theming System · Jeliroco Components · Monorepo Layout