Update theme.js

This commit is contained in:
Kosztyk 2026-01-12 22:06:43 +02:00 committed by GitHub
parent f71ebd5d98
commit e56020d086
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,15 +1,7 @@
/*
* ConvertX Theme Toggle
*
* - Stores explicit user choice in localStorage under KEY.
* - If no explicit choice exists, the UI follows the OS preference
* (prefers-color-scheme) and does not set data-theme.
*/
(() => {
const KEY = "convertx-theme";
const root = document.documentElement;
const mql = window.matchMedia?.("(prefers-color-scheme: dark)");
const getStoredTheme = () => {
@ -23,14 +15,16 @@
const getSystemTheme = () => (mql && mql.matches ? "dark" : "light");
const getEffectiveTheme = () => getStoredTheme() ?? getSystemTheme();
const applyColorSchemeOnly = (theme) => {
// Hint to the browser for built-in UI (form controls, scrollbars, etc.)
root.style.colorScheme = theme === "dark" ? "dark" : "light";
};
const setTheme = (theme, { persist } = { persist: true }) => {
if (theme !== "dark" && theme !== "light") return;
root.setAttribute("data-theme", theme);
// Hint to the browser for built-in UI (form controls, scrollbars, etc.)
root.style.colorScheme = theme;
applyColorSchemeOnly(theme);
if (persist) {
try {
@ -43,28 +37,27 @@
const clearThemeOverride = () => {
root.removeAttribute("data-theme");
root.style.colorScheme = "";
try {
localStorage.removeItem(KEY);
} catch {
// ignore
}
// Important: even in auto-mode we still set color-scheme to system theme.
applyColorSchemeOnly(getSystemTheme());
};
const getEffectiveTheme = () => getStoredTheme() ?? getSystemTheme();
const syncUI = () => {
const checkbox = document.getElementById("cx-theme-switch");
const label = document.getElementById("cx-theme-label");
if (!checkbox && !label) return;
const theme = getEffectiveTheme();
if (checkbox) {
checkbox.checked = theme === "dark";
checkbox.setAttribute(
"aria-checked",
checkbox.checked ? "true" : "false",
);
checkbox.setAttribute("aria-checked", checkbox.checked ? "true" : "false");
}
if (label) {
@ -73,13 +66,16 @@
};
// --- Initial state ---
// If the user chose a theme before, enforce it.
const stored = getStoredTheme();
if (stored) {
// Explicit override: lock both tokens + native controls.
setTheme(stored, { persist: false });
} else {
// Auto mode: follow OS, but ensure native controls match.
applyColorSchemeOnly(getSystemTheme());
}
// Keep the toggle in sync once the DOM is available.
document.addEventListener("DOMContentLoaded", () => {
syncUI();
@ -87,21 +83,22 @@
if (!checkbox) return;
checkbox.addEventListener("change", () => {
// Explicit user choice always overrides system.
setTheme(checkbox.checked ? "dark" : "light", { persist: true });
syncUI();
});
});
// If there's no explicit override, reflect OS changes in the UI.
if (mql) {
const onChange = () => {
if (getStoredTheme() == null) {
clearThemeOverride();
// Keep auto: no data-theme, but update color-scheme + UI.
root.removeAttribute("data-theme");
applyColorSchemeOnly(getSystemTheme());
syncUI();
}
};
// Safari uses addListener/removeListener
if (typeof mql.addEventListener === "function") {
mql.addEventListener("change", onChange);
} else if (typeof mql.addListener === "function") {