view 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
line wrap: on
line source

import "./components/index.js";

const pages = new Map([
  ["/", "overview"],
  ["/components", "overview"],
  ["/tokens", "tokens"],
  ["/components/button", "button"],
  ["/components/card", "card"],
  ["/components/alert", "alert"],
  ["/components/field", "field"],
  ["/components/stack", "stack"],
]);

function showPage(pathname) {
  const pageName = pages.get(pathname) || "overview";
  for (const page of document.querySelectorAll("[data-catalog-page]")) {
    page.hidden = page.dataset.catalogPage !== pageName;
  }
  for (const link of document.querySelectorAll(
    ".catalog-sidebar [data-catalog-link]",
  )) {
    const active = new URL(link.href).pathname === pathname;
    if (active) link.setAttribute("aria-current", "page");
    else link.removeAttribute("aria-current");
  }
  const heading = document.querySelector(
    `[data-catalog-page="${pageName}"] h1`,
  );
  if (heading) document.title = `${heading.textContent} ยท Zenbu UI`;
}

window.addEventListener("DOMContentLoaded", () => {
  const root = document.documentElement;
  const systemTheme = matchMedia("(prefers-color-scheme: dark)");
  const storedTheme = localStorage.getItem("zen-theme");
  if (storedTheme) root.dataset.zenTheme = storedTheme;

  const themeToggle = document.querySelector("#themeToggle");
  const isDark = () => {
    if (root.dataset.zenTheme) {
      return root.dataset.zenTheme === "dark";
    }
    return systemTheme.matches;
  };
  const updateThemeButton = () => {
    const dark = isDark();
    themeToggle?.setAttribute("aria-pressed", String(dark));
    if (themeToggle) {
      themeToggle.textContent = dark
        ? "Use light theme"
        : "Use dark theme";
    }
  };
  updateThemeButton();
  themeToggle?.addEventListener("click", () => {
    const next = isDark() ? "light" : "dark";
    root.dataset.zenTheme = next;
    localStorage.setItem("zen-theme", next);
    updateThemeButton();
  });
  systemTheme.addEventListener("change", () => {
    if (!root.dataset.zenTheme) updateThemeButton();
  });

  document.addEventListener("click", event => {
    const link = event.target.closest("a[data-catalog-link]");
    if (!link ||
        link.origin !== location.origin ||
        event.defaultPrevented ||
        event.button !== 0 ||
        event.metaKey ||
        event.ctrlKey ||
        event.shiftKey ||
        event.altKey ||
        link.hasAttribute("download") ||
        link.target) return;
    event.preventDefault();
    history.pushState({}, "", link.href);
    showPage(location.pathname);
    document.querySelector("#catalogMain")?.focus();
  });
  window.addEventListener("popstate", () => showPage(location.pathname));
  showPage(location.pathname);
});