blob: 7e428fad5d20c73129a95973c9e904b0636f16f0 [file] [log] [blame]
import { html } from "lit";
import { customElement, state } from "lit/decorators.js";
import { SketchTailwindElement } from "./sketch-tailwind-element.js";
import { ThemeService, ThemeMode } from "./theme-service.js";
@customElement("sketch-theme-toggle")
export class SketchThemeToggle extends SketchTailwindElement {
@state() private currentTheme: ThemeMode = "system";
@state() private effectiveTheme: "light" | "dark" = "light";
private themeService = ThemeService.getInstance();
connectedCallback() {
super.connectedCallback();
this.updateThemeState();
// Listen for theme changes from other sources
document.addEventListener("theme-changed", this.handleThemeChange);
}
disconnectedCallback() {
super.disconnectedCallback();
document.removeEventListener("theme-changed", this.handleThemeChange);
}
private handleThemeChange = (e: CustomEvent) => {
this.currentTheme = e.detail.theme;
this.effectiveTheme = e.detail.effectiveTheme;
};
private updateThemeState() {
this.currentTheme = this.themeService.getTheme();
this.effectiveTheme = this.themeService.getEffectiveTheme();
}
private toggleTheme() {
this.themeService.toggleTheme();
}
private getThemeIcon(): string {
switch (this.currentTheme) {
case "light":
return "\u2600\ufe0f"; // Sun
case "dark":
return "\ud83c\udf19"; // Moon
case "system":
return "\ud83d\udcbb"; // Computer/Laptop
default:
return "\ud83d\udcbb";
}
}
private getThemeLabel(): string {
switch (this.currentTheme) {
case "light":
return "Light mode";
case "dark":
return "Dark mode";
case "system":
return `System theme (${this.effectiveTheme})`;
default:
return "System theme";
}
}
private getNextThemeLabel(): string {
switch (this.currentTheme) {
case "light":
return "Switch to dark mode";
case "dark":
return "Switch to system theme";
case "system":
return "Switch to light mode";
default:
return "Switch theme";
}
}
render() {
return html`
<button
@click=${this.toggleTheme}
class="p-2 rounded-md border border-gray-300 dark:border-gray-600
bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-200
hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors
focus:outline-none focus:ring-2 focus:ring-blue-500"
title="${this.getThemeLabel()} - ${this.getNextThemeLabel()}"
aria-label="${this.getNextThemeLabel()}"
>
${this.getThemeIcon()}
</button>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"sketch-theme-toggle": SketchThemeToggle;
}
}