Component Library (Storybook)
The Frontend's entire component inventory — atoms, molecules, organisms, and pages — is browsable and fully interactive in Storybook, deployed with this documentation site:
Every component renders with the app's real MUI theme, design-token CSS variables, and Roboto typography, against mocked data — no live cameras, no real sessions, no network dependencies.
What you can do in the canvas
| Toolbar control | What it drives |
|---|---|
| Theme | Switches the MUI dark/light theme and the data-theme CSS variables together, exactly like the in-app toggle |
| Auth | Signed-in (with AI.Access role) vs signed-out session, for auth-gated components |
| Viewport | Presets matched to the app's real breakpoints — 600 / 788 / 920 / 1200 / 1536 px, plus phone and tablet in portrait and landscape (rotate button) |
| Controls | Every TypeScript prop, editable live — prop tables are generated from the component types |
| Accessibility | axe audits every story (a11y panel); ~136 pre-existing violations are tracked as a backlog — flip a11y.test to error per story as they're fixed |
| Backgrounds | The app's actual surface colors (#000/#353535 dark, #f0ebe1/#e6e0d4 light) |
Running it locally
npm run storybook # dev server on http://localhost:6006
npm run build-storybook # static build into storybook-static/
npm run test:storybook # vitest + playwright run of every story, a11y included
How stories are wired
- Provider stack —
.storybook/preview.tsxmirrorsapp/layout.tsx: mockedSessionProvider→ freshQueryClientProviderper story → no-fetchConfigProvider→ MUIThemeProvider. - Zustand isolation — every store is snapshotted at startup and restored
before each story; seed per-story state with the
withStoreshelper from.storybook/stores.tsx. - API mocks — MSW handlers in
mocks/handlers/answer the BFF endpoints (/api/env,/api/feature-flags, cameras, images, activity…); fixtures live inmocks/fixtures/. - SignalR —
@microsoft/signalris aliased to a controllable mock hub; fire fake broadcasts from a story withwindow.__sbSignalR.emit('ReceiveImageBroadcast', …). - Docs pages — every component carries
tags: ['autodocs'], so a docs page with prop tables is generated per component.
How it gets deployed here
The Documentation repo's pipeline checks out Alert.CA.Frontend, runs
build-storybook, and drops the output into the docs site's
static/storybook/ before building — so /storybook/ ships with every docs
deploy and refreshes whenever Frontend main changes. Access is gated the
same way as the rest of this site.