88 lines
1.7 KiB
TypeScript
88 lines
1.7 KiB
TypeScript
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
import { themeService, type Theme } from '../services/theme-service.js';
|
|
|
|
export type { Theme };
|
|
|
|
/**
|
|
* Lit reactive controller for theme management
|
|
* Automatically updates the host component when theme changes
|
|
*
|
|
* Usage:
|
|
* ```typescript
|
|
* class MyComponent extends LitElement {
|
|
* private theme = new ThemeController(this);
|
|
*
|
|
* render() {
|
|
* return html`
|
|
* <div class=${this.theme.isDark ? 'dark' : 'light'}>
|
|
* Current theme: ${this.theme.theme}
|
|
* </div>
|
|
* `;
|
|
* }
|
|
* }
|
|
* ```
|
|
*/
|
|
export class ThemeController implements ReactiveController {
|
|
private host: ReactiveControllerHost;
|
|
private unsubscribe?: () => void;
|
|
|
|
/**
|
|
* Whether dark mode is currently active
|
|
*/
|
|
isDark = false;
|
|
|
|
private _theme: Theme = 'system';
|
|
|
|
constructor(host: ReactiveControllerHost) {
|
|
this.host = host;
|
|
this.host.addController(this);
|
|
}
|
|
|
|
hostConnected() {
|
|
this.unsubscribe = themeService.subscribe((theme, isDark) => {
|
|
this._theme = theme;
|
|
this.isDark = isDark;
|
|
this.host.requestUpdate();
|
|
});
|
|
}
|
|
|
|
hostDisconnected() {
|
|
this.unsubscribe?.();
|
|
}
|
|
|
|
/**
|
|
* Get the current theme setting (light/dark/system)
|
|
*/
|
|
get theme(): Theme {
|
|
return this._theme;
|
|
}
|
|
|
|
/**
|
|
* Get the resolved theme (light or dark, never system)
|
|
*/
|
|
get resolvedTheme(): 'light' | 'dark' {
|
|
return this.isDark ? 'dark' : 'light';
|
|
}
|
|
|
|
/**
|
|
* Get the current theme from the service
|
|
*/
|
|
getTheme(): Theme {
|
|
return themeService.getTheme();
|
|
}
|
|
|
|
/**
|
|
* Set the theme
|
|
*/
|
|
setTheme(theme: Theme) {
|
|
themeService.setTheme(theme);
|
|
}
|
|
|
|
/**
|
|
* Toggle through themes
|
|
*/
|
|
toggleTheme() {
|
|
themeService.toggleTheme();
|
|
}
|
|
}
|