114 lines
3.4 KiB
TypeScript
114 lines
3.4 KiB
TypeScript
import React from "react";
|
|
import { twMerge } from "tailwind-merge";
|
|
import ReactDOM from "react-dom";
|
|
import { TWUI_MODAL_PROPS } from "../elements/Modal";
|
|
import Paper from "../elements/Paper";
|
|
import _ from "lodash";
|
|
import twuiGrabPopoverStyles from "../(functions)/popver/grab-popover-styles";
|
|
|
|
type Props = TWUI_MODAL_PROPS & {
|
|
open: boolean;
|
|
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
|
targetElRef?: React.RefObject<HTMLElement | null>;
|
|
popoverTargetActiveRef: React.MutableRefObject<boolean>;
|
|
popoverContentActiveRef: React.MutableRefObject<boolean>;
|
|
};
|
|
|
|
/**
|
|
* # Modal Main Component
|
|
*/
|
|
export default function PopoverComponent({
|
|
open,
|
|
setOpen,
|
|
targetElRef,
|
|
position = "bottom",
|
|
trigger = "hover",
|
|
debounce,
|
|
popoverTargetActiveRef,
|
|
popoverContentActiveRef,
|
|
popoverReferenceRef,
|
|
isPopover,
|
|
...props
|
|
}: Props) {
|
|
if (!open) return null;
|
|
|
|
const [style, setStyle] = React.useState({});
|
|
|
|
React.useEffect(() => {
|
|
if (open && targetElRef?.current) {
|
|
const popoverStyle = twuiGrabPopoverStyles({
|
|
position,
|
|
targetElRef,
|
|
});
|
|
setStyle(popoverStyle);
|
|
}
|
|
}, [open, targetElRef, position]);
|
|
|
|
let closeTimeout: any;
|
|
|
|
const popoverEnterFn = React.useCallback(() => {
|
|
popoverContentActiveRef.current = true;
|
|
popoverTargetActiveRef.current = false;
|
|
setOpen(true);
|
|
}, []);
|
|
|
|
const popoverLeaveFn = React.useCallback(() => {
|
|
window.clearTimeout(closeTimeout);
|
|
closeTimeout = setTimeout(() => {
|
|
if (popoverTargetActiveRef.current) {
|
|
popoverTargetActiveRef.current = false;
|
|
return;
|
|
}
|
|
setOpen(false);
|
|
}, debounce);
|
|
}, []);
|
|
|
|
if (!open) return null;
|
|
|
|
return ReactDOM.createPortal(
|
|
<Paper
|
|
{...props}
|
|
className={twMerge(
|
|
"max-w-[300px]",
|
|
"twui-popover-content",
|
|
props.className
|
|
)}
|
|
style={{ ...style, ...props.style }}
|
|
onMouseEnter={
|
|
trigger === "hover" ? popoverEnterFn : props.onMouseEnter
|
|
}
|
|
onMouseLeave={
|
|
trigger === "hover" ? popoverLeaveFn : props.onMouseLeave
|
|
}
|
|
>
|
|
{/* <div
|
|
className="absolute w-0 h-0 border-8 border-transparent bg-white"
|
|
style={{
|
|
...(position === "bottom" && {
|
|
top: "-16px",
|
|
left: "50%",
|
|
transform: "translateX(-50%)",
|
|
}),
|
|
...(position === "top" && {
|
|
bottom: "-16px",
|
|
left: "50%",
|
|
transform: "translateX(-50%)",
|
|
}),
|
|
...(position === "right" && {
|
|
top: "50%",
|
|
left: "-16px",
|
|
transform: "translateY(-50%)",
|
|
}),
|
|
...(position === "left" && {
|
|
top: "50%",
|
|
right: "-16px",
|
|
transform: "translateY(-50%)",
|
|
}),
|
|
}}
|
|
/> */}
|
|
{props.children}
|
|
</Paper>,
|
|
document.getElementById("twui-popover-root") as HTMLElement
|
|
);
|
|
}
|