import { useMemo, useState } from "react"; import { Button, cn, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Popover, PopoverContent, PopoverTrigger, } from "@arronqzy/ui"; import { useI18n } from "@arronqzy/i18n/react"; export type ViewElementMultiSelectOption = { id: string; label: string; }; export type ViewElementMultiSelectProps = { options: ViewElementMultiSelectOption[]; value: string[]; onChange: (next: string[]) => void; placeholder?: string; disabled?: boolean; }; function CheckIcon({ className }: { className?: string }) { return ( ); } function ChevronDownIcon({ className }: { className?: string }) { return ( ); } export function ViewElementMultiSelect({ options, value, onChange, placeholder, disabled = false, }: ViewElementMultiSelectProps) { const { t } = useI18n(); const [open, setOpen] = useState(false); const resolvedPlaceholder = placeholder ?? t("blueprint.config.selectViewNode"); const labelById = useMemo( () => new Map(options.map((opt) => [opt.id, opt.label])), [options] ); const selectedSet = useMemo(() => new Set(value), [value]); const emptyOptions = options.length === 0; let triggerText = resolvedPlaceholder; if (value.length > 0) { const labels = value.map((id) => labelById.get(id) ?? id); if (labels.length === 1) { triggerText = labels[0]!; } else { const joined = labels.join("、"); triggerText = joined.length <= 26 ? joined : t("blueprint.config.selectedCount", { count: value.length }); } } const toggle = (id: string) => { onChange( selectedSet.has(id) ? value.filter((item) => item !== id) : [...value, id] ); }; return ( {t("blueprint.config.noMatchingNodes")} {options.map((opt) => { const selected = selectedSet.has(opt.id); return ( e.preventDefault()} onSelect={() => toggle(opt.id)} > {opt.label} ); })} ); }