This commit is contained in:
@@ -84,7 +84,7 @@ const TaskDetailActionBar: FC<Props> = ({ activeTab, onTabChange, labelsPopover,
|
||||
|
||||
{(Object.keys(popoverByTab) as PopoverTab[]).map((tab) =>
|
||||
popoverByTab[tab] ? (
|
||||
<TaskDetailPopoverPanel key={tab} anchorRef={anchorRefs.current[tab]}>
|
||||
<TaskDetailPopoverPanel key={tab} anchorRef={anchorRefs.current[tab]} onClose={() => onTabChange(tab)}>
|
||||
{popoverByTab[tab]}
|
||||
</TaskDetailPopoverPanel>
|
||||
) : null,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type FC, type ReactNode, useLayoutEffect, useState } from "react";
|
||||
import { type FC, type ReactNode, useEffect, useLayoutEffect, useRef, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { clx } from "../../../../helpers/utils";
|
||||
|
||||
@@ -7,10 +7,12 @@ type Props = {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
width?: number;
|
||||
onClose?: () => void;
|
||||
};
|
||||
|
||||
const TaskDetailPopoverPanel: FC<Props> = ({ anchorRef, children, className, width = 300 }) => {
|
||||
const TaskDetailPopoverPanel: FC<Props> = ({ anchorRef, children, className, width = 300, onClose }) => {
|
||||
const [position, setPosition] = useState<{ top: number; left: number } | null>(null);
|
||||
const panelRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const updatePosition = () => {
|
||||
@@ -38,10 +40,25 @@ const TaskDetailPopoverPanel: FC<Props> = ({ anchorRef, children, className, wid
|
||||
};
|
||||
}, [anchorRef, width]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!onClose) return;
|
||||
|
||||
const handlePointerDown = (event: PointerEvent) => {
|
||||
const target = event.target as Node;
|
||||
if (panelRef.current?.contains(target)) return;
|
||||
if (anchorRef.current?.contains(target)) return;
|
||||
onClose();
|
||||
};
|
||||
|
||||
document.addEventListener("pointerdown", handlePointerDown);
|
||||
return () => document.removeEventListener("pointerdown", handlePointerDown);
|
||||
}, [anchorRef, onClose]);
|
||||
|
||||
if (!position) return null;
|
||||
|
||||
return createPortal(
|
||||
<div
|
||||
ref={panelRef}
|
||||
style={{ top: position.top, left: position.left, width }}
|
||||
className={clx("fixed z-[80] bg-white/90 backdrop-blur-md rounded-2xl p-4 shadow-lg border border-white/80", className)}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user