import React, { useContext, useCallback, useEffect, useState } from 'react'; import { Sun, Moon, Monitor } from 'lucide-react'; import { ThemeContext } from '~/hooks'; declare global { interface Window { lastThemeChange?: number; } } const Theme = ({ theme, onChange }: { theme: string; onChange: (value: string) => void }) => { const themeIcons = { system: , dark: , light: , }; const nextTheme = theme === 'dark' ? 'light' : 'dark'; const label = `Switch to ${nextTheme} theme`; useEffect(() => { const handleKeyPress = (e: KeyboardEvent) => { if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === 't') { e.preventDefault(); onChange(nextTheme); } }; window.addEventListener('keydown', handleKeyPress); return () => window.removeEventListener('keydown', handleKeyPress); }, [nextTheme, onChange]); return ( ); }; const ThemeSelector = ({ returnThemeOnly }: { returnThemeOnly?: boolean }) => { const { theme, setTheme } = useContext(ThemeContext); const [announcement, setAnnouncement] = useState(''); const changeTheme = useCallback( (value: string) => { const now = Date.now(); if (typeof window.lastThemeChange === 'number' && now - window.lastThemeChange < 500) { return; } window.lastThemeChange = now; setTheme(value); setAnnouncement(value === 'dark' ? 'Dark theme enabled' : 'Light theme enabled'); }, [setTheme], ); useEffect(() => { if (theme === 'system') { const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches; setTheme(prefersDarkScheme ? 'dark' : 'light'); } }, [theme, setTheme]); useEffect(() => { if (announcement) { const timeout = setTimeout(() => setAnnouncement(''), 1000); return () => clearTimeout(timeout); } }, [announcement]); if (returnThemeOnly === true) { return ; } return (
{announcement && (
{announcement}
)}
); }; export default ThemeSelector;