88 lines
2.8 KiB
JavaScript
88 lines
2.8 KiB
JavaScript
/* Theme Initialization Script
|
|
* Handles theme detection and application based on localStorage preference or browser settings
|
|
* Must be loaded in <head> before page content to prevent flash of unstyled content
|
|
*/
|
|
|
|
(function () {
|
|
"use strict";
|
|
|
|
// Get saved theme preference from localStorage
|
|
const savedTheme = localStorage.getItem("theme-preference");
|
|
|
|
// Apply theme immediately to prevent FOUC (Flash of Unstyled Content)
|
|
function applyTheme(theme) {
|
|
const body = document.body || document.documentElement;
|
|
|
|
if (theme === "dark") {
|
|
body.classList.remove("light-mode");
|
|
body.classList.add("dark-mode");
|
|
} else if (theme === "light") {
|
|
body.classList.remove("dark-mode");
|
|
body.classList.add("light-mode");
|
|
} else {
|
|
// 'auto' mode - remove manual override classes
|
|
body.classList.remove("dark-mode", "light-mode");
|
|
}
|
|
}
|
|
|
|
// Apply theme based on preference
|
|
if (
|
|
savedTheme === "dark" ||
|
|
savedTheme === "light" ||
|
|
savedTheme === "auto"
|
|
) {
|
|
applyTheme(savedTheme);
|
|
}
|
|
// If no preference saved, default to 'auto' (browser preference)
|
|
|
|
// Make theme switching function available globally
|
|
window.setTheme = function (theme) {
|
|
if (theme === "light" || theme === "dark" || theme === "auto") {
|
|
localStorage.setItem("theme-preference", theme);
|
|
applyTheme(theme);
|
|
|
|
// Trigger custom event for components that need to update (e.g., charts)
|
|
window.dispatchEvent(
|
|
new CustomEvent("themechange", { detail: { theme } }),
|
|
);
|
|
}
|
|
};
|
|
|
|
// Get current effective theme (resolves 'auto' to actual theme)
|
|
window.getEffectiveTheme = function () {
|
|
const savedTheme = localStorage.getItem("theme-preference");
|
|
|
|
if (savedTheme === "dark") return "dark";
|
|
if (savedTheme === "light") return "light";
|
|
|
|
// 'auto' or no preference - check system preference
|
|
if (
|
|
window.matchMedia &&
|
|
window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
) {
|
|
return "dark";
|
|
}
|
|
return "light";
|
|
};
|
|
|
|
// Get saved theme preference (returns 'light', 'dark', 'auto', or null)
|
|
window.getThemePreference = function () {
|
|
return localStorage.getItem("theme-preference") || "auto";
|
|
};
|
|
|
|
// Listen for system theme changes when in auto mode
|
|
if (window.matchMedia) {
|
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
mediaQuery.addEventListener("change", function (e) {
|
|
const savedTheme = localStorage.getItem("theme-preference");
|
|
// Only react to system changes if in auto mode
|
|
if (!savedTheme || savedTheme === "auto") {
|
|
// Trigger theme change event for components that need to update
|
|
window.dispatchEvent(
|
|
new CustomEvent("themechange", { detail: { theme: "auto" } }),
|
|
);
|
|
}
|
|
});
|
|
}
|
|
})();
|