import { useState, useEffect, useMemo } from 'react'; import { Variants } from 'framer-motion'; import { Icon } from '../../general/Icon/Icon'; import { Text } from '../../general/Text/Text'; import { MenuItemStyle } from '../../general/MenuItem/MenuItem.styles'; import { SelectDropdown, SelectWrapper } from './Select.styles'; import { RadioOption } from '../RadioGroup/RadioGroup'; const animationVariants: Variants = { enter: { opacity: 1, y: 4, display: 'block', transition: { duration: 0.3, }, }, exit: { y: -5, opacity: 0, transition: { duration: 0.3, }, transitionEnd: { display: 'none', }, }, }; type Props = { id: string; disabled?: boolean; placeholder?: string; defaultValue?: string; options: RadioOption[]; selected?: string; maxWidth?: number; width?: number; backgroundColor?: string; onClick: (value: string) => void; }; export const Select = ({ id = 'select-input', maxWidth, options, selected, placeholder = 'Select one', disabled, backgroundColor, width, onClick, }: Props) => { const [open, setOpen] = useState(false); const handleClickOutside = (event: MouseEvent) => { const domNode = document.getElementById(id); const dropdownNode = document.getElementById(`${id}-dropdown`); const isVisible = dropdownNode ? dropdownNode.getAttribute('data-is-open') === 'true' : false; // get if the picker is visible currently if (!domNode || !domNode.contains(event.target as HTMLElement)) { if ((event.target as HTMLElement).id === id) return; // You are clicking outside if (isVisible) setOpen(false); } }; useEffect(() => { document.addEventListener('click', handleClickOutside, true); () => { document.removeEventListener('click', handleClickOutside, true); }; }, []); const selectedOption = useMemo( () => options.find((option: RadioOption) => option.value === selected), [options, selected] ); const visibleOptions = useMemo( () => options.filter((option: RadioOption) => !option.hidden), [options] ); return ( !disabled && (open ? setOpen(false) : setOpen(true))} > {selectedOption ? ( {selectedOption.label} ) : ( {placeholder} )} {visibleOptions.map((option, index) => ( !disabled && !option.disabled && onClick(option.value) } > {option.label} ))} ); };