The working component library behind edwson.com.
design-system-showcase.htmlis the marketing surface; this Storybook is the source of truth.
Live: edwson.github.io/Ed_Storybook
(deploys automatically on push to main via GitHub Actions)
A vanilla-JS / HTML-first component library, served via Storybook 9
with the @storybook/html-vite
renderer. No React, no JSX, no framework lock-in. Each component exports a
render function that returns a string of HTML or a DOM node.
The library reuses the portfolio's design tokens directly from
/css/tokens.css — there is no fork. A change to a
token in the portfolio cascades into every Storybook component.
The portfolio's standing rule is zero build toolchain. Storybook
breaks that rule: it ships a Vite dev server, a manager UI, an addon
ecosystem, and a build step. This is a deliberate exception, the same
way design-system-showcase.html is allowed to fork the brand.
Reasons:
- A real component library has props, args, controls, and states. A static HTML page can demonstrate them. It cannot let a reviewer change the value, observe the result, copy the snippet, and read the a11y report. Storybook is the lowest-friction way to ship those four capabilities together.
- Industry expectation. Senior product designers at top-tier fintech are expected to understand component infrastructure. Bypassing Storybook would be a missed signal.
- Bounded scope. The build artifact lives at
/storybook-next/only; the rest of the portfolio remains zero-build vanilla JS.
# from this directory
nvm use # node 20.11.1
npm install
npm run storybook # → http://localhost:6006
npm run build-storybook # → ./storybook-static (deploy artifact)Note: the dev server fetches Google Fonts (Cormorant Garamond, Inter, JetBrains Mono) — same as the rest of the portfolio. Offline usage requires self-hosting; deferred for v0.2.
storybook-next/
├── .storybook/
│ ├── main.js ← stories glob, addons, framework
│ ├── preview.js ← decorators, theme toggle, tokens import
│ ├── manager.js ← Storybook UI chrome (Edwson brand)
│ ├── tokens.css ← @import portfolio tokens
│ ├── fonts.css ← Google Fonts
│ └── storybook-brand.css ← preview canvas styles
│
├── src/
│ ├── welcome/Welcome.mdx
│ ├── foundations/ ← color · typography · spacing · motion · wcag
│ ├── primitives/ ← button · input · …
│ ├── components/ ← cards · alerts · accordions · …
│ ├── financial/ ← pnl-cell · order-row · …
│ ├── compliance/ ← disclosure-banner · kyc-step · …
│ ├── aml/ ← sanctions · pep · ubo-graph · …
│ ├── b2b/ ← clm · pricing · sso-admin · …
│ └── patterns/ ← command-palette · dashboard-grid · …
│
├── package.json ← Storybook 9 + Vite + addons
├── vite.config.js ← shared aliases (@eds, @tokens)
├── ROADMAP.md ← 8-phase migration plan
└── README.md ← this file
src/<section>/<component>/
├── <Component>.js ← render fn, JSDoc props
├── <component>.css ← scoped BEM with .eds- prefix
└── <Component>.stories.js ← CSF 3 stories with full args/argTypes
eds-prefix everywhere — namespaced to avoid colliding with portfolio BEM (.btn,.nav__*,.pb-*, etc.).- BEM:
.eds-btn__icon,.eds-btn--primary. - Variants and states as modifiers, never attribute selectors.
- Every color, spacing, type, motion value comes from
tokens.css. - No hardcoded hex except inside the foundations stories (which are displaying the tokens).
Same as the rest of the portfolio:
- Zero inline styles in components (CSS custom property injection like
style="--demo-dur: 200ms"is allowed — it's data, not styling). - Zero
!importantoutsideprefers-reduced-motion. - Mobile-first.
- Token-driven.
- CSF 3 (
export const Foo = { args: ... }) — not CSF 2. argsfor every meaningful prop.argTypesfor control panel ergonomics +table.categorygrouping.- Top-level
tags: ['autodocs']so every component renders a docs page. - At least one use-case story per component (real composition,
e.g.
Use case · order ticket footer).
Two themes wired via addon-themes:
- Institutional Dark (default) — matches portfolio.
- Salt Light — matches Xanthos / Christie's / Double-Blind cream.
Toggle from the toolbar. Components that need theme-specific overrides
use [data-theme='salt'] .eds-foo { … } selectors at the bottom of
their CSS file.
A Comfortable / Compact toggle from the toolbar. Components read
--density aware tokens (--eds-row-h, --eds-pad-y) when present.
- WCAG 2.1 AA is the floor. The
addon-a11yruns on every story. role+aria-*wired on every interactive component.prefers-reduced-motionrespected on every keyframe.- Direction is never colour-only — pair with arrow + sign.
Production: GitHub Pages — auto-deployed on every push to main.
The workflow at .github/workflows/deploy.yml
runs npm ci + storybook build + publishes to Pages. The site URL is
https://edwson.github.io/Ed_Storybook/.
One-time repo setup (already done if the badge above is green):
- Repo → Settings → Pages → Source: GitHub Actions.
- Repo → Settings → Actions → Workflow permissions: Read and write permissions.
- Push to
main. The Action runs.
Custom domain (optional, future): if a custom domain is desired
later (storybook.edwson.com), add a CNAME file under public/
with the domain and configure DNS at the registrar. The workflow
already wires .nojekyll to keep Pages from filtering Storybook's
underscore-prefixed assets.
v0.5 — 7 foundations + 8 primitives + 3 components + 6 financial + 4 compliance + 2 patterns = 30 stories shipped.
The flagship demonstration is Patterns / Dashboard Grid — ten components composed into a Bloomberg-class trading-desk surface in a single story.
See ROADMAP.md for the migration plan covering all 149 components.
| Section | v0.5 | Notes |
|---|---|---|
| Foundations | 7 / 8 | Color · Typography · Spacing · Motion · WCAG · Elevation · Icons. Iconography rules pending. |
| Primitives | 8 / 12 | Button · Input · Select · Checkbox · Toggle · Badge · Radio · Avatar. Slider · Chip · Tag · IconButton pending. |
| Components | 3 / 14 | Card · Alert · Tooltip. Toast · Popover · Modal · Drawer · Accordion · Pagination · Breadcrumb · Tabs · Stepper · Empty State · Skeleton pending. |
| Financial | 6 / 25 | PnL Cell · Regime Chip · Price Tick · VIX Chip · Order Row · Position Row. |
| Compliance | 4 / 12 | Disclosure Banner · KYC Step · FIX State Chip · Threshold Band. |
| AML | 0 / 10 | All pending |
| B2B SaaS | 0 / 10 | All pending |
| Patterns | 2 / 6 | Command Palette · Dashboard Grid (showpiece). |
Maintained by Ed Chen · ed@edwson.com · edwson.com