fix(showcase): break wn-breadcrumb slotchange infinite loop (WHYNOT-WP-0002 T11)
Some checks failed
ci / check (push) Has been cancelled
ci / release (push) Has been cancelled

WnBreadcrumb._onSlot inserted separator <span>s into its own light DOM on
slotchange but cleaned up in the shadow DOM, so they were never removed — each
insertion re-fired slotchange, looping the main thread and wedging the showcase
page. Made _onSlot idempotent: exclude own separators when reading items, and
mutate only when separators are not already correct.

- Un-fixme the showcase visual test; add a warm-up full-page capture so
  deviceScaleFactor-2 sub-pixel snapping settles before the assertion. All 5
  visual tests pass.
- Remove the dead Google-Fonts @import from colors_and_type.css (token stacks are
  system-ui; webfont unused + a CI-flake source; no visual change).
- Unblocks WHYNOT-WP-0003 T08 (showcase = per-version visual catalog); both T11
  and T08 marked done.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-27 20:10:41 +02:00
parent 76e516f6d9
commit a89bb563a0
6 changed files with 79 additions and 24 deletions

View File

@@ -216,11 +216,27 @@ gate that confirms Lit actually matches the designbook appearance.
```task
id: WHYNOT-WP-0002-T11
status: todo
status: done
priority: medium
state_hub_task_id: "7435338d-702a-43d7-9c86-49531fe0d8e4"
```
**Resolved 2026-06-27.** Root cause: `WnBreadcrumb._onSlot` (`src/elements/layout.js`)
inserted separator `<span>`s into its own **light DOM** on `slotchange`, but its
cleanup queried the **shadow** wrapper for separators — so they were never removed.
Each insertion mutated the breadcrumb's children, re-firing `slotchange`, inserting
more separators, looping the main thread forever. (The earlier "specific demo
composition" hypothesis was a misdiagnosis — the minimal repro simply omitted
`<wn-breadcrumb>`; a minimal page *with* it reproduces the wedge, *without* it
registers in ~300ms.) Fix: made `_onSlot` idempotent — it excludes its own
separators when reading items and skips all DOM mutation once separators are
already correct, so the self-triggered `slotchange` is a no-op and the loop ends.
Also removed the dead Google-Fonts `@import` from `colors_and_type.css` (token
font stacks are system-ui; the webfont was unused and a documented CI-flake source).
`test.fixme` removed in `tests/visual/ui-kit.spec.mjs`; the showcase now renders and
captures a stable `showcase.png` (a warm-up full-page capture settles deviceScaleFactor-2
sub-pixel snapping before the assertion). All 5 visual tests pass.
Discovered 2026-06-26 while regenerating visual baselines after the T06 token
regen. The `examples/showcase/index.html` "every component" page wedges the
renderer main thread when its module executes — the page never reaches `load`

View File

@@ -225,7 +225,7 @@ anything, complementing the machine-readable manifest.
```task
id: WHYNOT-WP-0003-T08
status: wait
status: done
priority: low
state_hub_task_id: "a0886a4f-cf27-44ef-b8c6-8e61ceda1f84"
```
@@ -236,6 +236,13 @@ just to confirm, once T11 lands, that the showcase is deployable/inspectable per
version (e.g. served from a tag) — no new build, reuse the existing page. Blocked on
WP-0002-T11.
**Done 2026-06-27.** WP-0002-T11 landed (breadcrumb infinite-loop fixed); the
showcase page now renders deterministically and is covered by a passing visual test
(`showcase.png` baseline). No new build — the existing page *is* the per-version
visual catalog: served statically from any checkout/tag (`pnpm showcase`), it pairs
with the machine-readable `ir/manifest.json` + `ir/INDEX.md` as the visual side of a
version's inventory. Nothing further to build.
---
## Phase 4 — Deferred: live contract-parity mode (design-only)