StarfallBot/web/static/js/theme-switcher.js

89 lines
3.0 KiB
JavaScript

"use strict";
class S_ThemeSwitcher {
static attach() {
window.S_ThemeSwitcher = new S_ThemeSwitcher();
}
constructor() {
this.setTheme(this.getStoredTheme() || this.getPreferredTheme());
this.showActiveTheme();
document.querySelectorAll("[data-bs-theme-value]").forEach(function (button) {
button.addEventListener("click", () => this.manageThemeClick(button, true));
}, this);
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
const storedTheme = this.getStoredTheme();
if (storedTheme !== "light" && storedTheme !== "dark") {
const theme = this.getColorTheme();
const themeButton = document.querySelector("[data-bs-theme-value=\"" + theme + "\"]");
this.manageThemeClick(themeButton);
}
});
const breakpointMd = window.getComputedStyle(document.body).getPropertyValue("--bs-breakpoint-md");
const matchMd = window.matchMedia("(min-width: " + breakpointMd + ")");
this.manageThemeText(matchMd.matches);
matchMd.addEventListener("change", (ev) => this.manageThemeText(ev.matches));
}
getStoredTheme() {
return localStorage.getItem("theme");
}
setStoredTheme(theme) {
localStorage.setItem("theme", theme);
}
getPreferredTheme() {
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
getColorTheme() {
const theme = this.getStoredTheme();
return ('auto' === theme) ? this.getPreferredTheme() : theme;
}
setTheme(theme) {
document.documentElement.setAttribute("data-bs-theme", ("auto" === theme) ? this.getPreferredTheme() : theme);
}
showActiveTheme(focus = false) {
const themeSwitcher = document.querySelector("#theme");
if (!themeSwitcher) { return; }
const themeSwitcherIcon = themeSwitcher.querySelector("i");
const activeTheme = this.getColorTheme();
const activeThemeButton = document.querySelector("[data-bs-theme-value=\"" + activeTheme + "\"]");
const activeThemeButtonIcon = activeThemeButton.querySelector("i");
themeSwitcherIcon.classList = activeThemeButtonIcon.classList;
if (focus) {
themeSwitcher.focus();
}
}
manageThemeClick(button, focus = false) {
const theme = button.getAttribute("data-bs-theme-value");
this.setStoredTheme(theme);
this.setTheme(theme);
this.showActiveTheme(focus);
}
manageThemeText(matches) {
const themeSwitcher = document.querySelector("#theme");
if (!themeSwitcher) { return; }
const themeSwitcherText = themeSwitcher.querySelector("span");
themeSwitcherText.classList.toggle("visually-hidden", matches);
}
}
if (document.readyState !== "loading") {
S_ThemeSwitcher.attach();
} else {
document.addEventListener("DOMContentLoaded", S_ThemeSwitcher.attach);
}