Add light/dark mode toggle in settings
Settings gains a "Dark mode" switch. Theme preference is device-global (localStorage), independent of accounts. With no explicit choice the app keeps following the OS via prefers-color-scheme; picking a mode sets data-theme on <html>, which the CSS treats as an override (attribute selector beats the media query). A tiny <head> script applies a saved choice before first paint to avoid a light/dark flash. Toggling previews live, independent of Save/Cancel. Bumps the service-worker cache. Verified in a headless-browser run: default follows OS, enabling dark swaps the palette, the choice persists across reload, and toggling back restores light.
This commit is contained in:
+24
@@ -1485,15 +1485,39 @@
|
||||
});
|
||||
|
||||
// Settings dialog (puppy name + birthday)
|
||||
// ---------- theme ----------
|
||||
// Preference is device-global (not per user). No stored choice → follow the
|
||||
// OS via the prefers-color-scheme media query; a choice sets data-theme on
|
||||
// <html>, which the CSS treats as an override. The <head> applies any saved
|
||||
// choice before first paint; this just resolves state and reacts to the toggle.
|
||||
const THEME_KEY = "puppy-tracker:theme";
|
||||
const prefersDark = () =>
|
||||
window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
function effectiveTheme() {
|
||||
const s = localStorage.getItem(THEME_KEY);
|
||||
return s === "light" || s === "dark" ? s : (prefersDark() ? "dark" : "light");
|
||||
}
|
||||
function setTheme(theme) {
|
||||
document.documentElement.dataset.theme = theme;
|
||||
try { localStorage.setItem(THEME_KEY, theme); } catch { /* ignore */ }
|
||||
}
|
||||
|
||||
const settingsDialog = document.getElementById("settings-dialog");
|
||||
const settingsForm = document.getElementById("settings-form");
|
||||
const settingsName = document.getElementById("settings-name");
|
||||
const settingsBirthday = document.getElementById("settings-birthday");
|
||||
const settingsTheme = document.getElementById("settings-theme");
|
||||
|
||||
// Apply live so the toggle previews immediately (independent of Save/Cancel).
|
||||
settingsTheme.addEventListener("change", () => {
|
||||
setTheme(settingsTheme.checked ? "dark" : "light");
|
||||
});
|
||||
|
||||
function openSettingsDialog() {
|
||||
const cfg = loadConfig();
|
||||
settingsName.value = cfg.name;
|
||||
settingsBirthday.value = cfg.birthday;
|
||||
settingsTheme.checked = effectiveTheme() === "dark";
|
||||
settingsDialog.showModal();
|
||||
setTimeout(() => settingsName.focus(), 50);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user