import * as React from "react"; import { Popover as PopoverPrimitive } from "radix-ui"; import { Check, ChevronsUpDown } from "lucide-react"; import { cn } from "@/lib/utils"; import type { CollectionOption } from "@/hooks/queries/useAllUserCollections"; interface CollectionSearchableSelectProps { /** The full list of available collection options. */ options: CollectionOption[]; /** Currently selected collection ID (empty string = nothing selected). */ value: string; /** Called when the user picks a collection or clears the selection. */ onChange: (value: string) => void; placeholder?: string; disabled?: boolean; /** Show a loading skeleton while options are being fetched. */ isLoading?: boolean; } export function CollectionSearchableSelect({ options, value, onChange, placeholder = "Choose collection", disabled = false, isLoading = false, }: CollectionSearchableSelectProps) { const [open, setOpen] = React.useState(false); const [search, setSearch] = React.useState(""); const filtered = React.useMemo(() => { if (!search) return options; const lower = search.toLowerCase(); return options.filter( (opt) => opt.title.toLowerCase().includes(lower) || opt.group.toLowerCase().includes(lower), ); }, [options, search]); // Group filtered options by their `group` field, preserving insertion order. const grouped = React.useMemo(() => { const map = new Map(); for (const opt of filtered) { const existing = map.get(opt.group); if (existing) { existing.push(opt); } else { map.set(opt.group, [opt]); } } return map; }, [filtered]); const selectedOption = React.useMemo(() => options.find((o) => o.id === value), [options, value]); const displayText = selectedOption ? `${selectedOption.title} (${selectedOption.group})` : placeholder; return ( e.preventDefault()} >
setSearch(e.target.value)} placeholder="Search collections..." className="border-input bg-background placeholder:text-muted-foreground flex h-8 w-full rounded-md border px-2 text-sm outline-none" autoFocus />
{isLoading ? (

Loading...

) : filtered.length === 0 ? (

No collections found

) : ( <> {/* Clear / placeholder option */} {Array.from(grouped.entries()).map(([groupName, items]) => (
{/* Group header */}
{groupName}
{items.map((opt) => ( ))}
))} )}
); }