ar-design
Version:
AR Design is a (react | nextjs) ui library.
82 lines (81 loc) • 4.22 kB
JavaScript
"use client";
import React, { useEffect, useRef, useState } from "react";
import "../../../assets/css/components/feedback/popover/styles.css";
import Button from "../../form/button";
import Typography from "../../data-display/typography";
import ReactDOM from "react-dom";
const { Title } = Typography;
const Popover = ({ children, title, message, content, onConfirm, windowBlur, fullWidth, config }) => {
// refs
const _arPopoverWrapper = useRef(null);
const _arPopover = useRef(null);
const _arPopoverElement = useRef(null);
const _arPopoverClassName = ["ar-popover-wrapper"];
if (fullWidth)
_arPopoverClassName.push("full-width");
// states
const [open, setOpen] = useState(false);
// methods
const handleClickOutSide = (event) => {
const target = event.target;
if (_arPopover.current && !_arPopover.current.contains(target))
setOpen(false);
};
const handleKeys = (event) => {
const key = event.key;
if (key === "Escape")
setOpen(false);
};
const handlePosition = () => {
if (_arPopoverWrapper.current && _arPopover.current && _arPopoverElement.current) {
const popoverRect = _arPopover.current.getBoundingClientRect();
const elementRect = _arPopoverElement.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;
_arPopover.current.style.visibility = "visible";
_arPopover.current.style.opacity = "1";
_arPopover.current.style.top = `${(elementRect.top > screenCenterY
? elementRect.top - popoverRect.height + elementRect.height
: elementRect.top) + sy}px`;
_arPopover.current.style.left = `${(elementRect.left > screenCenterX
? elementRect.right - (elementRect.width + 7.5) - popoverRect.width
: elementRect.left + elementRect.width + 7.5) + sx}px`;
}
}
};
// useEffects
useEffect(() => {
if (open) {
setTimeout(() => handlePosition(), 0);
!windowBlur && window.addEventListener("blur", () => setOpen(false));
document.addEventListener("click", handleClickOutSide);
document.addEventListener("keydown", handleKeys);
}
return () => {
!windowBlur && window.removeEventListener("blur", () => setOpen(false));
document.removeEventListener("click", handleClickOutSide);
document.removeEventListener("keydown", handleKeys);
};
}, [open]);
return (React.createElement("div", { ref: _arPopoverWrapper, className: _arPopoverClassName.map((c) => c).join(" "), role: "dialog" },
open &&
ReactDOM.createPortal(React.createElement("div", { ref: _arPopover, className: "ar-popover" },
title && (React.createElement("div", { className: "title" },
React.createElement(Title, { Level: "h4" }, title))),
message && React.createElement("p", { className: "message" }, message),
content && React.createElement("div", { className: "content" }, content),
onConfirm && (React.createElement("div", { className: "footer" },
React.createElement(Button, { status: "success", size: "small", onClick: () => {
onConfirm(true);
setOpen(false);
} }, config?.buttons.okay ?? "Evet"),
React.createElement(Button, { status: "light", size: "small", onClick: () => {
onConfirm(false);
setOpen(false);
} }, config?.buttons.cancel ?? "Hayır")))), document.body),
React.createElement("div", { ref: _arPopoverElement, onClick: () => setOpen((prev) => !prev) }, children)));
};
export default Popover;