Skip to content

Instantly share code, notes, and snippets.

@ansidev
Created November 20, 2022 23:08
Show Gist options
  • Save ansidev/c26a50882c84a58e0a718aa3dcac274c to your computer and use it in GitHub Desktop.
Save ansidev/c26a50882c84a58e0a718aa3dcac274c to your computer and use it in GitHub Desktop.
Astro ThemeSwitcher Component
---
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