Skip to content

Story #2205: Storybook Implementation#2277

Draft
herzog0 wants to merge 5 commits intodevelopfrom
teo/storybook-django
Draft

Story #2205: Storybook Implementation#2277
herzog0 wants to merge 5 commits intodevelopfrom
teo/storybook-django

Conversation

@herzog0
Copy link
Copy Markdown
Collaborator

@herzog0 herzog0 commented Apr 6, 2026

Issue: #2205

Summary & Context

Adds Storybook to the project using storybook-django + django-pattern-library. Templates are rendered server-side by Django and displayed in Storybook's canvas, giving the team an isolated, interactive component browser for all V3 UI components with light/dark mode support.

  • Figma links:
    • ML Figma: N/A (tooling)
    • CPPA Figma: N/A (tooling)
  • Link to components/page: http://localhost:6006 (this is running in a new container, so stop the existing ones and run docker compose up -d --build before trying to access this url).

Changes

Infrastructure

  • Added django-pattern-library Python dependency (requirements.in / requirements.txt)
  • Added storybook, @storybook/react-webpack5, storybook-django, react, react-dom to package.json devDependencies
  • Added .storybook/main.js — Storybook config (story glob, webpack HTML loader)
  • Added .storybook/middleware.js — Express middleware proxying /pattern-library/ (template API) and /static/ to the running Django server
  • Added .storybook/preview-head.html — loads all V3 CSS, fonts (Google Fonts, Material Symbols, Font Awesome), Alpine.js, and project JS into the Storybook canvas iframe
  • Added .storybook/preview.js — global decorator that applies the v3 class to <html>/<body> and syncs Storybook's background picker with the project's colour-mode system (localStorage + saveColorMode)
  • Added docker/Dockerfile.storybook — Node 22 slim image for the Storybook container
  • Added storybook service to docker-compose.yml (port 6006, depends on web, proxies to Django via DJANGO_ORIGIN=http://web:8000 on the shared backend network)
  • Added templates/patterns/base.html — Django HTML shell used by the pattern library renderer (loads all V3 CSS, JS, Alpine, fonts)

Django integration

  • config/settings.py: conditionally registers pattern_library in INSTALLED_APPS and adds PATTERN_LIBRARY config dict; appends "web" to ALLOWED_HOSTS for Docker container-to-container communication
  • config/urls.py: conditionally mounts the pattern-library/ URL prefix; both additions gracefully no-op if django-pattern-library is not installed

Documentation

  • Added docs/storybook.md — full setup guide covering prerequisites, installation, running locally and via Docker, project structure, how it works, and how to add new components

‼️ Risks & Considerations ‼️

  • django-pattern-library is an optional dependency — both the app registration and the URL mount are wrapped in try/except ImportError, so Django starts normally without it. However reviewers should verify their local requirements.txt is up to date after this merges.
  • The "web" host is unconditionally appended to ALLOWED_HOSTS in settings.py (with a guard for duplicates). This is benign in production but worth noting.
  • Storybook serves Django templates directly — any template that relies on request context (e.g., request.user, CSRF) will not work unless mocked in the pattern library context. None of the current stories use such templates; complex layout components (_header_v3.html, _footer_v3.html, _hero_home.html) are intentionally excluded.
  • _markdown_card.html uses {% load wagtailmarkdown %}. The Storybook story for it will only render correctly if wagtailmarkdown is installed in the environment.
  • yarn.lock is updated with all new Node dependencies (~7k lines added); no conflicts expected but worth a quick review.

Screenshots

Light Mode Dark Mode
image image

Self-review Checklist

  • Tag at least one team member from each team to review this PR
  • Link this PR to the related GitHub Project ticket

Frontend

  • UI implementation matches Figma design
  • Tested in light and dark mode (background picker syncs with project theme system)
  • Responsive / mobile verified (components render at any canvas width)
  • Accessibility checked (keyboard navigation, etc.)
  • Ensure design tokens are used for colors, spacing, typography, etc. – No hardcoded values
  • Test without JavaScript (if applicable) — pattern library renders server-side HTML; no JS dependency for rendering
  • No console errors or warnings

@herzog0 herzog0 requested review from gregjkal and julhoang April 6, 2026 16:05
@herzog0 herzog0 linked an issue Apr 6, 2026 that may be closed by this pull request
@herzog0 herzog0 changed the title Teo/storybook django Story #2205: Storybook Implementation Apr 6, 2026
Copy link
Copy Markdown
Collaborator

@julhoang julhoang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great start @herzog0 !!

One thing I noticed: right now we can't test no-JS rendering by simply disabling JavaScript in the browser, since Storybook itself depends on JS to run 😅

Just an idea (I haven't tested it yet, but I kinda feel like it is feasible):

  • Add a toolbar toggle to switch JavaScript on/off per component
  • In the preview iframe, dynamically load/unload the component scripts based on the toggle state – so when JS is "off," the component renders with only HTML and CSS

Curious to hear your thoughts!

Comment on lines +2 to +3
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these 2 can be removed since we are not using Google Font

Comment on lines +4 to +5
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css">
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me like Font Awesome is only being used in _social_icon_links.html, which are used in _footer_v3.html – I have a feeling this icon library can be removed, we should look into this to confirm and remove them in a separate PR :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the explicit imports on this file, I'm concerned that this leaves room for unexpected drifts between base.html and this file when we load new files.

One idea to consider – perhaps we can create a small .html that takes care of loading these scripts/stylesheet, then both base.html and this file can share it. It definitely calls for a refactor on base.html though, I'm not sure if we really want to touch it 😅. What do you think of this?

Comment thread .storybook/preview-head.html Outdated
Comment on lines +26 to +27
<!-- v3 class on html element for v3 styles -->
<script>document.documentElement.classList.add('v3');</script>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is already handled in preview.js – 🪓?

Comment thread docs/storybook.md
Comment on lines +178 to +191
## Configuration Reference

| File | Purpose |
|---|---|
| `config/settings.py` | `PATTERN_LIBRARY` setting and `pattern_library` in `INSTALLED_APPS` (conditional) |
| `config/urls.py` | `pattern-library/` URL (conditional — only when package is installed) |
| `templates/patterns/base.html` | Base HTML shell for rendered patterns (CSS/JS/fonts) |
| `.storybook/main.js` | Storybook framework, story globs, webpack config |
| `.storybook/middleware.js` | Express middleware proxying API calls to Django (`DJANGO_ORIGIN` env var) |
| `.storybook/preview.js` | Storybook preview parameters |
| `package.json` | `storybook` and `build-storybook` scripts |
| `requirements.in` / `requirements.txt` | `django-pattern-library` Python dependency |
| `docker/Dockerfile.storybook` | Storybook container image (Node 22) |
| `docker-compose.yml` | `storybook` service on `backend` + `frontend` networks |
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if we can add preview-head.html here. I didn't know Storybook automatically scans for it 😄

Comment thread docs/storybook.md Outdated
Comment on lines +193 to +225
## Existing Components

The following V3 components have stories:

- **Button** — all style variants (primary, secondary, green, yellow, teal, error)
- **Button Tooltip** — all positions (top, right, bottom, left), icon-only
- **Avatar** — image, initials (yellow/green/teal), placeholder, all sizes
- **Basic Card** — one and two button variants
- **Horizontal Card** — image + text layout with CTA
- **Vertical Card** — image below text layout
- **Search Card** — with and without popular terms
- **Post Card** — with/without contributor badge
- **Post Cards List** — list layout with multiple cards
- **Banner** — default and auto-fade variants
- **Learn Card** — links list with hero image
- **Testimonial Card** — carousel of quotes
- **Account Connections Card** — mixed, all connected, none connected
- **Badges Card** — empty with/without CTA, filled (2 and 6 badges)
- **Create Account Card** — rich text body with preview image
- **Form Inputs** — text field, icon, error, checkbox, combo box, multi-select
- **Dialog** — modal with/without description
- **Content Detail Card** — with icon, link, CTA, plain
- **Content Event Card** — list and card variants
- **Achievement Card** — empty and filled states
- **Why Boost Cards** — grid of content-detail cards
- **Mailing List Card** — email subscription form
- **Install Card** — tabbed package manager / system install
- **Code Blocks** — standalone and card variants
- **Carousel Buttons** — prev/next controls
- **Cards Carousel** — default, autoplay, infinite+autoplay
- **Thread Archive Card** — mailing list archive links
- **Event Cards** — all color variant gallery
- **Category Tags** — all size/color variants with version tags
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious – are we expected to keep this list updated as we add more components? Or is it more like an FYI list that we can just list in the PR description?

@herzog0 herzog0 marked this pull request as draft April 7, 2026 15:06
@herzog0 herzog0 force-pushed the teo/storybook-django branch from 90373c1 to f3640f8 Compare April 8, 2026 13:18
feat: dockerize storybook

feat: add v3 components to storybook

feat: add missing storybook components

fix: dark theme

chore: remove component list section

chore: remove duplicate v3 class assignment
@herzog0 herzog0 force-pushed the teo/storybook-django branch from f3640f8 to 6237a70 Compare April 8, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Storybook to Lookbook Migration: Spike and Implementation

2 participants