ThemeToggle.tsx 1.5 KB

1234567891011121314151617181920212223242526272829303132
  1. 'use client';
  2. import { useTheme } from 'next-themes';
  3. import { useEffect, useState } from 'react';
  4. export function ThemeToggle() {
  5. const { theme, setTheme } = useTheme();
  6. const [mounted, setMounted] = useState(false);
  7. useEffect(() => setMounted(true), []);
  8. if (!mounted) return <div className="w-8 h-8" />;
  9. const isDark = theme === 'dark';
  10. return (
  11. <button
  12. onClick={() => setTheme(isDark ? 'light' : 'dark')}
  13. className="w-8 h-8 rounded-lg flex items-center justify-center transition-colors hover:bg-gray-200 dark:hover:bg-slate-700"
  14. title={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
  15. >
  16. {isDark ? (
  17. <svg className="w-4 h-4 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
  18. <path fillRule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clipRule="evenodd" />
  19. </svg>
  20. ) : (
  21. <svg className="w-4 h-4 text-gray-600" fill="currentColor" viewBox="0 0 20 20">
  22. <path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
  23. </svg>
  24. )}
  25. </button>
  26. );
  27. }