Spaces:
Running
Running
--- | |
import { Sun, Moon } from 'lucide-astro'; | |
--- | |
<button | |
class="relative p-2 text-white hover:text-blueprint-accent transition-colors duration-300 rounded-lg hover:bg-white/10 overflow-hidden" | |
data-theme-toggle | |
aria-label="Toggle dark/light theme" | |
> | |
<div class="relative w-5 h-5"> | |
<Sun class="w-5 h-5 absolute inset-0 transition-all duration-500 transform" data-sun-icon /> | |
<Moon class="w-5 h-5 absolute inset-0 transition-all duration-500 transform" data-moon-icon /> | |
</div> | |
</button> | |
<script> | |
function initTheme() { | |
const themeToggle = document.querySelector('[data-theme-toggle]'); | |
const htmlElement = document.documentElement; | |
const sunIcon = document.querySelector('[data-sun-icon]') as HTMLElement; | |
const moonIcon = document.querySelector('[data-moon-icon]') as HTMLElement; | |
// Get saved theme or default to dark | |
const savedTheme = localStorage.getItem('theme') || 'dark'; | |
// Function to update icons with animation | |
function updateIcons(isDark: boolean) { | |
if (isDark) { | |
// Dark mode - show moon, hide sun | |
sunIcon.style.transform = 'rotate(180deg) scale(0)'; | |
sunIcon.style.opacity = '0'; | |
moonIcon.style.transform = 'rotate(0deg) scale(1)'; | |
moonIcon.style.opacity = '1'; | |
} else { | |
// Light mode - show sun, hide moon | |
moonIcon.style.transform = 'rotate(-180deg) scale(0)'; | |
moonIcon.style.opacity = '0'; | |
sunIcon.style.transform = 'rotate(0deg) scale(1)'; | |
sunIcon.style.opacity = '1'; | |
} | |
} | |
// Apply theme | |
if (savedTheme === 'dark') { | |
htmlElement.classList.add('dark'); | |
updateIcons(true); | |
} else { | |
htmlElement.classList.remove('dark'); | |
updateIcons(false); | |
} | |
// Theme toggle functionality | |
themeToggle?.addEventListener('click', () => { | |
const isDark = htmlElement.classList.contains('dark'); | |
if (isDark) { | |
htmlElement.classList.remove('dark'); | |
localStorage.setItem('theme', 'light'); | |
updateIcons(false); | |
} else { | |
htmlElement.classList.add('dark'); | |
localStorage.setItem('theme', 'dark'); | |
updateIcons(true); | |
} | |
}); | |
} | |
// Initialize on DOM load | |
if (document.readyState === 'loading') { | |
document.addEventListener('DOMContentLoaded', initTheme); | |
} else { | |
initTheme(); | |
} | |
</script> |