diff options
| author | aman333nolawz <amananudhiu@gmail.com> | 2026-03-02 21:49:13 +0530 |
|---|---|---|
| committer | aman333nolawz <amananudhiu@gmail.com> | 2026-03-02 21:49:13 +0530 |
| commit | d41eff9eccf66644c4c60f53cb516bf079937a28 (patch) | |
| tree | 248a0863a3181369f943d678ec4273911d35efac /src/components/ThemeToggle.astro | |
Using astro-erudite for static site generation
Diffstat (limited to 'src/components/ThemeToggle.astro')
| -rw-r--r-- | src/components/ThemeToggle.astro | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/components/ThemeToggle.astro b/src/components/ThemeToggle.astro new file mode 100644 index 0000000..f7b0926 --- /dev/null +++ b/src/components/ThemeToggle.astro @@ -0,0 +1,72 @@ +--- +import { Button } from '@/components/ui/button' +import { Icon } from 'astro-icon/components' +--- + +<Button + id="theme-toggle" + variant="ghost" + size="icon" + title="Toggle theme" + className="-my-2 -me-2 size-8" +> + <Icon name="lucide:sun" class="size-4 dark:hidden" /> + <Icon name="lucide:moon" class="absolute hidden size-4 dark:block" /> + <span class="sr-only">Toggle theme</span> +</Button> + +<script is:inline data-astro-rerun> + ;(() => { + const theme = (() => { + const stored = localStorage?.getItem('theme') ?? '' + if (['dark', 'light'].includes(stored)) return stored + return window.matchMedia('(prefers-color-scheme: dark)').matches + ? 'dark' + : 'light' + })() + + document.documentElement.setAttribute('data-theme', theme) + 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) + window.getComputedStyle(element).getPropertyValue('opacity') + + requestAnimationFrame(() => { + element.classList.remove('[&_*]:transition-none') + }) + + localStorage.setItem('theme', newTheme) + } + + function initThemeToggle() { + document + .getElementById('theme-toggle') + ?.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) + + requestAnimationFrame(() => { + element.classList.remove('[&_*]:transition-none') + }) + + initThemeToggle() + }) +</script> |
