dark mode
This commit is contained in:
File diff suppressed because one or more lines are too long
78
web/static/vendor/theme.js
vendored
Normal file
78
web/static/vendor/theme.js
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
(function () {
|
||||
var STORAGE_KEY = "theme";
|
||||
var root = document.documentElement;
|
||||
var mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
|
||||
function getStoredTheme() {
|
||||
var value = null;
|
||||
try {
|
||||
value = localStorage.getItem(STORAGE_KEY);
|
||||
} catch (e) {
|
||||
value = null;
|
||||
}
|
||||
return value === "dark" || value === "light" ? value : null;
|
||||
}
|
||||
|
||||
function getPreferredTheme() {
|
||||
return mediaQuery.matches ? "dark" : "light";
|
||||
}
|
||||
|
||||
function applyTheme(theme) {
|
||||
root.classList.toggle("dark", theme === "dark");
|
||||
}
|
||||
|
||||
function currentTheme() {
|
||||
return root.classList.contains("dark") ? "dark" : "light";
|
||||
}
|
||||
|
||||
function setStoredTheme(theme) {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, theme);
|
||||
} catch (e) {
|
||||
// localStorage may be unavailable in private mode or blocked contexts.
|
||||
}
|
||||
}
|
||||
|
||||
function updateToggleState(theme) {
|
||||
var button = document.getElementById("themeToggle");
|
||||
if (!button) return;
|
||||
|
||||
var isDark = theme === "dark";
|
||||
button.setAttribute("aria-pressed", isDark ? "true" : "false");
|
||||
button.textContent = isDark ? "Light mode" : "Dark mode";
|
||||
}
|
||||
|
||||
function applyInitialTheme() {
|
||||
var stored = getStoredTheme();
|
||||
applyTheme(stored || getPreferredTheme());
|
||||
}
|
||||
|
||||
window.toggleTheme = function toggleTheme() {
|
||||
var next = currentTheme() === "dark" ? "light" : "dark";
|
||||
applyTheme(next);
|
||||
setStoredTheme(next);
|
||||
updateToggleState(next);
|
||||
};
|
||||
|
||||
window.initThemeToggle = function initThemeToggle() {
|
||||
updateToggleState(currentTheme());
|
||||
};
|
||||
|
||||
if (typeof mediaQuery.addEventListener === "function") {
|
||||
mediaQuery.addEventListener("change", function (event) {
|
||||
if (getStoredTheme()) return;
|
||||
var theme = event.matches ? "dark" : "light";
|
||||
applyTheme(theme);
|
||||
updateToggleState(theme);
|
||||
});
|
||||
} else if (typeof mediaQuery.addListener === "function") {
|
||||
mediaQuery.addListener(function (event) {
|
||||
if (getStoredTheme()) return;
|
||||
var theme = event.matches ? "dark" : "light";
|
||||
applyTheme(theme);
|
||||
updateToggleState(theme);
|
||||
});
|
||||
}
|
||||
|
||||
applyInitialTheme();
|
||||
})();
|
||||
Reference in New Issue
Block a user