diff --git a/packages/react-devtools-shared/src/devtools/views/Components/Tree.js b/packages/react-devtools-shared/src/devtools/views/Components/Tree.js index 5623d507a3b7..502056f936c8 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/Tree.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/Tree.js @@ -384,6 +384,23 @@ export default function Tree(): React.Node { const handleMouseLeave = clearHighlightHostInstance; + // The synthetic onMouseLeave on the tree div only fires within the document, + // so we need a native listener on the document itself. + useEffect(() => { + const container = focusTargetRef.current; + if (container == null) { + return; + } + const ownerDocument = container.ownerDocument; + ownerDocument.addEventListener('mouseleave', clearHighlightHostInstance); + return () => { + ownerDocument.removeEventListener( + 'mouseleave', + clearHighlightHostInstance, + ); + }; + }, [clearHighlightHostInstance]); + // Let react-window know to re-render any time the underlying tree data changes. // This includes the owner context, since it controls a filtered view of the tree. const itemData = useMemo(