import React from 'react'; import { twMerge } from 'tailwind-merge'; import { useSelect } from 'downshift'; import { Icon } from '@/shared/Icon'; type SelectProps = { options: Array<{ id: number | string; name: string }>; selectedId: number | string | null; onChange: (selectedId: number | string) => void; width?: string | number; listClassName?: string; testId?: string; }; export const Select = ({ options, selectedId, onChange, width = '100%', listClassName = '', testId = 'select-component', }: SelectProps): React.JSX.Element => { const selectedOption = options.find(option => option.id === selectedId) || null; const { isOpen, highlightedIndex, getToggleButtonProps, getMenuProps, getItemProps, selectedItem, } = useSelect({ items: options, selectedItem: selectedOption, onSelectedItemChange: ({ selectedItem: newSelectedItem }) => { if (newSelectedItem) { onChange(newSelectedItem.id); } }, itemToString: item => (item ? item.name : ''), }); const widthStyle = typeof width === 'number' ? { width: `${width}px` } : { width }; return ( <div data-testid={testId} className={twMerge( 'relative rounded-t bg-white text-xs shadow-primary', !isOpen && 'rounded-b', )} style={widthStyle} > <div className={twMerge( 'flex cursor-pointer flex-row items-center justify-between rounded-t p-2', )} {...getToggleButtonProps()} > <span data-testid="dropdown-button-name" className="font-medium"> {selectedItem ? selectedItem.name : 'Select an option'} </span> <Icon name="chevron-down" className={twMerge('arrow-button h-6 w-6 fill-primary-500', isOpen && 'rotate-180')} /> </div> <ul className={twMerge( 'absolute z-20 overflow-auto rounded-b bg-white shadow-lg', !isOpen && 'hidden', listClassName, )} style={widthStyle} {...getMenuProps()} > {isOpen && options.map((item, index) => ( <li className={twMerge( 'border-t', highlightedIndex === index && 'text-primary-500', selectedItem?.id === item.id && 'font-bold', 'flex flex-col p-2 shadow-sm', )} key={item.id} {...getItemProps({ item, index })} > <span>{item.name}</span> </li> ))} </ul> </div> ); };