92 lines
No EOL
2.5 KiB
Text
92 lines
No EOL
2.5 KiB
Text
---
|
|
import { Button } from "@/components/ui/button";
|
|
import { Icon } from "astro-icon/components";
|
|
---
|
|
|
|
<Button
|
|
id="theme-toggle"
|
|
variant="ghost"
|
|
size="icon"
|
|
title="Toggle theme"
|
|
className="-me-2 size-8"
|
|
>
|
|
<Icon
|
|
name="lucide:sun"
|
|
class="size-4 scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90"
|
|
/>
|
|
<Icon
|
|
name="lucide:moon"
|
|
class="absolute size-4 scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0"
|
|
/>
|
|
<span class="sr-only">Toggle theme</span>
|
|
</Button>
|
|
|
|
<script is:inline data-astro-rerun>
|
|
const theme = (() => {
|
|
const localStorageTheme = localStorage?.getItem('theme') ?? ''
|
|
if (['dark', 'light'].includes(localStorageTheme)) {
|
|
return localStorageTheme
|
|
}
|
|
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
return 'dark'
|
|
}
|
|
return 'light'
|
|
})()
|
|
|
|
document.documentElement.setAttribute('data-theme', theme)
|
|
document.documentElement.classList.add(
|
|
theme === 'dark' ? 'scheme-dark' : 'scheme-light',
|
|
)
|
|
window.localStorage.setItem('theme', theme)
|
|
</script>
|
|
|
|
<script>
|
|
function handleToggleClick() {
|
|
const element = document.documentElement
|
|
const currentTheme = element.getAttribute('data-theme')
|
|
const newTheme = currentTheme === 'dark' ? 'light' : 'dark'
|
|
|
|
element.classList.add('[&_*]:transition-none')
|
|
element.setAttribute('data-theme', newTheme)
|
|
element.classList.remove('scheme-dark', 'scheme-light')
|
|
element.classList.add(newTheme === 'dark' ? 'scheme-dark' : 'scheme-light')
|
|
|
|
window.getComputedStyle(element).getPropertyValue('opacity')
|
|
|
|
requestAnimationFrame(() => {
|
|
element.classList.remove('[&_*]:transition-none')
|
|
})
|
|
|
|
localStorage.setItem('theme', newTheme)
|
|
}
|
|
|
|
function initThemeToggle() {
|
|
const themeToggle = document.getElementById('theme-toggle')
|
|
if (themeToggle) {
|
|
themeToggle.addEventListener('click', handleToggleClick)
|
|
}
|
|
}
|
|
|
|
initThemeToggle()
|
|
|
|
document.addEventListener('astro:after-swap', () => {
|
|
const storedTheme = localStorage.getItem('theme') || 'light'
|
|
const element = document.documentElement
|
|
|
|
element.classList.add('[&_*]:transition-none')
|
|
|
|
window.getComputedStyle(element).getPropertyValue('opacity')
|
|
|
|
element.setAttribute('data-theme', storedTheme)
|
|
element.classList.remove('scheme-dark', 'scheme-light')
|
|
element.classList.add(
|
|
storedTheme === 'dark' ? 'scheme-dark' : 'scheme-light',
|
|
)
|
|
|
|
requestAnimationFrame(() => {
|
|
element.classList.remove('[&_*]:transition-none')
|
|
})
|
|
|
|
initThemeToggle()
|
|
})
|
|
</script> |