import { useState, useRef, useEffect } from "react"; import { ChevronDown } from "lucide-react"; import { LANGUAGES, type LanguageCode, LANGUAGES_WITH_AUTO, } from "../constants"; interface LanguageSelectorProps { value: LanguageCode; onChange: (language: LanguageCode) => void; includeAuto?: boolean; } export default function LanguageSelector({ value, onChange, includeAuto = false, }: LanguageSelectorProps) { const [isOpen, setIsOpen] = useState(false); const [search, setSearch] = useState(""); const containerRef = useRef(null); const searchInputRef = useRef(null); const languages = includeAuto ? LANGUAGES_WITH_AUTO : LANGUAGES; const getLanguageDisplay = (code: LanguageCode) => { return languages.find((lang) => lang.code === code)?.name || code; }; const filterLanguages = (searchTerm: string) => { const searchLower = searchTerm.toLowerCase(); return languages.filter( (lang) => lang.name.toLowerCase().includes(searchLower) || lang.code.toLowerCase().includes(searchLower) ); }; const filteredLanguages = search ? filterLanguages(search) : languages; const handleSelect = (language: LanguageCode) => { onChange(language); setIsOpen(false); setSearch(""); }; useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( containerRef.current && !containerRef.current.contains(event.target as Node) ) { setIsOpen(false); setSearch(""); } }; if (isOpen) { document.addEventListener("mousedown", handleClickOutside); setTimeout(() => searchInputRef.current?.focus(), 0); } return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, [isOpen]); return (
{isOpen && (
setSearch(e.target.value)} className="w-full px-3 py-2 text-sm border border-border rounded-md focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary" />
{filteredLanguages.map((lang) => ( ))} {filteredLanguages.length === 0 && (
No languages found
)}
)}
); }