Created
November 20, 2022 23:08
-
-
Save ansidev/c26a50882c84a58e0a718aa3dcac274c to your computer and use it in GitHub Desktop.
Astro ThemeSwitcher Component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
import bi from "@iconify-json/bi/icons.json" | |
import Icon from "@/components/Icon.astro" | |
type ThemeType = "dark" | "light" | |
const THEME_DARK: ThemeType = "dark" | |
const THEME_LIGHT: ThemeType = "light" | |
const STORAGE_KEY_THEME: string = "theme" | |
let defaultTheme: ThemeType = THEME_DARK | |
const icons = { | |
dark: bi.icons["moon-fill"].body, | |
light: bi.icons["sun-fill"].body | |
} | |
--- | |
<button id="theme-switcher-btn" type="button" class="ml-2"> | |
<Icon id="theme-switcher-icon" clazz="text-black hover:text-white" name="bi:moon-fill" size={20} /> | |
</button> | |
<script define:vars={{ icons, THEME_DARK, THEME_LIGHT, STORAGE_KEY_THEME, defaultTheme }} > | |
const theme = (() => { | |
if (typeof localStorage !== "undefined" && localStorage.getItem(STORAGE_KEY_THEME)) { | |
return localStorage.getItem(STORAGE_KEY_THEME) | |
} | |
if (window.matchMedia("(prefers-color-scheme: dark)").matches) { | |
return THEME_DARK | |
} | |
return THEME_LIGHT | |
})() | |
if (theme === THEME_DARK) { | |
document.documentElement.classList.add(THEME_DARK) | |
} else { | |
document.documentElement.classList.remove(THEME_DARK) | |
} | |
window.localStorage.setItem(STORAGE_KEY_THEME, theme || defaultTheme) | |
const switchTheme = () => { | |
const element = document.documentElement | |
element.classList.toggle(THEME_DARK) | |
const isDark = element.classList.contains(THEME_DARK) | |
localStorage.setItem(STORAGE_KEY_THEME, isDark ? THEME_DARK : THEME_LIGHT) | |
const themeSwitcherIcon = document.getElementById("theme-switcher-icon") | |
if (isDark) { | |
themeSwitcherIcon.classList.remove("bi:sun-fill") | |
themeSwitcherIcon.classList.add("bi:moon-fill") | |
themeSwitcherIcon.innerHTML = icons.dark | |
} else { | |
themeSwitcherIcon.classList.add("bi:sun-fill") | |
themeSwitcherIcon.classList.remove("bi:moon-fill") | |
themeSwitcherIcon.innerHTML = icons.light | |
} | |
} | |
document.getElementById("theme-switcher-btn")?.addEventListener("click", switchTheme) | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment