import { Input } from "antd"; import { Search } from "lucide-react"; import { useId, useState, type ReactNode } from "react"; import "./choice-browser.css"; export type BrowserChoice = { value: string; label: string; subtitle?: string; vendor?: string; searchText?: string; disabled?: boolean; details: Array<{ label: string; value: ReactNode }>; }; /** A controlled form field: searching never changes the selected value. */ export function ChoiceBrowser({ value, onChange, options, label, placeholder = "搜索名称、来源或请求路径", loading = false, error = "", disabled = false, id, ...aria }: { value?: string; onChange?: (value: string) => void; options: BrowserChoice[]; label: string; placeholder?: string; loading?: boolean; error?: string; disabled?: boolean; id?: string; "aria-describedby"?: string; "aria-invalid"?: boolean | "true" | "false"; }) { const name = useId(); const [query, setQuery] = useState(""); const selected = options.find((option) => option.value === value); const normalizedQuery = query.trim().toLowerCase(); const visible = options.filter((option) => [option.label, option.subtitle, option.vendor, option.searchText].join(" ").toLowerCase().includes(normalizedQuery)); const unavailable = disabled || loading || Boolean(error); return (
} placeholder={placeholder} value={query} onChange={(event) => setQuery(event.target.value)} /> {loading || error || !options.length ? (
{loading ? "正在读取可选项…" : error || "暂无可用选项"}
) : (
{visible.map((option) => ( ))} {!visible.length && (
没有匹配的选项
)}
当前选择 {selected ? ( <> {selected.label}
{selected.details.map((detail) => (
{detail.label}
{detail.value}
))}
) : (

{value ? `当前配置 ${value} 不在可用目录中,请重新选择。` : "选择左侧选项查看详情"}

)}
)}
); }