import * as React from 'react' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import { cn } from '@/lib/utils' import { Button } from './button' import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from './command' import { Popover, PopoverContent, PopoverTrigger } from './popover' export interface ComboboxOption { value: string label: string disabled?: boolean keywords?: string[] } export interface ComboboxProps { options: ComboboxOption[] size?: 'default' | 'compact' value?: string defaultValue?: string onValueChange?: (value: string) => void placeholder?: React.ReactNode searchPlaceholder?: string emptyText?: React.ReactNode disabled?: boolean className?: string contentClassName?: string align?: 'start' | 'center' | 'end' triggerClassName?: string id?: string name?: string 'aria-label'?: string } function Combobox({ options, value, defaultValue, onValueChange, placeholder = 'Select an option…', searchPlaceholder = 'Search…', emptyText = 'No option found.', size = 'compact', disabled, className, contentClassName, triggerClassName, align = 'start', id, name, 'aria-label': ariaLabel, }: ComboboxProps) { const isControlled = value !== undefined const [internal, setInternal] = React.useState(defaultValue) const [open, setOpen] = React.useState(false) const current = isControlled ? value : internal const selected = options.find((option) => option.value === current) const handleSelect = React.useCallback( (next: string) => { const resolved = next === current ? '' : next if (!isControlled) setInternal(resolved) onValueChange?.(resolved) setOpen(false) }, [current, isControlled, onValueChange], ) return (
{emptyText} {options.map((option) => ( {option.label} ))} {name ? : null}
) } export { Combobox }