ar-design
Version:
AR Design is a (react | nextjs) ui library.
60 lines (59 loc) • 2.39 kB
JavaScript
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
const FilterPopup = ({ children, tableContent, coordinate, buttons }) => {
// refs
const _arTableFilterPopup = useRef(null);
// states
const [open, setOpen] = useState(false);
// methods
const handleClickOutSide = (event) => {
const target = event.target;
const clickedInsidePopup = _arTableFilterPopup.current && _arTableFilterPopup.current.contains(target);
const isOneOfButtons = buttons.current.some((button) => button === target || button?.contains(target));
if (!clickedInsidePopup && !isOneOfButtons)
setOpen(false);
};
const handleKeys = (event) => {
const key = event.key;
if (key === "Escape")
setOpen(false);
};
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
// useEffects
useEffect(() => {
buttons.current.map((button) => {
if (button)
button.addEventListener("click", handleOpen);
});
return () => {
buttons.current.map((button) => {
if (button)
button.removeEventListener("click", handleOpen);
});
};
}, [buttons]);
useEffect(() => {
const firstFilterButton = buttons.current[0];
if (firstFilterButton) {
const rect = firstFilterButton.getBoundingClientRect();
coordinate.x = rect.left;
coordinate.y = rect.top + rect.height;
}
if (tableContent.current) {
tableContent.current.addEventListener("scroll", handleClose);
}
document.addEventListener("click", handleClickOutSide);
document.addEventListener("keydown", handleKeys);
return () => {
document.removeEventListener("click", handleClickOutSide);
document.removeEventListener("keydown", handleKeys);
if (tableContent.current) {
tableContent.current.removeEventListener("scroll", handleClose);
}
};
}, []);
return (open &&
ReactDOM.createPortal(React.createElement("div", { ref: _arTableFilterPopup, className: "ar-table-filter-popup", style: { top: coordinate.y, left: coordinate.x } }, children), document.body));
};
export default FilterPopup;