UNPKG

ar-design

Version:

AR Design is a (react | nextjs) ui library.

82 lines (81 loc) 4.22 kB
"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;