import { useState, useEffect, useMemo, useRef } from 'react'; import { ChevronDown } from 'lucide-react'; export function SearchSelect({ value, onChange, options, placeholder, className }: { value: string; onChange: (v: string) => void; options: string[]; placeholder: string; className?: string; }) { const [open, setOpen] = useState(false); const [query, setQuery] = useState(''); const ref = useRef(null); useEffect(() => { const handler = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false); }; document.addEventListener('mousedown', handler); return () => document.removeEventListener('mousedown', handler); }, []); const filtered = useMemo(() => { if (!query) return options; const q = query.toLowerCase(); return options.filter((o) => o.toLowerCase().includes(q)); }, [options, query]); const displayValue = value || ''; return (
setOpen(!open)} > { setQuery(e.target.value); if (!open) setOpen(true); }} onFocus={() => { setOpen(true); setQuery(''); }} />
{open && (
{ onChange(''); setQuery(''); setOpen(false); }} > {placeholder}
{filtered.map((o) => (
{ onChange(o); setQuery(''); setOpen(false); }} > {o}
))} {filtered.length === 0 && (
无匹配项
)}
)}
); }