import React, { useState, useMemo } from 'react' import { Check, ChevronsUpDown, X, Search } from 'lucide-react' import { cn } from '../lib/utils' import { Button } from './ui/button' import { Command, CommandEmpty, CommandGroup, CommandItem, CommandList, } from './ui/command' import { Popover, PopoverContent, PopoverTrigger, } from './ui/popover' export type MultiSelectOption = { value: string label: string } type MultiSelectSearchableProps = { options: MultiSelectOption[] value: string[] onChange: (value: string[]) => void onSearch?: (searchTerm: string) => void onOpenChange?: (open: boolean) => void placeholder?: string label?: string error_text?: string disabled?: boolean loading?: boolean } const MultiSelectSearchable: React.FC = ({ options, value, onChange, onSearch, onOpenChange, placeholder = "انتخاب کنید...", label, error_text, disabled = false, loading = false, }) => { const [open, setOpen] = useState(false) const handleOpenChange = (newOpen: boolean) => { setOpen(newOpen) onOpenChange?.(newOpen) } const selectedLabels = useMemo(() => { return value .map(v => options.find(option => option.value === v)?.label) .filter(Boolean) }, [value, options]) const handleSelect = (currentValue: string) => { const newValue = value.includes(currentValue) ? value.filter(v => v !== currentValue) : [...value, currentValue] onChange(newValue) } const handleRemove = (itemValue: string) => { onChange(value.filter(v => v !== itemValue)) } return (
{label && ( )} { // Prevent event bubbling that might cause navigation e.stopPropagation() }} > { // Prevent any navigation or form submission from command e.stopPropagation() }} >
{ e.preventDefault() onSearch?.(e.target.value) }} onKeyDown={(e) => { // Prevent form submission or other default behaviors if (e.key === 'Enter') { e.preventDefault() e.stopPropagation() } }} />
{loading && options.length === 0 && (
در حال بارگذاری...
)} موردی یافت نشد. {options.map((option) => { const isSelected = value.includes(option.value) return ( { handleSelect(option.value) }} className="flex items-center" > {option.label} ) })}
{error_text && (
{error_text}
)}
) } export default MultiSelectSearchable