comparison design_system/src/storybook.js @ 251:117c4d53c9a4

[ui] Add HTML-first Web Component system Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Tue, 04 Aug 2026 09:14:57 -0700
parents
children 7a7581f040e8
comparison
equal deleted inserted replaced
250:745fd127b2a1 251:117c4d53c9a4
1 import "./components/index.js";
2
3 const pages = new Map([
4 ["/", "overview"],
5 ["/components", "overview"],
6 ["/tokens", "tokens"],
7 ["/components/button", "button"],
8 ["/components/card", "card"],
9 ["/components/alert", "alert"],
10 ["/components/field", "field"],
11 ["/components/stack", "stack"],
12 ]);
13
14 function showPage(pathname) {
15 const pageName = pages.get(pathname) || "overview";
16 for (const page of document.querySelectorAll("[data-catalog-page]")) {
17 page.hidden = page.dataset.catalogPage !== pageName;
18 }
19 for (const link of document.querySelectorAll(
20 ".catalog-sidebar [data-catalog-link]",
21 )) {
22 const active = new URL(link.href).pathname === pathname;
23 if (active) link.setAttribute("aria-current", "page");
24 else link.removeAttribute("aria-current");
25 }
26 const heading = document.querySelector(
27 `[data-catalog-page="${pageName}"] h1`,
28 );
29 if (heading) document.title = `${heading.textContent} ยท Zenbu UI`;
30 }
31
32 window.addEventListener("DOMContentLoaded", () => {
33 const root = document.documentElement;
34 const systemTheme = matchMedia("(prefers-color-scheme: dark)");
35 const storedTheme = localStorage.getItem("zen-theme");
36 if (storedTheme) root.dataset.zenTheme = storedTheme;
37
38 const themeToggle = document.querySelector("#themeToggle");
39 const isDark = () => {
40 if (root.dataset.zenTheme) {
41 return root.dataset.zenTheme === "dark";
42 }
43 return systemTheme.matches;
44 };
45 const updateThemeButton = () => {
46 const dark = isDark();
47 themeToggle?.setAttribute("aria-pressed", String(dark));
48 if (themeToggle) {
49 themeToggle.textContent = dark
50 ? "Use light theme"
51 : "Use dark theme";
52 }
53 };
54 updateThemeButton();
55 themeToggle?.addEventListener("click", () => {
56 const next = isDark() ? "light" : "dark";
57 root.dataset.zenTheme = next;
58 localStorage.setItem("zen-theme", next);
59 updateThemeButton();
60 });
61 systemTheme.addEventListener("change", () => {
62 if (!root.dataset.zenTheme) updateThemeButton();
63 });
64
65 document.addEventListener("click", event => {
66 const link = event.target.closest("a[data-catalog-link]");
67 if (!link ||
68 link.origin !== location.origin ||
69 event.defaultPrevented ||
70 event.button !== 0 ||
71 event.metaKey ||
72 event.ctrlKey ||
73 event.shiftKey ||
74 event.altKey ||
75 link.hasAttribute("download") ||
76 link.target) return;
77 event.preventDefault();
78 history.pushState({}, "", link.href);
79 showPage(location.pathname);
80 document.querySelector("#catalogMain")?.focus();
81 });
82 window.addEventListener("popstate", () => showPage(location.pathname));
83 showPage(location.pathname);
84 });