From 4fee4cbdd5591eef38105a41d007b4e44bda89ae Mon Sep 17 00:00:00 2001 From: Serik Date: Thu, 4 Jul 2024 00:12:30 +0500 Subject: [PATCH] theme switcher --- states/themeSwitcher.js | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 states/themeSwitcher.js diff --git a/states/themeSwitcher.js b/states/themeSwitcher.js new file mode 100644 index 0000000..ed72ada --- /dev/null +++ b/states/themeSwitcher.js @@ -0,0 +1,53 @@ +export const THEME_NAME = { + dark: 'dark', + light: 'light', +} + +export const isDarkMode = () => + window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches + +const getSystemTheme = () => (isDarkMode() ? THEME_NAME.dark : THEME_NAME.light) + +class ThemeSwitcher extends EventTarget { + constructor() { + super() + this.set(localStorage.getItem('theme')) + } + set(_theme) { + this.theme = _theme + if (!this.theme) { + this.theme = "auto" + } + localStorage.setItem('theme', this.theme) + if (this.theme === "auto") { + const systemTheme = getSystemTheme() + document.documentElement.setAttribute('data-theme', systemTheme) + } else { + document.documentElement.setAttribute('data-theme', this.theme) + } + + // Displatch the current state + this.dispatchEvent( + new CustomEvent('updated', { + detail: { theme: this.theme }, + }) + ) + } + toggle() { + if (this.theme === THEME_NAME.dark) { + this.set(THEME_NAME.light) + } else { + this.set(THEME_NAME.dark) + } + } +} +const themeSwithcherState = new ThemeSwitcher() + +if (window.matchMedia) { + var colorSchemeQuery = window.matchMedia('(prefers-color-scheme: dark)') + colorSchemeQuery.addEventListener('change', () => { + themeSwithcherState.set(getSystemTheme()) + }) +} + +export { themeSwithcherState }