import { WebComponent } from 'web-component-base' /** * The shared chrome for every example page — itself built with * `web-component-base` (dogfooding). It renders into light DOM, so the shared * `shell.css` styles it like everything else. */ class AppHeader extends WebComponent { static props = { heading: '' } get template() { return ` web-component-base ${this.props.heading} ← All examples ` } } customElements.define('app-header', AppHeader) // --------------------------------------------------------------------------- // Theme toggle // // The initial theme is applied by a tiny inline
script (so there is no // flash of the wrong theme). Here we build the toggle control, keep it in sync, // and follow the OS while the user hasn't made an explicit choice. // --------------------------------------------------------------------------- const THEME_KEY = 'wcb-theme' const prefersDark = window.matchMedia('(prefers-color-scheme: dark)') const effectiveTheme = () => document.documentElement.dataset.theme || (prefersDark.matches ? 'dark' : 'light') const SUN_ICON = `` const MOON_ICON = `` const themeToggle = document.createElement('button') themeToggle.type = 'button' themeToggle.className = 'theme-toggle' function syncToggle() { const dark = effectiveTheme() === 'dark' themeToggle.innerHTML = dark ? SUN_ICON : MOON_ICON const label = `Switch to ${dark ? 'light' : 'dark'} theme` themeToggle.setAttribute('aria-label', label) themeToggle.title = label } themeToggle.addEventListener('click', () => { const next = effectiveTheme() === 'dark' ? 'light' : 'dark' document.documentElement.dataset.theme = next try { localStorage.setItem(THEME_KEY, next) } catch { /* private mode / storage disabled — the choice just won't persist */ } syncToggle() }) // Follow OS changes only while the user hasn't chosen explicitly. prefersDark.addEventListener('change', () => { let stored = null try { stored = localStorage.getItem(THEME_KEY) } catch { /* ignore */ } if (!stored) { document.documentElement.dataset.theme = prefersDark.matches ? 'dark' : 'light' } syncToggle() }) syncToggle() // --------------------------------------------------------------------------- // Source preview // // Every example page shows the source of its own implementation. Vite inlines // each file's raw text at build time via `?raw` glob imports; we look them up // by the example's folder (taken from the URL) so this works identically in dev // and in the hashed production build (unlike reading rewritten