"use client"
import { useState, useEffect, useRef, ReactNode, ReactElement } from 'react';
import { FaChevronUp } from 'react-icons/fa';
export interface Option {
value: string;
label: string;
icon?: ReactNode;
}
interface SelectProps {
options: Option[];
value: string;
onChange: (value: string, label: string) => void;
placeholder?: string;
trigger?: ReactElement;
noOptionsMessage?: string;
noOptionsIcon?: ReactNode;
selectIcon?: ReactNode;
className?: string;
placeholderIcon?: ReactNode
}
const Select = ({
options,
value,
onChange,
placeholder,
trigger,
noOptionsMessage = 'No options found',
noOptionsIcon,
selectIcon,
className,
placeholderIcon
}: SelectProps) => {
const [isOpen, setIsOpen] = useState(false);
const selectRef = useRef(null);
const handleOptionClick = (optionValue: string, optionLabel: string) => {
onChange(optionValue, optionLabel);
setIsOpen(false);
};
const handleClickOutside = (event: MouseEvent) => {
if (selectRef.current && !selectRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
};
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
return (
setIsOpen(!isOpen)}
>
{trigger || (
<>
{selectIcon ? selectIcon : null}{options.find(option => option.value === value)?.label || placeholder}
>
)}
{isOpen && (
{options.length > 0 ? (
options.map((option) => (
handleOptionClick(option.value, option.label)}
>
{option.icon &&
{option.icon}
}
{option.label}
))
) : (
{noOptionsIcon &&
{noOptionsIcon}
}
{noOptionsMessage}
)}
)}
);
};
export default Select;