const DARK = "dark" const LIGHT = "light" const SYSTEM = "system" const DEFAULT_THEME = SYSTEM const parseTheme = (themeName) => { const s = (typeof (themeName) === 'string') ? themeName.toLowerCase().trim() : themeName if (s == "light" || s == LIGHT) return LIGHT else if (s == "dark" || s == DARK) return DARK else return SYSTEM } const oppositeOf = (theme) => { if (theme == LIGHT) return DARK else if (theme == DARK) return LIGHT else return null } export class Theme { #theme = DEFAULT_THEME #defaultPreference = LIGHT constructor(initialThemeName = undefined) { if (!initialThemeName) initialThemeName = localStorage.getItem("theme") this.#defaultPreference = window.matchMedia("(prefers-color-scheme: light)").matches ? LIGHT : DARK this.theme = parseTheme(initialThemeName) } cycle() { this.theme = this.getNext() } getNext() { if (this.theme == SYSTEM) { return oppositeOf(this.#defaultPreference) } else { if (this.theme == this.#defaultPreference) { return SYSTEM } else { return oppositeOf(this.#theme) } } } toggle() { // unused on this page } set theme(themeName) { localStorage.setItem("theme", themeName) this.#theme = parseTheme(themeName) document.body.classList.remove(`light-theme`) document.body.classList.remove(`dark-theme`) document.body.classList.remove(`system-theme`) console.log(this, this.getNext()) document.body.classList.add(`${this.#theme}-theme`) } get theme() { return this.#theme } }