"use client"; import { useState, useCallback } from "react"; import { Check } from "lucide-react"; import { Popover, PopoverTrigger, PopoverContent, } from "@/components/ui/popover"; // --------------------------------------------------------------------------- // PropertyPicker — generic Popover shell with optional search // --------------------------------------------------------------------------- export function PropertyPicker({ open, onOpenChange, trigger, triggerRender, width = "w-48", align = "end", searchable = false, searchPlaceholder = "Filter...", onSearchChange, children, }: { open: boolean; onOpenChange: (v: boolean) => void; trigger: React.ReactNode; triggerRender?: React.ReactElement; width?: string; align?: "start" | "center" | "end"; searchable?: boolean; searchPlaceholder?: string; onSearchChange?: (query: string) => void; children: React.ReactNode; }) { const [query, setQuery] = useState(""); const handleOpenChange = useCallback( (v: boolean) => { onOpenChange(v); if (!v) { setQuery(""); onSearchChange?.(""); } }, [onOpenChange, onSearchChange], ); return ( {trigger} {searchable && (
{ setQuery(e.target.value); onSearchChange?.(e.target.value); }} placeholder={searchPlaceholder} aria-label="Filter options" className="w-full bg-transparent text-sm placeholder:text-muted-foreground outline-none" />
)}
{children}
); } // --------------------------------------------------------------------------- // PickerItem — single selectable row // --------------------------------------------------------------------------- export function PickerItem({ selected, disabled, onClick, hoverClassName, children, }: { selected: boolean; disabled?: boolean; onClick: () => void; hoverClassName?: string; children: React.ReactNode; }) { return ( ); } // --------------------------------------------------------------------------- // PickerSection — group header // --------------------------------------------------------------------------- export function PickerSection({ label, children, }: { label: string; children: React.ReactNode; }) { return (
{label}
{children}
); } // --------------------------------------------------------------------------- // PickerEmpty — no results state // --------------------------------------------------------------------------- export function PickerEmpty() { return (
No results
); }