diff --git a/src/components/Elements/Tooltip/Tooltip.jsx b/src/components/Elements/Tooltip/Tooltip.jsx index 75696635..5df2df0c 100644 --- a/src/components/Elements/Tooltip/Tooltip.jsx +++ b/src/components/Elements/Tooltip/Tooltip.jsx @@ -4,10 +4,18 @@ import './tooltip.scss'; function Tooltip({ children, title, style, placement, subtitle }) { const [showTooltip, setShowTooltip] = useState(false); + const [isClosing, setIsClosing] = useState(false); const [reference, setReference] = useState(null); const tooltipId = useRef(`tooltip-${Math.random()}`); + const closeTimeout = useRef(null); - const { x, y, refs, strategy } = useFloating({ + const { + x, + y, + refs, + strategy, + placement: computedPlacement, + } = useFloating({ placement: placement || 'bottom', middleware: [flip(), offset(15), shift()], elements: { @@ -15,21 +23,64 @@ function Tooltip({ children, title, style, placement, subtitle }) { }, }); + const handleMouseEnter = () => { + // Clear any pending close timeout if mouse re-enters during exit + if (closeTimeout.current) { + clearTimeout(closeTimeout.current); + closeTimeout.current = null; + } + setIsClosing(false); + setShowTooltip(true); + }; + + const handleMouseLeave = () => { + setIsClosing(true); + // Wait for exit animation to complete before unmounting + closeTimeout.current = setTimeout(() => { + setShowTooltip(false); + setIsClosing(false); + }, 200); // Match exit animation duration + }; + + const handleFocus = () => { + if (closeTimeout.current) { + clearTimeout(closeTimeout.current); + closeTimeout.current = null; + } + setIsClosing(false); + setShowTooltip(true); + }; + + const handleBlur = () => { + setIsClosing(true); + closeTimeout.current = setTimeout(() => { + setShowTooltip(false); + setIsClosing(false); + }, 200); + }; + + // Determine the data-status attribute value + const getStatus = () => { + if (!showTooltip && !isClosing) return 'initial'; + if (isClosing) return 'close'; + return 'open'; + }; + return ( <>