| '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; |