'use client'; import * as React from 'react'; import type { ButtonProps } from '@/components/ui/button'; import { Button } from '@/components/ui/button'; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, } from '@/components/ui/command'; import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover'; import { cn } from '@/utils/cn'; import type { LucideIcon } from 'lucide-react'; import { Check, ChevronsUpDown } from 'lucide-react'; export interface ComboboxProps { placeholder: string; items: { value: T; label: string; disabled?: boolean; }[]; value: T | null | undefined; onChange: (value: T) => void; children?: React.ReactNode; onCreate?: (value: T) => void; className?: string; searchable?: boolean; icon?: LucideIcon; size?: ButtonProps['size']; label?: string; } export type ExtendedComboboxProps = Omit< ComboboxProps, 'items' | 'placeholder' > & { placeholder?: string; }; export function Combobox({ placeholder, items, value, onChange, children, onCreate, className, searchable, icon: Icon, size, }: ComboboxProps) { const [open, setOpen] = React.useState(false); const [search, setSearch] = React.useState(''); function find(value: string) { return items.find( (item) => item.value.toLowerCase() === value.toLowerCase() ); } return ( {children ?? ( )} {searchable === true && ( )} {typeof onCreate === 'function' && search ? ( ) : ( Nothing selected )}
{items.map((item) => ( { const value = find(currentValue)?.value ?? currentValue; onChange(value as T); setOpen(false); }} {...(item.disabled && { disabled: true })} > {item.label} ))}
); }