import * as React from 'react' import { Command as CommandPrimitive } from 'cmdk' import { X } from 'lucide-react' import { useTranslation } from 'react-i18next' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Command, CommandGroup, CommandItem } from '@/components/ui/command' export type Option = { label: string value: string } interface MultiSelectProps { options: Option[] selected: string[] onChange: (values: string[]) => void placeholder?: string className?: string } export function MultiSelect({ options, selected, onChange, placeholder, className, }: MultiSelectProps) { const { t } = useTranslation() const resolvedPlaceholder = placeholder ?? t('Select items...') const inputRef = React.useRef(null) const [open, setOpen] = React.useState(false) const [inputValue, setInputValue] = React.useState('') const handleUnselect = (value: string) => { onChange(selected.filter((s) => s !== value)) } const handleKeyDown = (e: React.KeyboardEvent) => { const input = inputRef.current if (input) { if (e.key === 'Delete' || e.key === 'Backspace') { if (input.value === '' && selected.length > 0) { onChange(selected.slice(0, -1)) } } if (e.key === 'Escape') { input.blur() } } } const selectables = options.filter( (option) => !selected.includes(option.value) ) return (
{selected.map((value) => { const option = options.find((o) => o.value === value) return ( {option?.label || value} ) })} setOpen(false)} onFocus={() => setOpen(true)} placeholder={selected.length === 0 ? resolvedPlaceholder : ''} className='placeholder:text-muted-foreground flex-1 bg-transparent outline-none' />
{open && selectables.length > 0 ? (
{selectables.map((option) => { return ( { e.preventDefault() e.stopPropagation() }} onSelect={() => { setInputValue('') onChange([...selected, option.value]) }} className='cursor-pointer' > {option.label} ) })}
) : null}
) }