Play UI Component Storybook Workflow
Use this workflow when building or revising isolated React components for the play service UI.
Purpose
The play UI now uses a Storybook-first component workflow for MVP frontend development:
- isolated component review runs in Storybook inside the existing frontend package,
- component contracts stay explicit and prop-driven,
- runtime bootstrapping is not required for component iteration,
- fixtures and stories double as contributor-facing documentation.
The current catalog includes both:
- interaction workflow slices for the player HUD shell, navbar, and side-chat surfaces
- Daggerheart reference surfaces such as the character card and character sheet
Run Storybook
Install the UI workspace dependencies first:
cd internal/services/play/ui
npm ci
Start Storybook:
npm run storybook
Open the component catalog:
http://localhost:6006
/ on the play service now points contributors to Storybook, and /preview/character-card has been intentionally retired.
Where to work
The Daggerheart reference slices live under:
internal/services/play/ui/src/systems/daggerheart/character-card/internal/services/play/ui/src/systems/daggerheart/character-sheet/
The active interaction workflow slices live under:
internal/services/play/ui/src/interaction/player-hud/
Keep concerns separate inside each component slice:
contract.tsexported prop and data typesfixtures.tscanonical mock characters shared by stories and testsCharacterCardOverview.stories.tsxside-by-side reference matrix for the supported variantsCharacterCardVariants.stories.tsxvariant-only stories with a fixed fixture and realistic screen framingCharacterCardFixtures.stories.tsxfixture-only stories using the canonical mock dataCharacterCard.tsxactual component implementationStoryStage.tsxshared Storybook-only screen wrappers for realistic card presentation
Contributor rules
- Keep component inputs explicit and prop-driven.
- Reuse canonical fixtures instead of scattering inline mock objects.
- Source Storybook avatar and campaign-cover imagery from the checked-in asset manifests under
internal/platform/assets/catalog/data/instead of embedding one-off Cloudinary URLs in fixture files. - When a component is derived from an existing product surface, document that source in story descriptions and fixture comments.
- Let Storybook own navigation; do not rebuild fixture or variant selectors inside the component canvas.
- Keep alternate implementations behind the same exported component contract.
- Delete obsolete UI paths and tests once the new slice fully replaces them.
Testing
The Character Card workflow uses the same conceptual inputs in both stories and tests:
- component rendering tests live in Vitest/RTL next to the component slice
- Storybook stories reuse the same canonical fixtures and component contract
npm run build-storybookverifies that the isolated documentation surface still builds
Use the package checks during iteration:
cd internal/services/play/ui
npm test
npm run typecheck
npm run build
npm run build-storybook
For a clean-checkout verification path that installs dependencies first and builds into temporary output directories instead of rewriting the checked-in bundle, run this from the repo root:
make play-ui-check
If Storybook is already running from the same workspace, use the non-destructive root target instead. It reuses the current node_modules tree and avoids npm ci, which can destabilize a live storybook dev process:
make play-ui-check-live
Extending the pattern
When adding the next isolated component:
- create a system-owned component slice with its own contract, fixtures, and stories for Daggerheart reference surfaces, or an interaction-owned slice under
src/interaction/player-hud/for active HUD workflow surfaces - add Storybook stories that clearly separate overview, variants, and fixtures
- write component tests against the exported contract, not runtime internals
- remove temporary or superseded UI code instead of preserving compatibility by default