Archived
45 lines
1.6 KiB
JavaScript
45 lines
1.6 KiB
JavaScript
(() => {
|
|
const media = window.matchMedia("(prefers-color-scheme: dark)");
|
|
const storageKey = "karldns-theme";
|
|
const systemTheme = () => (media.matches ? "dark" : "light");
|
|
const storedTheme = () => {
|
|
try {
|
|
return window.localStorage.getItem(storageKey);
|
|
} catch (_) {
|
|
return null;
|
|
}
|
|
};
|
|
const setStoredTheme = (theme) => {
|
|
try {
|
|
window.localStorage.setItem(storageKey, theme);
|
|
} catch (_) {}
|
|
};
|
|
const syncToggle = (theme) => {
|
|
document.querySelectorAll("[data-theme-toggle]").forEach((button) => {
|
|
const nextTheme = theme === "dark" ? "light" : "dark";
|
|
button.dataset.themeNext = nextTheme;
|
|
button.setAttribute("aria-label", `Switch to ${nextTheme.toLowerCase()} theme`);
|
|
});
|
|
};
|
|
const applyTheme = (requestedTheme = storedTheme() || systemTheme()) => {
|
|
const theme = requestedTheme === "dark" ? "dark" : "light";
|
|
document.documentElement.setAttribute("data-bs-theme", theme);
|
|
syncToggle(theme);
|
|
return theme;
|
|
};
|
|
applyTheme();
|
|
media.addEventListener("change", () => {
|
|
if (!storedTheme()) applyTheme();
|
|
});
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
syncToggle(document.documentElement.getAttribute("data-bs-theme") || "light");
|
|
});
|
|
document.addEventListener("click", (event) => {
|
|
const toggle = event.target.closest("[data-theme-toggle]");
|
|
if (!toggle) return;
|
|
const currentTheme = document.documentElement.getAttribute("data-bs-theme") || systemTheme();
|
|
const nextTheme = currentTheme === "dark" ? "light" : "dark";
|
|
setStoredTheme(nextTheme);
|
|
applyTheme(nextTheme);
|
|
});
|
|
})(); |