Mercurial
comparison mrjunejune/src/index.js @ 258:60a876c4587a
[ui] Add semantic primitive ownership
Build a layered Zenbu token and sizing system, make authored controls use native-underneath primitives, migrate mrjunejune without imposing visual surfaces, and document/enforce HTML ownership in the catalog and wiki.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Wed, 05 Aug 2026 05:25:40 -0700 |
| parents | 30c2196d03d4 |
| children |
comparison
equal
deleted
inserted
replaced
| 257:609d3c6aff4e | 258:60a876c4587a |
|---|---|
| 17 return normalizeTheme(localStorage.getItem(THEME_STORAGE_KEY)); | 17 return normalizeTheme(localStorage.getItem(THEME_STORAGE_KEY)); |
| 18 } | 18 } |
| 19 | 19 |
| 20 function updateThemeColor() { | 20 function updateThemeColor() { |
| 21 const probe = document.createElement('span'); | 21 const probe = document.createElement('span'); |
| 22 probe.style.background = 'var(--zen-color-canvas)'; | 22 probe.style.background = 'var(--zenbu-sys-color-surface-page)'; |
| 23 document.body.append(probe); | 23 document.body.append(probe); |
| 24 const color = getComputedStyle(probe).backgroundColor; | 24 const color = getComputedStyle(probe).backgroundColor; |
| 25 probe.remove(); | 25 probe.remove(); |
| 26 document.querySelector('meta[name="theme-color"]') | 26 document.querySelector('meta[name="theme-color"]') |
| 27 ?.setAttribute('content', color); | 27 ?.setAttribute('content', color); |
| 55 const currentPreference = applyTheme(getThemePreference()); | 55 const currentPreference = applyTheme(getThemePreference()); |
| 56 if (localStorage.getItem(THEME_STORAGE_KEY) !== currentPreference) { | 56 if (localStorage.getItem(THEME_STORAGE_KEY) !== currentPreference) { |
| 57 localStorage.setItem(THEME_STORAGE_KEY, currentPreference); | 57 localStorage.setItem(THEME_STORAGE_KEY, currentPreference); |
| 58 } | 58 } |
| 59 | 59 |
| 60 function enhanceLinks(root = document) { | |
| 61 const links = root instanceof HTMLAnchorElement | |
| 62 ? [root] | |
| 63 : [...root.querySelectorAll?.('a') || []]; | |
| 64 for (const link of links) { | |
| 65 if (link.closest('zen-link, zen-button') || | |
| 66 link.dataset.zenLinkEffect === 'none') { | |
| 67 continue; | |
| 68 } | |
| 69 const wrapper = document.createElement('zen-link'); | |
| 70 wrapper.setAttribute('effect', 'paw'); | |
| 71 link.before(wrapper); | |
| 72 wrapper.append(link); | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 window.addEventListener('DOMContentLoaded', () => { | |
| 77 enhanceLinks(); | |
| 78 const observer = new MutationObserver(records => { | |
| 79 for (const record of records) { | |
| 80 for (const node of record.addedNodes) { | |
| 81 if (node instanceof Element) enhanceLinks(node); | |
| 82 } | |
| 83 } | |
| 84 }); | |
| 85 observer.observe(document.body, { childList: true, subtree: true }); | |
| 86 }); | |
| 87 | |
| 60 document.querySelector('#themeToggle')?.addEventListener('click', () => { | 88 document.querySelector('#themeToggle')?.addEventListener('click', () => { |
| 61 const current = getThemePreference(); | 89 const current = getThemePreference(); |
| 62 const next = THEMES[(THEMES.indexOf(current) + 1) % THEMES.length]; | 90 const next = THEMES[(THEMES.indexOf(current) + 1) % THEMES.length]; |
| 63 applyTheme(next, true); | 91 applyTheme(next, true); |
| 64 }); | 92 }); |