diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx index 844f3ca2..5413a652 100644 --- a/src/components/Tooltip/Tooltip.tsx +++ b/src/components/Tooltip/Tooltip.tsx @@ -314,6 +314,10 @@ const Tooltip = ({ return } + if (!activeAnchor?.isConnected) { + return + } + computeTooltipPosition({ place, offset, @@ -486,6 +490,7 @@ const Tooltip = ({ } const documentObserverCallback: MutationCallback = (mutationList) => { const newAnchors: HTMLElement[] = [] + const removedAnchors: HTMLElement[] = [] mutationList.forEach((mutation) => { if (mutation.type === 'attributes' && mutation.attributeName === 'data-tooltip-id') { const newId = (mutation.target as HTMLElement).getAttribute('data-tooltip-id') @@ -497,7 +502,30 @@ const Tooltip = ({ return } if (activeAnchor) { - ;[...mutation.removedNodes].some((node) => { + const elements = [...mutation.removedNodes].filter((node) => node.nodeType === 1) + if (selector) { + try { + removedAnchors.push( + // the element itself is an anchor + ...(elements.filter((element) => + (element as HTMLElement).matches(selector), + ) as HTMLElement[]), + ) + removedAnchors.push( + // the element has children which are anchors + ...elements.flatMap( + (element) => + [...(element as HTMLElement).querySelectorAll(selector)] as HTMLElement[], + ), + ) + } catch { + /** + * invalid CSS selector. + * already warned on tooltip controller + */ + } + } + elements.some((node) => { if (node?.contains?.(activeAnchor)) { setRendered(false) handleShow(false) @@ -538,8 +566,11 @@ const Tooltip = ({ */ } }) - if (newAnchors.length) { - setAnchorsBySelect((anchors) => [...anchors, ...newAnchors]) + if (newAnchors.length || removedAnchors.length) { + setAnchorsBySelect((anchors) => [ + ...anchors.filter((anchor) => removedAnchors.includes(anchor)), + ...newAnchors, + ]) } } const documentObserver = new MutationObserver(documentObserverCallback)