ar-design
Version:
AR Design is a (react | nextjs) ui library.
69 lines (68 loc) • 3.49 kB
JavaScript
"use client";
import React, { useEffect, useRef, useState } from "react";
import "../../../assets/css/components/form/button-action/styles.css";
import Button from "../button";
import ReactDOM from "react-dom";
const ButtonAction = ({ buttons }) => {
// refs
const _wrapper = useRef(null);
const _button = useRef(null);
const _list = useRef(null);
// states
const [open, setOpen] = useState(false);
// methods
const handleClickOutSide = (event) => {
const target = event.target;
if (_wrapper.current && !_wrapper.current.contains(target))
setOpen(false);
};
const handleKeys = (event) => {
const key = event.key;
if (key === "Escape")
setOpen(false);
};
const handlePosition = () => {
if (_wrapper.current && _button.current && _list.current) {
const elementRect = _button.current.getBoundingClientRect();
const popoverRect = _list.current.getBoundingClientRect();
if (elementRect) {
const screenCenterX = window.innerWidth / 2;
const screenCenterY = window.innerHeight / 2;
const sx = window.scrollX || document.documentElement.scrollLeft;
const sy = window.scrollY || document.documentElement.scrollTop;
_list.current.style.visibility = "visible";
_list.current.style.opacity = "1";
_list.current.style.top = `${(elementRect.top > screenCenterY
? elementRect.top - popoverRect.height + elementRect.height
: elementRect.top) + sy}px`;
_list.current.style.left = `${(elementRect.left > screenCenterX
? elementRect.right - (elementRect.width + 7.5) - popoverRect.width
: elementRect.left + elementRect.width + 7.5) + sx}px`;
}
}
};
const handleResizeEvent = () => setOpen(false);
// useEffects
useEffect(() => {
if (!open)
return;
setTimeout(() => handlePosition(), 0);
window.addEventListener("blur", () => setOpen(false));
window.addEventListener("resize", handleResizeEvent);
document.addEventListener("click", handleClickOutSide);
document.addEventListener("keydown", handleKeys);
return () => {
window.removeEventListener("blur", () => setOpen(false));
window.removeEventListener("resize", handleResizeEvent);
document.removeEventListener("click", handleClickOutSide);
document.removeEventListener("keydown", handleKeys);
};
}, [open]);
return (React.createElement("div", { ref: _wrapper, className: "ar-button-action" },
React.createElement("span", { ref: _button },
React.createElement(Button, { variant: "borderless", color: "light", icon: { element: React.createElement("span", { className: "dotted" }) }, onClick: () => setOpen((prev) => !prev) })),
open &&
ReactDOM.createPortal(React.createElement("span", { ref: _list, className: "ar-action-buttons" }, buttons.map((button, index) => (React.createElement(Button, { key: index, style: { display: "flex", justifyContent: "flex-start" }, variant: "borderless", color: button.color ?? "blue", size: "small", icon: button.icon, onClick: button.onClick }, button.text)))), document.body)));
};
ButtonAction.displayName = "ButtonAction";
export default ButtonAction;