UNPKG

terriajs

Version:

Geospatial data visualization platform.

59 lines 3.31 kB
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime"; import { useState, useRef, useEffect, useCallback } from "react"; import classNames from "classnames"; import Styles from "./dropdown.scss"; import { OutsideClickHandler } from "./OutsideClickHandler"; const Dropdown = ({ theme = {}, options = [], selected, selectOption, textProperty = "name", disabled = false, children }) => { const [isOpen, setIsOpen] = useState(false); const buttonRef = useRef(null); const scrollListeners = useRef([]); const hideList = useCallback(() => { setIsOpen(false); }, []); const showList = useCallback(() => { setIsOpen(true); }, []); const select = useCallback((option, index) => { selectOption?.(option, index); hideList(); }, [selectOption, hideList]); const addScrollListeners = useCallback((element, listeningToSoFar) => { if (!element) return listeningToSoFar; if (element.scrollHeight > element.clientHeight) { element.addEventListener("scroll", hideList); listeningToSoFar.push(element); } if (element !== document.body) { return addScrollListeners(element.parentElement, listeningToSoFar); } return listeningToSoFar; }, [hideList]); const clearListeners = useCallback(() => { scrollListeners.current.forEach((element) => element?.removeEventListener("scroll", hideList)); scrollListeners.current = []; }, [hideList]); useEffect(() => { if (isOpen) { scrollListeners.current = addScrollListeners(buttonRef.current, []); } else { clearListeners(); } return clearListeners; }, [addScrollListeners, clearListeners, hideList, isOpen]); const selectedText = selected?.[textProperty]; return (_jsx("div", { className: classNames(Styles.dropdown, theme.dropdown), children: _jsxs(OutsideClickHandler, { disabled: !isOpen, onOutsideClick: hideList, children: [_jsxs("button", { type: "button", onClick: isOpen ? hideList : showList, className: classNames(theme.button, Styles.btnDropdown), ref: buttonRef, disabled: disabled, children: [selectedText || children, theme.icon] }), _jsx("ul", { className: classNames(Styles.list, theme.list, { [Styles.isOpen]: isOpen, [theme.isOpen ?? ""]: isOpen }), children: options.map((option, i) => { const optionText = option[textProperty]; return (_jsx("li", { children: option.href ? (_jsx("a", { href: option.href, target: "_blank", rel: "noopener noreferrer", className: classNames(Styles.btnOption, theme.btnOption || "", { [Styles.isSelected]: option === selected }), download: option.download, children: optionText })) : (_jsx("button", { type: "button", className: classNames(Styles.btnOption, theme.btnOption || "", { [Styles.isSelected]: option === selected }), onClick: () => select(option, i), children: optionText })) }, optionText)); }) })] }) })); }; export default Dropdown; //# sourceMappingURL=Dropdown.js.map