50 lines
No EOL
1.7 KiB
JavaScript
50 lines
No EOL
1.7 KiB
JavaScript
document.addEventListener("DOMContentLoaded", () => {
|
|
const themeSwitch = document.getElementById("theme-switch");
|
|
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
|
|
|
|
const applyTheme = (theme) => {
|
|
document.documentElement.classList.toggle("dark", theme === "dark");
|
|
};
|
|
|
|
const getStoredTheme = () => localStorage.getItem("theme");
|
|
const setStoredTheme = (theme) => localStorage.setItem("theme", theme);
|
|
|
|
// Initial load
|
|
const savedTheme = getStoredTheme();
|
|
if (savedTheme) {
|
|
applyTheme(savedTheme);
|
|
} else {
|
|
applyTheme(prefersDarkScheme.matches ? "dark" : "light");
|
|
}
|
|
|
|
// system changes
|
|
prefersDarkScheme.addEventListener("change", (e) => {
|
|
const saved = getStoredTheme();
|
|
if (!saved) {
|
|
applyTheme(e.matches ? "dark" : "light");
|
|
}
|
|
});
|
|
|
|
// toggle handler
|
|
themeSwitch.addEventListener("click", () => {
|
|
const currentTheme = document.documentElement.classList.contains("dark") ? "dark" : "light";
|
|
const newTheme = currentTheme === "dark" ? "light" : "dark";
|
|
applyTheme(newTheme);
|
|
setStoredTheme(newTheme);
|
|
});
|
|
|
|
|
|
const updateBodyThemeAttr = () => {
|
|
const current = document.documentElement.classList.contains("dark") ? "dark" : "light";
|
|
document.body.setAttribute("data-theme", current);
|
|
};
|
|
updateBodyThemeAttr();
|
|
|
|
// update on change
|
|
const observer = new MutationObserver(updateBodyThemeAttr);
|
|
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
|
|
|
|
prefersDarkScheme.addEventListener("change", () => {
|
|
updateBodyThemeAttr();
|
|
});
|
|
}); |