import { useState } from "react"; import { useTranslation } from "react-i18next"; import { ChevronDown, MonitorIcon, MoonIcon, SunMediumIcon, type LucideIcon } from "lucide-react"; import { DropdownMenu, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger, } from "@/components/DropdownMenu"; import { HelpText } from "@/components/typography/HelpText"; import { Label } from "@/components/typography/Label"; import { useTheme, type ThemePreference } from "@/contexts/ThemeContext"; import { useFocusVisible } from "@/hooks/useFocusVisible"; import { cn } from "@/lib/cn"; import { errorDialog, formatErrorMessage } from "@/lib/errors"; const OPTIONS: { value: ThemePreference; icon: LucideIcon; labelKey: string }[] = [ { value: "system", icon: MonitorIcon, labelKey: "settings.general.theme.system" }, { value: "light", icon: SunMediumIcon, labelKey: "settings.general.theme.light" }, { value: "dark", icon: MoonIcon, labelKey: "settings.general.theme.dark" }, ]; export function ThemePicker() { const { t } = useTranslation(); const { theme, setTheme } = useTheme(); const [busy, setBusy] = useState(false); const isFocusVisible = useFocusVisible(); const current = OPTIONS.find((o) => o.value === theme) ?? OPTIONS[0]; const CurrentIcon = current.icon; const select = async (value: string) => { if (busy || value === theme) return; setBusy(true); try { await setTheme(value as ThemePreference); } catch (e) { await errorDialog({ Title: t("settings.error.saveTitle"), Message: formatErrorMessage(e), }); } finally { setBusy(false); } }; return (
{t("settings.general.theme.help")}
void select(v)}> {OPTIONS.map(({ value, icon: Icon, labelKey }) => ( {t(labelKey)} ))}
); }