This commit is contained in:
@@ -84,7 +84,7 @@ const TaskDetailActionBar: FC<Props> = ({ activeTab, onTabChange, labelsPopover,
|
|||||||
|
|
||||||
{(Object.keys(popoverByTab) as PopoverTab[]).map((tab) =>
|
{(Object.keys(popoverByTab) as PopoverTab[]).map((tab) =>
|
||||||
popoverByTab[tab] ? (
|
popoverByTab[tab] ? (
|
||||||
<TaskDetailPopoverPanel key={tab} anchorRef={anchorRefs.current[tab]}>
|
<TaskDetailPopoverPanel key={tab} anchorRef={anchorRefs.current[tab]} onClose={() => onTabChange(tab)}>
|
||||||
{popoverByTab[tab]}
|
{popoverByTab[tab]}
|
||||||
</TaskDetailPopoverPanel>
|
</TaskDetailPopoverPanel>
|
||||||
) : null,
|
) : 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 { createPortal } from "react-dom";
|
||||||
import { clx } from "../../../../helpers/utils";
|
import { clx } from "../../../../helpers/utils";
|
||||||
|
|
||||||
@@ -7,10 +7,12 @@ type Props = {
|
|||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
width?: number;
|
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 [position, setPosition] = useState<{ top: number; left: number } | null>(null);
|
||||||
|
const panelRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const updatePosition = () => {
|
const updatePosition = () => {
|
||||||
@@ -38,10 +40,25 @@ const TaskDetailPopoverPanel: FC<Props> = ({ anchorRef, children, className, wid
|
|||||||
};
|
};
|
||||||
}, [anchorRef, width]);
|
}, [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;
|
if (!position) return null;
|
||||||
|
|
||||||
return createPortal(
|
return createPortal(
|
||||||
<div
|
<div
|
||||||
|
ref={panelRef}
|
||||||
style={{ top: position.top, left: position.left, width }}
|
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)}
|
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