'use client'; import { useState, forwardRef, useRef, useEffect } from 'react'; interface SelectProps { value?: string | string[]; onChange: (value: string | string[]) => void; options: { label: string; value: string }[]; placeholder?: string; disabled?: boolean; multiple?: boolean; } const Select = forwardRef( ({ value, onChange, options, placeholder, disabled = false, multiple = false }, ref) => { const [isOpen, setIsOpen] = useState(false); const selectRef = useRef(null); const triggerRef = useRef(null); const isMulti = multiple; const currentValue = value; const selectedLabels = isMulti ? (Array.isArray(currentValue) ? currentValue : []) : options.find((o) => o.value === currentValue)?.label || ''; function handleClick() { setIsOpen(!isOpen); } function handleSelect(optionValue: string) { if (isMulti) { const newValues = Array.isArray(currentValue) ? [...currentValue] : []; if (newValues.includes(optionValue)) { onChange(newValues.filter((v) => v !== optionValue)); } else { onChange([...newValues, optionValue]); } } else { onChange(optionValue); } setIsOpen(false); } function handleClickOutside(e: MouseEvent) { if (triggerRef.current && !triggerRef.current.contains(e.target as Node)) { setIsOpen(false); } } useEffect(() => { if (isOpen) { document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); } }, [isOpen]); return (
{placeholder || 'Select...'} {isMulti && Array.isArray(selectedLabels) && selectedLabels.length > 0 && ({selectedLabels.length})} {!isMulti && selectedLabels && {selectedLabels}}
{isOpen && (
{options.map((option) => { const isSelected = isMulti ? Array.isArray(currentValue) && currentValue.includes(option.value) : currentValue === option.value; return (
handleSelect(option.value)} className={` px-3 py-2 cursor-pointer hover:bg-surface-50 dark:hover:bg-surface-700 ${isSelected ? 'bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-400' : 'text-surface-800 dark:text-surface-300'} `} >
{isMulti && ( {}} className="w-4 h-4" readOnly /> )} {option.label}
); })}
)}
); } ); Select.displayName = 'Select'; export { Select };