import React, { useState, useEffect, useRef } from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { IconProp } from "@fortawesome/fontawesome-svg-core"; export function OlDropdown(props: { className: string, leftIcon?: IconProp, rightIcon?: IconProp, label: string, children?: JSX.Element | JSX.Element[] }) { var [open, setOpen] = useState(false); var contentRef = useRef(null); var buttonRef = useRef(null); function setPosition(content: HTMLDivElement, button: HTMLButtonElement) { /* Reset the position of the content */ content.style.left = "0px"; content.style.top = "0px"; content.style.height = ""; /* Get the position and size of the button and the content elements */ var [cxl, cyt, cxr, cyb, cw, ch] = [content.getBoundingClientRect().x, content.getBoundingClientRect().y, content.getBoundingClientRect().x + content.clientWidth, content.getBoundingClientRect().y + content.clientHeight, content.clientWidth, content.clientHeight]; var [bxl, byt, bxr, byb, bbw, bh] = [button.getBoundingClientRect().x, button.getBoundingClientRect().y, button.getBoundingClientRect().x + button.clientWidth, button.getBoundingClientRect().y + button.clientHeight, button.clientWidth, button.clientHeight]; /* Limit the maximum height */ if (ch > 400) { ch = 400; content.style.height = `${ch}px`; } /* Compute the horizontal position of the center of the button and the content */ var cxc = (cxl + cxr) / 2; var bxc = (bxl + bxr) / 2; /* Compute the x and y offsets needed to align the button and element horizontally, and to put the content below the button */ var offsetX = bxc - cxc; var offsetY = byb - cyt + 8; /* Compute the new position of the left and right margins of the content */ cxl += offsetX; cxr += offsetX; cyb += offsetY; /* Try and move the content so it is inside the screen */ if (cxl < 0) offsetX -= cxl; if (cxr > window.innerWidth) offsetX -= (cxr - window.innerWidth) if (cyb > window.innerHeight) offsetY = -ch - 8; /* Apply the offset */ content.style.left = `${offsetX}px` content.style.top = `${offsetY}px` } useEffect(() => { if (contentRef.current && buttonRef.current) { const content = contentRef.current as HTMLDivElement; const button = buttonRef.current as HTMLButtonElement; setPosition(content, button); /* Register click events to automatically close the dropdown when clicked anywhere outside of it */ document.addEventListener('click', function (event) { const target = event.target; if (target && /*!content.contains(target as HTMLElement) &&*/ !button.contains(target as HTMLElement)) { setOpen(false); } }); } }) return
{props.children}
} /* Conveniency Component for dropdown elements */ export function OlDropdownItem(props) { return }