Per user: the mode indicator text 'light/dark/auto' next to the
toggle button is redundant — the button itself shows the current
mode in its label ('◐ auto' / '☀ light' / '☾ dark').
Removed:
- <span id='fx-mode-indicator'> from UtilityBar.astro
- getElementById('fx-mode-indicator') in applyTheme() JS
- (CSS for .fx-mode-indicator stays — minimal cost, no harm)
Build: 22 pages, 2.27s.
103 lines
3.6 KiB
Plaintext
103 lines
3.6 KiB
Plaintext
---
|
|
/**
|
|
* MOREMINIMORE - UtilityBar (from v6-utility)
|
|
* Extracted from Desktop/moreminomore-mockup-v7-5.html lines 571-589
|
|
*
|
|
* Top info bar — phone + clock + date + mode indicator + email + THEME TOGGLE
|
|
* Phone/email pulled from src/content/settings/site.md (single source of truth)
|
|
*
|
|
* Clock/date are updated by fx-animations.ts → fxClock() (id="fx-time", id="fx-date")
|
|
* Theme toggle: id="fx-theme-toggle" — click flips data-theme on <html> + saves to localStorage
|
|
*/
|
|
import { getEntry } from 'astro:content';
|
|
import type { CollectionEntry } from 'astro:content';
|
|
|
|
const site = (await getEntry('settings', 'site')) as CollectionEntry<'settings'>;
|
|
const phone = site?.data?.phone ?? '080-995-5945';
|
|
const email = site?.data?.email ?? 'contact@moreminimore.com';
|
|
---
|
|
|
|
<div id="v6-utility-inner" class="fx-utility-bar">
|
|
<div class="fx-utility-bar-left">
|
|
<span class="fx-utility-item">📞 <strong>{phone}</strong></span>
|
|
<span class="fx-utility-item" id="fx-time">⏱ — : — : —</span>
|
|
<span class="fx-utility-item" id="fx-date">📅 — — —</span>
|
|
</div>
|
|
<div class="fx-utility-bar-right">
|
|
<button
|
|
type="button"
|
|
class="fx-theme-toggle"
|
|
id="fx-theme-toggle"
|
|
aria-label="Toggle light/dark mode"
|
|
title="Toggle light/dark mode"
|
|
>
|
|
◐ auto
|
|
</button>
|
|
<a href={`mailto:${email}`} class="fx-utility-item" style="text-decoration:none">✉ {email}</a>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
/**
|
|
* Theme toggle logic — runs on every page (mounted via UtilityBar.astro).
|
|
* States: 'light' | 'dark' | 'auto' (follows system)
|
|
* Persists to localStorage; default = auto (follow OS preference)
|
|
*/
|
|
type ThemeMode = 'light' | 'dark' | 'auto';
|
|
const STORAGE_KEY = 'moreminimore-theme';
|
|
|
|
function getStoredTheme(): ThemeMode {
|
|
try {
|
|
const stored = localStorage.getItem(STORAGE_KEY);
|
|
if (stored === 'light' || stored === 'dark' || stored === 'auto') return stored;
|
|
} catch (_) { /* localStorage blocked */ }
|
|
return 'auto';
|
|
}
|
|
|
|
function effectiveTheme(mode: ThemeMode): 'light' | 'dark' {
|
|
if (mode === 'auto') {
|
|
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
}
|
|
return mode;
|
|
}
|
|
|
|
function applyTheme(mode: ThemeMode) {
|
|
const eff = effectiveTheme(mode);
|
|
// Use class instead of data-theme (Astro/Vite keeps .dark selectors)
|
|
if (eff === 'dark') {
|
|
document.documentElement.classList.add('dark');
|
|
} else {
|
|
document.documentElement.classList.remove('dark');
|
|
}
|
|
// Update button label to reflect current mode (button is the sole indicator)
|
|
const btn = document.getElementById('fx-theme-toggle');
|
|
if (btn) {
|
|
btn.textContent = mode === 'auto' ? '◐ auto' : mode === 'light' ? '☀ light' : '☾ dark';
|
|
}
|
|
}
|
|
|
|
function cycleTheme() {
|
|
const current = getStoredTheme();
|
|
const next: ThemeMode = current === 'light' ? 'dark' : current === 'dark' ? 'auto' : 'light';
|
|
try { localStorage.setItem(STORAGE_KEY, next); } catch (_) { /* ignore */ }
|
|
applyTheme(next);
|
|
}
|
|
|
|
// Initialize on load
|
|
applyTheme(getStoredTheme());
|
|
|
|
// Wire button (idempotent — fires on every page navigation)
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const btn = document.getElementById('fx-theme-toggle');
|
|
if (btn && !btn.dataset.bound) {
|
|
btn.dataset.bound = 'true';
|
|
btn.addEventListener('click', cycleTheme);
|
|
}
|
|
});
|
|
|
|
// If user hasn't picked explicitly, follow OS changes live
|
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
|
if (getStoredTheme() === 'auto') applyTheme('auto');
|
|
});
|
|
</script>
|