Files
whynot-design/CHANGELOG.md
tegwick 2de30beb7b
Some checks failed
ci / check (push) Has been cancelled
ci / release (push) Has been cancelled
feat(consumer): versioned IR manifest + drift-check (WHYNOT-WP-0003 T03-T07,T09)
Make ir/ the unit of versioned downstream consumption so consuming repos can
pin a version, inspect it, and follow changes at their own pace.

- T03 ir/manifest.json: per-version inventory + diff anchor with deterministic
  sha256-over-canonicalised-JSON hashes; no-churn generatedAt; manifest schema.
- T07 ir/INDEX.md: human-readable catalog generated by make ir.
- T04 .whynot-design.lock sync-point format + lock schema.
- T05 npx @whynot/design drift: consumer drift-check (bin entry), exit 0/2/3,
  --json/--update/--manifest/--version/--lock.
- T06 CONSUMING.md guide + examples/consumer-fixture/ runnable demo; README +
  MultiFrameworkSupport cross-links; fix README version pin (@0.3.0 not @v0.3.0).
- T09 CONSUMER_CONTRACT_PARITY.md design-only note (live-UI parity deferred).

T02 (publish) and T08 (showcase, blocked on WP-0002 T11) remain wait. Repo stays
in dev mode; no outward publish performed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 19:35:45 +02:00

