Exact asger toggle (theme key + prefers-color-scheme), responsive container + full site-chrome components
- weirsoe-theme.js: match asger.weirsoe.dk exactly — localStorage['theme'], prefers-color-scheme default, light<->dark click delegation. - Container tokens + .wt-container(/--wide/--narrow/--bleed); Bulma adapter constrains content to a centred column past tablet (full-bleed on phones). - Site chrome extracted from agw/pw so it can drop its hardcoded CSS: .wt-header /.wt-nav/.wt-brand/.wt-nav-link/.wt-main/.wt-footer, postcard .wt-card(+date/ title/desc, --raised) and .wt-chip. README components table + theme-color note.
This commit is contained in:
+33
-37
@@ -1,54 +1,50 @@
|
||||
/* weirsoe-theme.js — persisted theme toggle for weirsoe-theme.css.
|
||||
/* weirsoe-theme.js — persisted light/dark toggle (matches asger.weirsøe.dk).
|
||||
*
|
||||
* 1) Prevent a flash of the wrong theme: put this MINIMAL snippet inline in
|
||||
* <head>, BEFORE any stylesheet (it runs pre-paint):
|
||||
* 1) No-flash: put this MINIMAL snippet inline in <head>, BEFORE any stylesheet
|
||||
* (runs pre-paint; respects the OS preference on first visit):
|
||||
*
|
||||
* <script>try{var t=localStorage.getItem('wt-theme');
|
||||
* document.documentElement.dataset.theme=t||'dark';}catch(e){
|
||||
* document.documentElement.dataset.theme='dark';}</script>
|
||||
* <script>(()=>{try{var t=localStorage.getItem('theme')||(matchMedia('(prefers-color-scheme: light)').matches?'light':'dark');document.documentElement.dataset.theme=t}catch(e){document.documentElement.dataset.theme='dark'}})()</script>
|
||||
*
|
||||
* 2) Load this file (defer is fine) and drop a toggle button somewhere:
|
||||
* 2) Load this file and drop the toggle button anywhere (exact markup from
|
||||
* asger.weirsøe.dk):
|
||||
*
|
||||
* <button class="theme-toggle" data-theme-toggle aria-label="Skift tema">
|
||||
* <button type="button" data-theme-toggle class="theme-toggle" aria-label="Skift tema" title="Skift mellem lyst og mørkt tema">
|
||||
* <svg class="sun-and-moon" aria-hidden="true" width="22" height="22" viewBox="0 0 24 24">
|
||||
* <circle class="sun" cx="12" cy="12" r="6" mask="url(#wt-moon)" fill="currentColor"/>
|
||||
* <g class="sun-beams" stroke="currentColor"><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.2" y1="4.2" x2="5.6" y2="5.6"/><line x1="18.4" y1="18.4" x2="19.8" y2="19.8"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.2" y1="19.8" x2="5.6" y2="18.4"/><line x1="18.4" y1="5.6" x2="19.8" y2="4.2"/></g>
|
||||
* <mask class="moon" id="wt-moon"><rect x="0" y="0" width="100%" height="100%" fill="white"/><circle cx="24" cy="10" r="6" fill="black"/></mask>
|
||||
* <mask class="moon" id="moon-mask"><rect x="0" y="0" width="100%" height="100%" fill="white"/><circle cx="24" cy="10" r="6" fill="black"/></mask>
|
||||
* <circle class="sun" cx="12" cy="12" r="6" mask="url(#moon-mask)" fill="currentColor"/>
|
||||
* <g class="sun-beams" stroke="currentColor"><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></g>
|
||||
* </svg>
|
||||
* </button>
|
||||
*
|
||||
* The toggle cycles dark -> light (add "terminal" yourself if you want a 3-way).
|
||||
* Cycles light ⇄ dark and persists to localStorage['theme'].
|
||||
*/
|
||||
(function () {
|
||||
var KEY = 'wt-theme';
|
||||
var root = document.documentElement;
|
||||
|
||||
function set(theme) {
|
||||
root.dataset.theme = theme;
|
||||
try { localStorage.setItem(KEY, theme); } catch (e) { /* ignore */ }
|
||||
function preferred() {
|
||||
return window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
}
|
||||
function apply() {
|
||||
var t;
|
||||
try { t = localStorage.getItem('theme'); } catch (e) { /* ignore */ }
|
||||
root.dataset.theme = t || preferred();
|
||||
}
|
||||
|
||||
// Ensure a theme is set even if the inline no-flash snippet was omitted.
|
||||
if (!root.dataset.theme) {
|
||||
var saved;
|
||||
try { saved = localStorage.getItem(KEY); } catch (e) { saved = null; }
|
||||
root.dataset.theme = saved || 'dark';
|
||||
}
|
||||
apply();
|
||||
// Re-apply after client-side navigations (Astro etc.) — harmless if unused.
|
||||
document.addEventListener('astro:after-swap', apply);
|
||||
|
||||
function wire() {
|
||||
document.querySelectorAll('[data-theme-toggle]').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
set(root.dataset.theme === 'dark' ? 'light' : 'dark');
|
||||
});
|
||||
});
|
||||
}
|
||||
document.addEventListener('click', function (e) {
|
||||
var btn = e.target.closest && e.target.closest('[data-theme-toggle]');
|
||||
if (!btn) return;
|
||||
var next = root.dataset.theme === 'light' ? 'dark' : 'light';
|
||||
root.dataset.theme = next;
|
||||
try { localStorage.setItem('theme', next); } catch (err) { /* ignore */ }
|
||||
});
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', wire);
|
||||
} else {
|
||||
wire();
|
||||
}
|
||||
|
||||
// Expose a tiny API for custom controls (e.g. a 3-way picker).
|
||||
window.weirsoeTheme = { set: set, get: function () { return root.dataset.theme; } };
|
||||
// Tiny API for custom controls (e.g. a 3-way picker incl. 'terminal').
|
||||
window.weirsoeTheme = {
|
||||
set: function (t) { root.dataset.theme = t; try { localStorage.setItem('theme', t); } catch (e) {} },
|
||||
get: function () { return root.dataset.theme; },
|
||||
};
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user