import { useDisclosure, useOutsideClick, Flex, Popover, PopoverTrigger, Input, PopoverContent, Button, InputProps, } from '@chakra-ui/react' import { useState, useRef, useEffect, ChangeEvent } from 'react' import { useDebounce } from 'use-debounce' type Props = { selectedItem?: string items: string[] onValueChange?: (value: string) => void } & InputProps export const SearchableDropdown = ({ selectedItem, items, onValueChange, ...inputProps }: Props) => { const { onOpen, onClose, isOpen } = useDisclosure() const [inputValue, setInputValue] = useState(selectedItem ?? '') const [debouncedInputValue] = useDebounce( inputValue, process.env.NEXT_PUBLIC_E2E_TEST ? 0 : 1000 ) const [filteredItems, setFilteredItems] = useState([ ...items .filter((item) => item.toLowerCase().includes((selectedItem ?? '').toLowerCase()) ) .slice(0, 50), ]) const dropdownRef = useRef(null) const inputRef = useRef(null) useEffect(() => { if (filteredItems.length > 0) return setFilteredItems([ ...items .filter((item) => item.toLowerCase().includes((selectedItem ?? '').toLowerCase()) ) .slice(0, 50), ]) if (inputRef.current === document.activeElement) onOpen() // eslint-disable-next-line react-hooks/exhaustive-deps }, [items]) useOutsideClick({ ref: dropdownRef, handler: onClose, }) useEffect(() => { onValueChange && debouncedInputValue !== selectedItem && onValueChange(debouncedInputValue) // eslint-disable-next-line react-hooks/exhaustive-deps }, [debouncedInputValue]) const onInputChange = (e: ChangeEvent) => { if (!isOpen) onOpen() setInputValue(e.target.value) if (e.target.value === '') { setFilteredItems([...items.slice(0, 50)]) return } setFilteredItems([ ...items .filter((item) => item.toLowerCase().includes((inputValue ?? '').toLowerCase()) ) .slice(0, 50), ]) } const handleItemClick = (item: string) => () => { setInputValue(item) onClose() } return ( {filteredItems.length > 0 && ( <> {filteredItems.map((item, idx) => { return ( ) })} )} ) }