159 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
All notable changes to `@whynot/design` are recorded here. Hand-edited until release cadence makes it painful.
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning rules: see [`DesignSystemIntroduction.md` §6](./DesignSystemIntroduction.md#6-versioning-discipline).
## [Unreleased]
### Added
- **Versioned IR manifest + consumer drift-check** (WHYNOT-WP-0003, Phase 14). The
`ir/` contract is now the unit of versioned downstream consumption:
- `ir/manifest.json` (T03) — per-version inventory + diff anchor:
`{ schemaVersion, designVersion, generatedAt, tokensHash, components:[{name,group,hash}] }`,
each hash a deterministic sha256 over canonicalised JSON (formatting-invariant,
`generatedAt` reused on no-op runs → no git churn). Schema:
`ir/schema/manifest.schema.json`. Emitted by `make ir`.
- `ir/INDEX.md` (T07) — human-readable catalog generated from the contracts;
browse a version without cloning or running anything. Emitted by `make ir`.
- **`npx @whynot/design drift`** (T05) — consumer-side drift-check (`bin/whynot-design.mjs`,
new `bin` entry). Compares a consumer's adopted `.whynot-design.lock` against the
installed package's manifest and reports added/changed/removed components + token
changes (`--json`, `--update`, `--manifest`, `--version`, `--lock`). Exit codes
mirror the adapter contract: `0` in sync · `2` usage error · `3` drift.
- `.whynot-design.lock` sync-point format (T04) — `ir/schema/lock.schema.json` +
documented lifecycle (consumer-side mirror of `designbook/.design-sync.json`).
- `CONSUMING.md` (T06) — pin → inspect → drift → update guide, with a runnable
`examples/consumer-fixture/`; cross-linked from `README.md` and `MultiFrameworkSupport.md`.
- `CONSUMER_CONTRACT_PARITY.md` (T09) — design-only note + recorded go/defer
decision for the heavier live-UI-vs-contract parity mode (deferred).
- **Publishable to the coulomb Gitea npm registry** (WHYNOT-WP-0003 T02) — `private:false`,
`publishConfig.registry`, real `repository.url`, an `.npmrc` scope + `${NPM_AUTH_TOKEN}`
reference (no secret committed), and `PUBLISHING.md` (publish flow + consumer install +
token routing). The package now ships the `ir/` consumer contract (added to `files` and
the `./ir/*` export) so consumers can pin a version and track it.
### Changed
- **`lit` is now a `peerDependency`** (`^3`), not a direct dependency. Consumers must
install `lit` alongside `@whynot/design` (`npm i @whynot/design lit`) so their bundler
dedupes to a single `lit` instance.
## [0.3.0] — 2026-06-27
### Added
- **Technology-neutral IR + stack-adapter pipeline** (WHYNOT-WP-0002, Phase 03). The
design language is now authored once in the canonical React designbook and projected
one-way onto each stack: `React → designbook/ → ir/ → adapters/<stack>/`.
- `ir/` — committed, diffable blueprint: `ir/SCHEMA.md`, JSON Schemas
(`ir/schema/{component,tokens}.schema.json`), and the extractor's output
(`ir/tokens.json` in W3C DTCG format, `ir/components/*.json`, `ir/exemplars/*`).
- `adapters/ADAPTER_CONTRACT.md` — the contract every stack adapter implements
(inputs, drift report + parity result shapes, idempotency, CI exit codes).
- `scripts/designbook_pull.py` + `make designbook-pull` — pulls the React designbook
from Claude Design into `designbook/` (the bundled `/design-sync` skill only
*pushes*, so it cannot populate `designbook/`).
- `scripts/ir-extract.mjs` + `make ir` — extracts the IR from the `.jsx` ui-kit,
manifest, and previews.
- `adapters/lit/` + `make adapt-lit` — Lit reference adapter; tokens fully generated
into `src/styles/colors_and_type.css` (marker-bounded, idempotent).
- `.claude/rules/designbook-propagation.md` + `DesignSystemIntroduction.md` §5.1 —
one-way governance and drift-resolution workflow.
### Changed
- `src/styles/colors_and_type.css` — token `:root` block is now **generated** by
`make adapt-lit` from `ir/tokens.json` (between `@generated tokens` markers). This
synced the Lit token layer to the canonical React designbook: font stacks switched
from IBM Plex to system-font stacks, and the functional-status tokens
(`--status-error/warn/success/info` + `-bg`) were added. **Visual change — Playwright
baselines need review + `pnpm test:visual:update`.**
### Fixed
- **Visual-regression harness now renders deterministically.** The four
`examples/whynot-control` pages render and screenshot cleanly against the new tokens.
Snapshot baselines are now **gitignored** (generated locally via
`pnpm test:visual:update`, not committed — they are large binary test artifacts).
Along the way:
- `serve.json` (`cleanUrls:false`) — the static server was 301-redirecting
`/…/index.html` to a trailing-slash-stripped URL, shifting the document base and
404'ing every relative asset (also broke `pnpm showcase` in the browser).
- `examples/whynot-control/index.html` — token stylesheet linked a non-existent
root path; repointed to `../../src/styles/colors_and_type.css` so the page picks
up the design tokens.
- `examples/vendor/lit.js` — vendored a self-contained esbuild bundle of `lit` and
pointed the showcase importmap at it, replacing the multi-hop live esm.sh module
graph (regen command noted in the showcase importmap comment).
- `tests/visual/ui-kit.spec.mjs` — abort the (unused, post-IBM-Plex) Google-Fonts
CDN in tests; a hung font request was blocking module execution and `load`.
- The `showcase` "every component" visual test is `test.fixme` pending
**WHYNOT-WP-0002-T11** — that page wedges the renderer main thread (a demo
composition loops); the four control baselines are unaffected.
## [0.2.0] — 2026-05-25
**Architectural reframe.** The system is now delivered as three stacked layers — tokens + CSS, Lit web components, optional framework adapters. The previous React-only component layer has been removed.
### Added
- `MultiFrameworkSupport.md` — full integration guide for React, Django, HTMX, Vue, Svelte, plain HTML.
- `src/elements/` — Lit-based web components, light-DOM rendered:
- **Atoms** (`atoms.js`): `<wn-button>`, `<wn-tag>`, `<wn-eyebrow>`, `<wn-stamp>`, `<wn-stage-dot>`, `<wn-phase-dot>`, `<wn-icon>`.
- **Form** (`form.js`): `<wn-input>`, `<wn-textarea>`, `<wn-select>`, `<wn-search-input>`, `<wn-field-row>`.
- **Layout** (`layout.js`): `<wn-card>`, `<wn-modal>`, `<wn-table>` + `<wn-table-row>` + `<wn-table-cell>`, `<wn-banner>`, `<wn-toast>` + `<wn-toast-region>`, `<wn-empty-state>`, `<wn-breadcrumb>`.
- **Chrome** (`chrome.js`): `<wn-top-nav>`, `<wn-sidebar>` + `<wn-sidebar-group>` + `<wn-sidebar-item>`, `<wn-page-header>`, `<wn-pipeline>`, `<wn-prototype-card>`.
- `src/elements/icons.js` — Lucide-derived inline icon paths (no runtime CDN dependency).
- `src/styles/components.css` — utility-class layer (`wn-btn`, `wn-card`, `wn-tag`, etc.). Consumable directly from any HTML for the "Layer 1 only" use case.
- `adapters/django/templates/whynot/*.html``{% include %}`-ready partials for Django consumers (button, eyebrow, tag, stage-dot, page-header, pipeline, field-row, prototype-card, banner, empty-state).
- `adapters/django/README.md` — how to wire the partials into a Django app.
- `examples/showcase/index.html` — single-page reference rendering every component. Doubles as the Playwright visual-regression baseline.
- `lit` ^3.2.1 as a runtime dependency.
### Changed
- `DesignSystemIntroduction.md` — updated to describe the three-layer architecture, multi-framework consumption, and the revised propagation pipeline.
- `README.md` — top-level rewrite around the new architecture, with quick-start blocks per framework.
- `package.json` — adds per-group `exports` (`@whynot/design/atoms`, `/form`, `/layout`, `/chrome`, `/icons`).
- CI now runs visual regression against `examples/showcase/index.html` *and* `examples/whynot-control/index.html`.
### Removed
- `src/components/Atoms.jsx`, `src/components/Chrome.jsx` — the React-only component layer. Consumers using these from v0.1.0 should swap to the corresponding custom elements (drop-in replacements; see `MultiFrameworkSupport.md` § React).
- `peerDependencies` on React. React is no longer required to consume `@whynot/design`.
### Migration
If you were on v0.1.0 with React imports like `import { Button } from "@whynot/design"`:
| Before (v0.1.0) | After (v0.2.0) |
|---|---|
| `import { Button } from "@whynot/design"; <Button variant="primary">…</Button>` | `import "@whynot/design"; <wn-button variant="primary">…</wn-button>` |
| `import { Tag } from "@whynot/design"; <Tag active>…</Tag>` | `<wn-tag active>…</wn-tag>` |
| `<StageDot level="S2" />` | `<wn-stage-dot level="S2"></wn-stage-dot>` |
CSS imports are unchanged; add the new `components.css` import alongside `colors_and_type.css`.
### Known caveats
- IBM Plex is loaded from Google Fonts. Drop `.woff2` files into `fonts/` and swap to a local `@font-face` for offline use.
- The showcase uses `importmap` + esm.sh to load Lit (no bundler). Real consumers using `pnpm add` will pick up Lit from `node_modules` via the package's `dependencies` entry.
- No TypeScript declarations for JSX yet — deferred until a TS consumer asks.
- `<wn-select>` uses a native `<select>` internally; richer custom selects (ElementInternals-based) will appear when a real need shows up.
## [0.1.0] — 2026-05-23
**Initial seed.** Established `whynot-design` as the implementation surface for the `whynot` visual language. (Pre-architectural reframe — see v0.2.0.)
### Added
- `src/styles/colors_and_type.css` — full token set + semantic element styles.
- `tokens/` — source-of-truth JSON tokens for colours, type, spacing, radii, shadows.
- `src/components/Atoms.jsx` — React: `Eyebrow`, `Tag`, `Button`, `StageDot`, `Stamp`, `Icon`.
- `src/components/Chrome.jsx` — React: `TopNav`, `Sidebar`, `PageHeader`, `PipelineStrip`.
- `examples/whynot-control/` — click-through UI kit recreating the `whynot-control` surface.
- `assets/whynot-logo.png` — LEGO-brick + `?!` mark.
- `SKILL.md`, `README.md`, `DesignSystemIntroduction.md`, `CONTRIBUTING.md`, `BOOTSTRAP.md`.