|
|
'use client'; |
|
|
|
|
|
import React, { useEffect, useState } from 'react'; |
|
|
import { useTheme } from '../contexts/ThemeContext'; |
|
|
import { cn } from '../lib/utils'; |
|
|
|
|
|
interface ThemeToggleProps { |
|
|
className?: string; |
|
|
} |
|
|
|
|
|
const ThemeToggle: React.FC<ThemeToggleProps> = ({ className }) => { |
|
|
const [mounted, setMounted] = useState(false); |
|
|
const { theme, toggleTheme } = useTheme(); |
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
setMounted(true); |
|
|
}, []); |
|
|
|
|
|
if (!mounted) { |
|
|
|
|
|
return ( |
|
|
<div className={cn( |
|
|
"relative inline-flex h-10 w-10 items-center justify-center rounded-lg border border-border bg-background", |
|
|
className |
|
|
)}> |
|
|
<div className="h-5 w-5 animate-pulse bg-muted rounded"></div> |
|
|
</div> |
|
|
); |
|
|
} |
|
|
|
|
|
return ( |
|
|
<button |
|
|
onClick={toggleTheme} |
|
|
className={cn( |
|
|
"relative inline-flex h-10 w-10 items-center justify-center rounded-lg border border-border bg-background hover:bg-accent hover:text-accent-foreground transition-colors", |
|
|
className |
|
|
)} |
|
|
aria-label={`Switch to ${theme === 'light' ? 'dark' : 'light'} mode`} |
|
|
> |
|
|
<div className="relative h-5 w-5"> |
|
|
{/* Sun Icon */} |
|
|
<svg |
|
|
className={cn( |
|
|
"absolute inset-0 h-5 w-5 transition-all", |
|
|
theme === 'dark' ? "rotate-90 scale-0" : "rotate-0 scale-100" |
|
|
)} |
|
|
fill="none" |
|
|
viewBox="0 0 24 24" |
|
|
stroke="currentColor" |
|
|
strokeWidth={2} |
|
|
> |
|
|
<path |
|
|
strokeLinecap="round" |
|
|
strokeLinejoin="round" |
|
|
d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" |
|
|
/> |
|
|
</svg> |
|
|
|
|
|
{/* Moon Icon */} |
|
|
<svg |
|
|
className={cn( |
|
|
"absolute inset-0 h-5 w-5 transition-all", |
|
|
theme === 'dark' ? "rotate-0 scale-100" : "-rotate-90 scale-0" |
|
|
)} |
|
|
fill="none" |
|
|
viewBox="0 0 24 24" |
|
|
stroke="currentColor" |
|
|
strokeWidth={2} |
|
|
> |
|
|
<path |
|
|
strokeLinecap="round" |
|
|
strokeLinejoin="round" |
|
|
d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" |
|
|
/> |
|
|
</svg> |
|
|
</div> |
|
|
</button> |
|
|
); |
|
|
}; |
|
|
|
|
|
export default ThemeToggle; |