77 lines
2.6 KiB
TypeScript
77 lines
2.6 KiB
TypeScript
(() => {
|
|
const getStoredTheme = () => localStorage.getItem("theme");
|
|
const setStoredTheme = (theme: string) => localStorage.setItem("theme", theme);
|
|
|
|
const getPreferredTheme = () => {
|
|
const storedTheme = getStoredTheme();
|
|
if (storedTheme) {
|
|
return storedTheme;
|
|
}
|
|
|
|
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
};
|
|
|
|
const setTheme = (theme: string) => {
|
|
if (theme === "auto") {
|
|
document.documentElement.setAttribute(
|
|
"data-bs-theme",
|
|
window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light",
|
|
);
|
|
} else {
|
|
document.documentElement.setAttribute("data-bs-theme", theme);
|
|
}
|
|
};
|
|
|
|
setTheme(getPreferredTheme());
|
|
|
|
const showActiveTheme = (theme: string, focus = false) => {
|
|
const themeSwitcher = document.querySelector("#bd-theme");
|
|
|
|
if (!themeSwitcher) {
|
|
return;
|
|
}
|
|
|
|
const themeSwitcherText = document.querySelector("#bd-theme-text");
|
|
const activeThemeIcon = document.querySelector(".theme-icon-active");
|
|
const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`);
|
|
const activeThemeIconClass = btnToActive.querySelector("i.bi").className.match(/bi-[\w-]+/)[0];
|
|
|
|
document.querySelectorAll("[data-bs-theme-value]").forEach((element) => {
|
|
element.classList.remove("active");
|
|
element.setAttribute("aria-pressed", "false");
|
|
});
|
|
|
|
btnToActive.classList.add("active");
|
|
btnToActive.setAttribute("aria-pressed", "true");
|
|
const classesToRemove = Array.from(activeThemeIcon.classList).filter((className) => className.startsWith("bi-"));
|
|
activeThemeIcon.classList.remove(...classesToRemove);
|
|
activeThemeIcon.classList.add(activeThemeIconClass);
|
|
const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`;
|
|
themeSwitcher.setAttribute("aria-label", themeSwitcherLabel);
|
|
|
|
if (focus) {
|
|
themeSwitcher.focus();
|
|
}
|
|
};
|
|
|
|
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
|
|
const storedTheme = getStoredTheme();
|
|
if (storedTheme !== "light" && storedTheme !== "dark") {
|
|
setTheme(getPreferredTheme());
|
|
}
|
|
});
|
|
|
|
window.addEventListener("DOMContentLoaded", () => {
|
|
showActiveTheme(getPreferredTheme());
|
|
|
|
document.querySelectorAll("[data-bs-theme-value]").forEach((toggle) => {
|
|
toggle.addEventListener("click", () => {
|
|
const theme = toggle.getAttribute("data-bs-theme-value") || '';
|
|
setStoredTheme(theme);
|
|
setTheme(theme);
|
|
showActiveTheme(theme, true);
|
|
});
|
|
});
|
|
});
|
|
})();
|