Spaces:
Sleeping
Sleeping
File size: 1,595 Bytes
e50b7ef |
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 43 44 45 46 47 48 49 50 |
'use client';
import { useState, useEffect } from 'react';
import { Moon, Sun } from 'lucide-react';
import { Button } from '@/components/ui/button';
export function ThemeToggle() {
const [theme, setTheme] = useState<string | undefined>(undefined);
useEffect(() => {
// Set initial theme based on localStorage or system preference
const storedTheme = localStorage.getItem('theme');
const systemPrefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
if (storedTheme) {
setTheme(storedTheme);
} else {
setTheme(systemPrefersDark ? 'dark' : 'light');
}
}, []);
useEffect(() => {
// Apply theme to document and save to localStorage
if (theme === 'dark') {
document.documentElement.classList.add('dark');
localStorage.setItem('theme', 'dark');
} else if (theme === 'light') {
document.documentElement.classList.remove('dark');
localStorage.setItem('theme', 'light');
}
}, [theme]);
const toggleTheme = () => {
setTheme(prevTheme => (prevTheme === 'light' ? 'dark' : 'light'));
};
if (theme === undefined) {
// Return a placeholder to avoid rendering mismatch during initial load
// and to reserve space, matching the button's size.
return <Button variant="ghost" size="icon" disabled className="h-9 w-9" />;
}
return (
<Button variant="ghost" size="icon" onClick={toggleTheme} aria-label="Toggle theme" className="h-9 w-9">
{theme === 'light' ? <Moon className="h-5 w-5" /> : <Sun className="h-5 w-5" />}
</Button>
);
}
|