Files
SHiNE-server/shine-UI/js/services/theme-service.js
T
2026-09-22 14:09:02 +03:00

50 lines
1.6 KiB
JavaScript

const STORAGE_KEY = 'shine-ui-theme-mode-v1';
const MODES = new Set(['system', 'light', 'dark']);
let sessionMode = null;
function normalizeMode(value) {
const mode = String(value || '').trim().toLowerCase();
return MODES.has(mode) ? mode : 'system';
}
export function getThemeMode() {
if (sessionMode !== null) return sessionMode;
try {
return normalizeMode(localStorage.getItem(STORAGE_KEY));
} catch {
return 'system';
}
}
export function applyThemeMode(mode = getThemeMode()) {
const normalized = normalizeMode(mode);
const resolved = normalized === 'system'
? (window.matchMedia?.('(prefers-color-scheme: light)')?.matches ? 'light' : 'dark')
: normalized;
document.documentElement.dataset.themeMode = normalized;
document.documentElement.dataset.theme = resolved;
document.documentElement.style.colorScheme = resolved;
return { mode: normalized, resolved };
}
export function setThemeMode(mode) {
const normalized = normalizeMode(mode);
sessionMode = normalized;
try {
localStorage.setItem(STORAGE_KEY, normalized);
} catch {
// В приватном режиме тема всё равно применяется до закрытия страницы.
}
return applyThemeMode(normalized);
}
export function watchSystemTheme() {
const media = window.matchMedia?.('(prefers-color-scheme: light)');
if (!media) return () => {};
const onChange = () => {
if (getThemeMode() === 'system') applyThemeMode('system');
};
media.addEventListener?.('change', onChange);
return () => media.removeEventListener?.('change', onChange);
}