@violetprotocol/nudge-components
Version:
Components for Nudge's websites and applications.
40 lines (39 loc) • 2.64 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useEffect, useRef, useState, } from "react";
import { Icon } from "../Icon/Icon";
import { clsx } from "clsx";
import { Typography } from "../Typography/Typography";
export const TokenDropdown = ({ tokens, selectedToken, ImageComponent, onSelectToken, className, }) => {
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef(null);
const ulRef = useRef(null);
// Set the width of the dropdown to be the same as the button
useEffect(() => {
if (dropdownRef.current && ulRef.current) {
ulRef.current.style.width = `${dropdownRef.current.offsetWidth}px`;
}
}, [isOpen]);
useEffect(() => {
document.addEventListener("pointerdown", handleClickOutside);
return () => {
document.removeEventListener("pointerdown", handleClickOutside);
};
}, []);
if (!Array.isArray(tokens) || tokens.length === 0)
return null;
const hasMoreThanOneToken = tokens.length > 1;
const handleClickOutside = (event) => {
if (dropdownRef.current &&
!dropdownRef.current.contains(event.target) &&
ulRef.current &&
!ulRef.current.contains(event.target.parentElement)) {
setIsOpen(false);
}
};
const handleTokenSelect = (token) => {
setIsOpen(false);
if (onSelectToken)
onSelectToken(token);
};
return (_jsxs(_Fragment, { children: [_jsx("div", { className: clsx("relative inline-flex items-center bg-neutral-50 rounded-lg", { "cursor-pointer": hasMoreThanOneToken }, className), ref: dropdownRef, onClick: () => hasMoreThanOneToken && setIsOpen(!isOpen), children: _jsxs("div", { className: "flex mx-auto items-center px-4 py-[22px]", children: [_jsx(ImageComponent, { src: selectedToken?.iconUri, height: 32, width: 32, className: "mr-2" }), _jsx(Typography, { variant: "p", className: "font-medium text-neutral-950", children: selectedToken?.symbol }), hasMoreThanOneToken && (_jsx(Icon, { name: "chevron-down", height: 24, width: 24, className: clsx("ml-2 transition-transform duration-300", isOpen && "rotate-180") }))] }) }), isOpen && (_jsx("ul", { className: "absolute mt-2 bg-neutral-50 rounded-md shadow-lg z-10", ref: ulRef, children: tokens.map((token) => (_jsxs("li", { className: "flex items-center p-2 cursor-pointer hover:bg-neutral-100", onClick: () => handleTokenSelect(token), children: [_jsx(ImageComponent, { src: token.iconUri, height: 32, width: 32, className: "mr-2" }), token.symbol] }, token.symbol))) }))] }));
};