diff --git a/CHANGELOG.md b/CHANGELOG.md index 30fe3ce..cb3a1b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,23 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Version ## [Unreleased] +### Fixed + +- **Showcase page no longer wedges the renderer** (WHYNOT-WP-0002 T11). `` + inserted separator elements into its own light DOM on `slotchange` while cleaning up + in the shadow DOM, so separators were never removed — each insertion re-fired + `slotchange` and the main thread looped forever, so `examples/showcase/index.html` + never finished rendering. `WnBreadcrumb._onSlot` is now idempotent (excludes its own + separators; mutates only when they are not already correct). The showcase visual test + is un-`fixme`'d and captures a stable `showcase.png`, unblocking WHYNOT-WP-0003 T08 + (showcase as per-version visual catalog). + +### Removed + +- **Dead Google-Fonts `@import`** from `src/styles/colors_and_type.css`. Every token + font stack is system-ui based, so the imported IBM Plex webfont was unused; it was + also a documented source of CI flakiness. No visual change (system fonts unchanged). + ### Added - **Versioned IR manifest + consumer drift-check** (WHYNOT-WP-0003, Phase 1–4). The diff --git a/src/elements/layout.js b/src/elements/layout.js index 2311f27..21869b0 100644 --- a/src/elements/layout.js +++ b/src/elements/layout.js @@ -236,11 +236,23 @@ export class WnEmptyState extends WnBase { export class WnBreadcrumb extends WnBase { _onSlot(e) { const slot = e.target; - const items = slot.assignedElements({ flatten: true }); - // Build the rendered tree: each item + a separator after it. - const wrapper = this.shadowRoot?.querySelector('.wn-breadcrumb__list'); - if (!wrapper) return; - wrapper.querySelectorAll('.wn-breadcrumb__sep').forEach(s => s.remove()); + // Separators are inserted into the LIGHT DOM (so they sit in document order + // between the slotted items), which re-fires this slotchange. We must + // therefore be idempotent: exclude our own separators when reading items, + // and skip all mutation once the separators are already correct — otherwise + // each insertion retriggers slotchange and the main thread loops forever. + const items = slot.assignedElements({ flatten: true }) + .filter((el) => !el.classList.contains("wn-breadcrumb__sep")); + const existing = [...this.querySelectorAll(":scope > .wn-breadcrumb__sep")]; + + if (existing.length === Math.max(0, items.length - 1)) { + // Structure already correct — only refresh the "current" marker, do not + // touch the child list (no mutation ⇒ no slotchange re-fire ⇒ loop ends). + items.forEach((el, i) => el.classList.toggle("wn-breadcrumb__current", i === items.length - 1)); + return; + } + + existing.forEach((s) => s.remove()); items.forEach((el, i) => { el.classList.toggle("wn-breadcrumb__current", i === items.length - 1); if (i > 0) { @@ -248,8 +260,6 @@ export class WnBreadcrumb extends WnBase { sep.className = "wn-breadcrumb__sep"; sep.setAttribute("aria-hidden", "true"); sep.textContent = "/"; - // Use light-DOM-relative insertion: items are still in light DOM, - // so DOM-order separators between them belong in light DOM too. el.parentNode.insertBefore(sep, el); } }); diff --git a/src/styles/colors_and_type.css b/src/styles/colors_and_type.css index 40e4114..0f0c076 100644 --- a/src/styles/colors_and_type.css +++ b/src/styles/colors_and_type.css @@ -7,8 +7,11 @@ artefacts over heavy fills. ============================================================ */ -/* ---------- Webfonts (Google Fonts, see /fonts for offline) ---------- */ -@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@300;400;500;600;700&family=IBM+Plex+Serif:ital,wght@0,400;0,500;1,400&display=swap"); +/* No webfont is loaded. Every token font stack is system-ui based + (ui-sans-serif / ui-monospace / ui-serif), so the design ships with zero + network font dependency. (Historically this imported IBM Plex from Google + Fonts; that webfont was unused and a source of CI flakiness, so it was + dropped.) */ /* @generated tokens — regenerated by `make adapt-lit` from ir/tokens.json. DO NOT EDIT. */ :root { diff --git a/tests/visual/ui-kit.spec.mjs b/tests/visual/ui-kit.spec.mjs index abe76f7..06db604 100644 --- a/tests/visual/ui-kit.spec.mjs +++ b/tests/visual/ui-kit.spec.mjs @@ -8,28 +8,30 @@ import { test, expect } from "@playwright/test"; // // To update intentionally: pnpm test:visual:update -// The design-tokens stylesheet (colors_and_type.css) @imports IBM Plex from -// Google Fonts, but every token font stack is system-ui based — the webfont is -// unused. Left live it intermittently hangs in CI, blocking the page's module -//