import React, { useState, useCallback, useEffect, useContext, useRef, } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { isEqual } from 'lodash'; import { I18nContext } from '../../../contexts/i18n'; import SearchableItemList from '../searchable-item-list'; import PulseLoader from '../../../components/ui/pulse-loader'; import UrlIcon from '../../../components/ui/url-icon'; export default function DropdownSearchList({ searchListClassName, itemsToSearch, selectPlaceHolderText, fuseSearchKeys, defaultToAll, maxListItems, onSelect, startingItem, onOpen, onClose, className = '', externallySelectedItem, selectorClosedClassName, loading, hideRightLabels, hideItemIf, listContainerClassName, }) { const t = useContext(I18nContext); const [isOpen, setIsOpen] = useState(false); const [selectedItem, setSelectedItem] = useState(startingItem); const close = useCallback(() => { setIsOpen(false); onClose?.(); }, [onClose]); const onClickItem = useCallback( (item) => { onSelect?.(item); setSelectedItem(item); close(); }, [onSelect, close], ); const onClickSelector = useCallback(() => { if (!isOpen) { setIsOpen(true); onOpen?.(); } }, [isOpen, onOpen]); const prevExternallySelectedItemRef = useRef(); useEffect(() => { prevExternallySelectedItemRef.current = externallySelectedItem; }); const prevExternallySelectedItem = prevExternallySelectedItemRef.current; useEffect(() => { if ( externallySelectedItem && !isEqual(externallySelectedItem, selectedItem) ) { setSelectedItem(externallySelectedItem); } else if (prevExternallySelectedItem && !externallySelectedItem) { setSelectedItem(null); } }, [externallySelectedItem, selectedItem, prevExternallySelectedItem]); const onKeyUp = (e) => { if (e.key === 'Escape') { close(); } else if (e.key === 'Enter') { onClickSelector(e); } }; return (
{!isOpen && (
{selectedItem?.iconUrl && ( )} {!selectedItem?.iconUrl && (
)}
{selectedItem?.symbol || selectPlaceHolderText}
)} {isOpen && ( <> loading ? (
{t('swapFetchingTokens')}
) : (
{t('swapBuildQuotePlaceHolderText', [searchQuery])}
) } searchPlaceholderText={t('swapSearchForAToken')} fuseSearchKeys={fuseSearchKeys} defaultToAll={defaultToAll} onClickItem={onClickItem} maxListItems={maxListItems} className={classnames( 'dropdown-search-list__token-container', searchListClassName, { 'dropdown-search-list--open': isOpen, }, )} hideRightLabels={hideRightLabels} hideItemIf={hideItemIf} listContainerClassName={listContainerClassName} />
{ event.stopPropagation(); setIsOpen(false); onClose?.(); }} /> )}
); } DropdownSearchList.propTypes = { itemsToSearch: PropTypes.array, onSelect: PropTypes.func, searchListClassName: PropTypes.string, fuseSearchKeys: PropTypes.arrayOf( PropTypes.shape({ name: PropTypes.string, weight: PropTypes.number, }), ), defaultToAll: PropTypes.bool, maxListItems: PropTypes.number, startingItem: PropTypes.object, onOpen: PropTypes.func, onClose: PropTypes.func, className: PropTypes.string, externallySelectedItem: PropTypes.object, loading: PropTypes.bool, selectPlaceHolderText: PropTypes.string, selectorClosedClassName: PropTypes.string, hideRightLabels: PropTypes.bool, hideItemIf: PropTypes.func, listContainerClassName: PropTypes.string, };