"use client"; import { useState } from "react"; import { Check, Plus, X } from "lucide-react"; import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/primitives"; import { cn } from "@/lib/utils"; import type { Property, SelectOption } from "@/lib/databases/types"; import { OPTION_CLASS } from "../colors"; export function OptionChip({ opt, onRemove, className }: { opt: SelectOption | { name: string; color?: string }; onRemove?: () => void; className?: string }) { return {opt.name}{onRemove && }; } /** Popover for select / multi_select / status; `children` is the trigger. */ export function SelectPopover({ p, value, multi, onChange, addOption, open, onOpenChange, children }: { p: Property; value: unknown; multi: boolean; onChange: (v: unknown) => void; addOption: (name: string) => Promise; open: boolean; onOpenChange: (o: boolean) => void; children: React.ReactNode }) { const [q, setQ] = useState(""); const opts = p.config.options ?? []; const sel: string[] = multi ? (Array.isArray(value) ? (value as string[]) : []) : value ? [String(value)] : []; const filtered = opts.filter((o) => o.name.toLowerCase().includes(q.trim().toLowerCase())); const canCreate = q.trim() && !opts.some((o) => o.name.toLowerCase() === q.trim().toLowerCase()); const pick = (id: string) => { if (multi) onChange(sel.includes(id) ? sel.filter((x) => x !== id) : [...sel, id]); else { onChange(sel[0] === id ? null : id); onOpenChange(false); } }; const create = async () => { const o = await addOption(q.trim()); setQ(""); pick(o.id); }; return ( { onOpenChange(o); if (!o) setQ(""); }}>{children} { e.preventDefault(); (e.currentTarget as HTMLElement).querySelector("input")?.focus(); }}> {multi && sel.length > 0 &&
{sel.map((id) => { const o = opts.find((x) => x.id === id); return o ? pick(id)} /> : null; })}
} setQ(e.target.value)} placeholder={multi ? "Search or create…" : "Search or create…"} className="h-8 w-full rounded-md bg-bg-sunk px-2 text-[13px] outline-none" onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); if (filtered.length === 1) pick(filtered[0].id); else if (canCreate) create(); } if (e.key === "Escape") onOpenChange(false); }} />
{filtered.map((o) => )} {canCreate && } {!filtered.length && !canCreate &&
No options yet — type to create one.
}
); }