setup
All checks were successful
Deploy / deploy-staging (push) Successful in 6s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-04-15 01:06:16 +02:00
parent 5677a8d806
commit 11fb43b9ce
5 changed files with 334 additions and 106 deletions

View File

@@ -8,38 +8,75 @@ function readThemePreference(key, fallback) {
}
}
const themeMode = readThemePreference('nexus.theme', document.documentElement.dataset.theme || 'day');
const themeAccent = readThemePreference('nexus.accent', document.documentElement.dataset.accent || 'logo');
const moduleName = document.documentElement.dataset.module || '';
const mainThemeMode = readThemePreference('nexus.theme', 'day');
const mainThemeAccent = readThemePreference('nexus.accent', 'logo');
const moduleThemeMode = moduleName ? readThemePreference(`nexus.module.${moduleName}.theme`, 'inherit') : mainThemeMode;
const moduleThemeAccent = moduleName ? readThemePreference(`nexus.module.${moduleName}.accent`, 'inherit') : mainThemeAccent;
function applyTheme(mode, accent) {
const normalizedMode = ['day', 'night'].includes(mode) ? mode : 'day';
const normalizedAccent = ['logo', 'pink', 'cyan', 'orange', 'green'].includes(accent) ? accent : 'logo';
document.documentElement.dataset.theme = normalizedMode;
document.documentElement.dataset.accent = normalizedAccent;
function normalizeThemeValue(value, allowed, fallback) {
return allowed.includes(value) ? value : fallback;
}
function storedTheme() {
const rawMode = moduleName ? readThemePreference(`nexus.module.${moduleName}.theme`, 'inherit') : readThemePreference('nexus.theme', 'day');
const rawAccent = moduleName ? readThemePreference(`nexus.module.${moduleName}.accent`, 'inherit') : readThemePreference('nexus.accent', 'logo');
const mode = moduleName ? normalizeThemeValue(rawMode, ['inherit', 'day', 'night'], 'inherit') : normalizeThemeValue(rawMode, ['day', 'night'], 'day');
const accent = moduleName ? normalizeThemeValue(rawAccent, ['inherit', 'logo', 'pink', 'cyan', 'orange', 'green'], 'inherit') : normalizeThemeValue(rawAccent, ['logo', 'pink', 'cyan', 'orange', 'green'], 'logo');
return { mode, accent };
}
function applyTheme(mode, accent, persist = true) {
const allowedModes = moduleName ? ['inherit', 'day', 'night'] : ['day', 'night'];
const allowedAccents = moduleName ? ['inherit', 'logo', 'pink', 'cyan', 'orange', 'green'] : ['logo', 'pink', 'cyan', 'orange', 'green'];
const normalizedMode = normalizeThemeValue(mode, allowedModes, moduleName ? 'inherit' : 'day');
const normalizedAccent = normalizeThemeValue(accent, allowedAccents, moduleName ? 'inherit' : 'logo');
const effectiveMode = normalizedMode === 'inherit' ? mainThemeMode : normalizedMode;
const effectiveAccent = normalizedAccent === 'inherit' ? mainThemeAccent : normalizedAccent;
document.documentElement.dataset.theme = effectiveMode;
document.documentElement.dataset.accent = effectiveAccent;
try {
localStorage.setItem('nexus.theme', normalizedMode);
localStorage.setItem('nexus.accent', normalizedAccent);
if (persist) {
if (moduleName) {
if (normalizedMode === 'inherit') {
localStorage.removeItem(`nexus.module.${moduleName}.theme`);
} else {
localStorage.setItem(`nexus.module.${moduleName}.theme`, normalizedMode);
}
if (normalizedAccent === 'inherit') {
localStorage.removeItem(`nexus.module.${moduleName}.accent`);
} else {
localStorage.setItem(`nexus.module.${moduleName}.accent`, normalizedAccent);
}
} else {
localStorage.setItem('nexus.theme', normalizedMode);
localStorage.setItem('nexus.accent', normalizedAccent);
}
}
} catch (error) {
// Ignore blocked storage; the current page still receives the theme.
}
return { mode: normalizedMode, accent: normalizedAccent };
}
applyTheme(themeMode, themeAccent);
const initialTheme = applyTheme(moduleThemeMode, moduleThemeAccent, false);
const themeModeSelect = document.querySelector('[data-theme-mode]');
const themeAccentSelect = document.querySelector('[data-theme-accent]');
if (themeModeSelect) {
themeModeSelect.value = document.documentElement.dataset.theme;
themeModeSelect.value = initialTheme.mode;
themeModeSelect.addEventListener('change', () => {
applyTheme(themeModeSelect.value, document.documentElement.dataset.accent);
const current = storedTheme();
applyTheme(themeModeSelect.value, current.accent);
});
}
if (themeAccentSelect) {
themeAccentSelect.value = document.documentElement.dataset.accent;
themeAccentSelect.value = initialTheme.accent;
themeAccentSelect.addEventListener('change', () => {
applyTheme(document.documentElement.dataset.theme, themeAccentSelect.value);
const current = storedTheme();
applyTheme(current.mode, themeAccentSelect.value);
});
}