type Theme = 'light' | 'dark' | 'system';
class ThemeManager {
private theme: Theme;
private effectiveTheme: 'light' | 'dark';
private mediaQuery: MediaQueryList;
constructor() {
this.theme = (localStorage.getItem('theme') as Theme) || 'system';
this.effectiveTheme = 'light';
this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
this.updateEffectiveTheme();
this.mediaQuery.addEventListener('change', () => this.updateEffectiveTheme());
}
setTheme(newTheme: Theme): void {
if (['light', 'dark', 'system'].includes(newTheme)) {
this.theme = newTheme;
localStorage.setItem('theme', newTheme);
this.updateEffectiveTheme();
}
}
private updateEffectiveTheme(): void {
if (this.theme === 'system') {
this.effectiveTheme = this.mediaQuery.matches ? 'dark' : 'light';
} else {
this.effectiveTheme = this.theme;
}
document.documentElement.classList.remove('theme-light', 'theme-dark');
document.documentElement.classList.add(`theme-${this.effectiveTheme}`);
}
getTheme(): Theme {
return this.theme;
}
getEffectiveTheme(): 'light' | 'dark' {
return this.effectiveTheme;
}
}