'use client' import * as React from 'react' import { Check, ChevronDown, Search } from 'lucide-react' import { cn } from '@/lib/utils' import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover' interface ComboboxOption { value: string label: string } interface ComboboxProps { options: ComboboxOption[] value: string onChange: (value: string) => void placeholder?: string searchPlaceholder?: string emptyMessage?: string disabled?: boolean className?: string } export function Combobox({ options, value, onChange, placeholder = 'Select...', searchPlaceholder = 'Search...', emptyMessage = 'No results found.', disabled = false, className, }: ComboboxProps) { const [open, setOpen] = React.useState(false) const [search, setSearch] = React.useState('') const selectedLabel = options.find((o) => o.value === value)?.label const filtered = React.useMemo(() => { if (!search.trim()) return options const q = search.toLowerCase() return options.filter( (o) => o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q) ) }, [options, search]) const handleSelect = (optionValue: string) => { onChange(optionValue === value ? '' : optionValue) setOpen(false) setSearch('') } return ( { setOpen(v); if (!v) setSearch('') }}>
setSearch(e.target.value)} autoFocus />
{filtered.length === 0 ? (
{emptyMessage}
) : ( filtered.map((option) => { const isSelected = option.value === value return ( ) }) )}
) }