import React, { useCallback, useEffect, useState } from 'react'; import { Sun, Moon, Laptop } from 'lucide-react'; // Constants for better maintainability const THEME_OPTIONS = ['light', 'dark', 'system'] as const; type ThemeOption = (typeof THEME_OPTIONS)[number]; const THEME_STORAGE_KEY = 'bogam-color-theme'; const DEFAULT_THEME: ThemeOption = 'light'; // UI component constants const TOGGLE_GROUP_CLASS = 'toggle-group inline-flex h-10 items-center rounded-md border bg-background p-1 text-muted-foreground w-full'; const TOGGLE_BUTTON_CLASS = 'flex-1 inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ' + 'ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ' + 'focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50'; export function DarkModeToggle() { const [theme, setTheme] = useState(() => { if (typeof window === 'undefined') return DEFAULT_THEME; const storedPreferredTheme = localStorage.getItem(THEME_STORAGE_KEY); if (storedPreferredTheme && THEME_OPTIONS.includes(storedPreferredTheme as ThemeOption)) { return storedPreferredTheme as ThemeOption; } return DEFAULT_THEME; }); // Memoize the theme application function for performance const updateTheme = useCallback(() => { const root = document.documentElement; const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); // Remove existing theme classes root.classList.remove('light', 'dark'); // Apply appropriate theme class if (theme === 'system') { const systemTheme = mediaQuery.matches ? 'dark' : 'light'; root.classList.add(systemTheme); } else { root.classList.add(theme); } }, [theme]); // Apply theme changes and handle system preference useEffect(() => { const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); // Apply theme immediately updateTheme(); // Save to localStorage localStorage.setItem(THEME_STORAGE_KEY, theme); // Listen for system preference changes const handleSystemThemeChange = () => { if (theme === 'system') { updateTheme(); } }; // Proper event listener management with cleanup mediaQuery.addEventListener('change', handleSystemThemeChange); return () => mediaQuery.removeEventListener('change', handleSystemThemeChange); }, [theme, updateTheme]); // Handle theme change with type safety const handleThemeChange = (newTheme: ThemeOption) => { setTheme(newTheme); }; return (
); }