File size: 1,406 Bytes
44ec4f2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 'use client'
import * as React from 'react'
import { Moon, Sun } from 'lucide-react'
import { Button } from '@/components/ui/button'
function getPreferredTheme(): 'light' | 'dark' {
if (typeof window === 'undefined') return 'light'
const stored = window.localStorage.getItem('theme') as 'light' | 'dark' | null
if (stored === 'light' || stored === 'dark') return stored
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
return prefersDark ? 'dark' : 'light'
}
export function ThemeToggle() {
const [theme, setTheme] = React.useState<'light' | 'dark'>(() => getPreferredTheme())
React.useEffect(() => {
const root = document.documentElement
if (theme === 'dark') {
root.classList.add('dark')
} else {
root.classList.remove('dark')
}
window.localStorage.setItem('theme', theme)
}, [theme])
const toggle = () => setTheme((t) => (t === 'dark' ? 'light' : 'dark'))
return (
<Button variant="ghost" size="icon" aria-label="Toggle theme" onClick={toggle}>
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
)
}
export default ThemeToggle
|