'use client'; import { Button } from '@workspace/ui/components/button'; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from '@workspace/ui/components/command'; import { Popover, PopoverContent, PopoverTrigger } from '@workspace/ui/components/popover'; import { cn } from '@workspace/ui/lib/utils'; import { BoxIcon, CheckIcon, ChevronsUpDownIcon } from 'lucide-react'; import * as React from 'react'; export type Option = { value: T; label: string; children?: React.ReactNode; }; // Conditional types to determine the value type for onChange type OnChangeType = M extends true ? T[] : T; type ComboboxProps = { multiple?: M; options?: Option[]; placeholder?: string; value?: OnChangeType; onChange: (value: OnChangeType) => void; className?: string; }; export function Combobox({ multiple = false as M, options = [], placeholder = 'Select...', value, onChange, className, }: ComboboxProps) { const [open, setOpen] = React.useState(false); const handleSelect = (selectedValue: T) => { if (multiple) { const newValue = Array.isArray(value) ? [...value] : []; if (newValue.includes(selectedValue)) { newValue.splice(newValue.indexOf(selectedValue), 1); onChange(newValue as OnChangeType); } else { onChange([...newValue, selectedValue] as OnChangeType); } } else { const newValue = selectedValue === value ? ('' as T) : selectedValue; onChange(newValue as OnChangeType); setOpen(false); } }; const renderButtonLabel = () => { if (multiple && Array.isArray(value) && value.length > 0) { const selectedLabels = options .filter((option) => value.includes(option.value)) .map((option) => option.label) .join(', '); return selectedLabels; } else if (!multiple) { const selectedOption = options.find((option) => option.value === value); return selectedOption ? selectedOption.label : placeholder; } return placeholder; }; return ( {options.map((option) => ( handleSelect(option.value)} > {option.children || option.label} ))} ); }