"use client"; import { useEffect, useRef, useState, type KeyboardEvent as ReactKeyboardEvent } from "react"; import { DICTATION_LANGUAGES, type DictationLanguage } from "@/src/core"; import { MenuShell } from "@/components/menu-shell"; import { Hint } from "@/components/ui/hint"; import { SettingsMenuTrigger, SettingsRow } from "@/components/settings/controls"; import { SearchMenuList } from "@/components/settings/search-menu-list"; import { useDictationActive } from "@/components/dictation-state"; import { useDictationLanguage } from "@/components/dictation-preference"; type LanguagePreference = ReturnType; export function DictationLanguageSetting() { const preference = useDictationLanguage(); const active = useDictationActive(); return ; } function DictationLanguagePicker({ preference, disabled }: { preference: LanguagePreference; disabled: boolean; }) { const { language, saving, error, load, save } = preference; const [open, setOpen] = useState(false); const triggerRef = useRef(null); const label = DICTATION_LANGUAGES.find((item) => item.code === language)?.label ?? "—"; useEffect(() => { if (disabled) setOpen(false); }, [disabled]); useEffect(() => { if (!open) return; const onPointerDown = (event: PointerEvent) => { const target = event.target as Element; if (target instanceof Element && target.closest('[data-testid="dictation-language-menu"]')) return; if (!triggerRef.current?.contains(target)) setOpen(false); }; document.addEventListener("pointerdown", onPointerDown); return () => document.removeEventListener("pointerdown", onPointerDown); }, [open]); const closeOnEscape = (event: ReactKeyboardEvent) => { if (event.key !== "Escape") return; event.preventDefault(); event.stopPropagation(); setOpen(false); triggerRef.current?.focus(); }; const pick = async (code: DictationLanguage) => { if (disabled || saving || language === undefined) return; if (await save(code)) { setOpen(false); triggerRef.current?.focus(); } }; return <> { if (open) closeOnEscape(event); }} onClick={() => { setOpen((value) => !value); if (language === undefined) void load().catch(() => {}); }} className="min-w-20 max-w-[65%]" /> {open && !disabled &&
{ closeOnEscape(event); if (event.key === "Enter") { // Empty search results must not submit the composer, but a // focused option button still needs Enter's native click. if (event.target instanceof HTMLInputElement) event.preventDefault(); event.stopPropagation(); } }}> {error &&
{error}
} item.code} searchTerms={(item) => [item.code, item.label]} isSelected={(item) => item.code === language} onPick={(item) => { void pick(item.code); }} disabled={saving || language === undefined} searchTestid="dictation-language-search" listTestid="dictation-language-list" optionTestid={(item) => `dictation-language-${item.code}`} ariaLabel="Search dictation languages" placeholder="Search languages…" empty="No languages match." renderItem={(item) => {item.label}} />
} ; }