83 lines
1.9 KiB
JavaScript

import React, { useEffect, useMemo, useRef, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import {
closePopup,
openPopup,
togglePopup,
} from "../../slices/localVariablesSlice";
const HoverPopup = ({
id,
title,
content,
children,
className,
Mode = "hover",
}) => {
const dispatch = useDispatch();
const visible = useSelector((s) => s.localVariables.popups[id] || false);
const triggerRef = useRef(null);
const popupRef = useRef(null);
const handleMouseEnter = () => {
if (Mode === "hover") dispatch(openPopup(id));
};
const handleMouseLeave = () => {
if (Mode === "hover") dispatch(closePopup(id));
};
const handleClick = (e) => {
if (Mode === "click") {
e.stopPropagation();
dispatch(togglePopup(id));
}
};
useEffect(() => {
if (Mode !== "click" || !visible) return;
const handleOutside = (e) => {
if (
!popupRef.current?.contains(e.target) &&
!triggerRef.current?.contains(e.target)
) {
dispatch(closePopup(id));
}
};
document.addEventListener("click", handleOutside);
return () => document.removeEventListener("click", handleOutside);
}, [visible, Mode, id]);
return (
<div className="d-inline-block position-relative">
<div
ref={triggerRef}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
style={{ cursor: "pointer" }}
>
{children}
</div>
{visible && (
<div
ref={popupRef}
className={`bg-white border w-max rounded shadow-sm p-3 position-absolute top-100 mt-2 start-50 translate-middle-x ${className}`}
style={{ zIndex: 1000 }}
onClick={(e) => e.stopPropagation()}
>
{title && <h6 className="fw-semibold mb-2">{title}</h6>}
<div>{content}</div>
</div>
)}
</div>
);
};
export default HoverPopup;