Description
The useHover hook does not trigger the floating element to open when the reference element is hovered over, if both elements are rendered inside a closed shadow DOM. Because the nodes are all inside of a closed shadowDOM, it cannot find the popover target and assumes we should close the popover
I suspect this is because internal utilities, like getDocument(element), resolve to the main document rather than the specific shadowRoot that contains the element and the event listeners. This likely leads to event listeners being attached to the document rather than a custom root e.g. shadowDOM root.
ie
// react/src/utils.ts
export function getDocument(node: Element | null) {
return node?.ownerDocument || document;
}
// react/src/hooks/useHover.ts
const doc = getDocument(elements.floating);
...
doc.addEventListener('mousemove', handler);
unbindMouseMoveRef.current = () => {
doc.removeEventListener('mousemove', handler);
};
...
May share root causes with other event handling difficulties in closed shadow roots (e.g., #2420).
To Reproduce
Sandbox Example: https://codesandbox.io/p/devbox/floating-ui-react-dom-template-forked-rq5vw3?workspaceId=ws_7W4bVEnyApNs2h4kWzkjHu
Steps to reproduce the behavior using the sandbox:
- Open the sandbox link provided above.
- Wait for the preview pane to load the application. Note that the React application is rendered inside a shadowRoot attached with
{ mode: 'closed' }
- Hover the mouse cursor over the blue button labeled "Hover Me (Inside Shadow DOM)".
- Observe: The popover fails to open. The hover event is not triggering the floating element.
NOTE: If you modify src/index.js:10 from closed
to open
you'll see that it works
Expected behavior
When hovering over the reference element within the closed shadow DOM, the useHover hook should detect the mouseenter event and keep the floating element open
Context:
OS: Reproducible in CodeSandbox environment
Browser: Reproducible in CodeSandbox environment
Version: @floating-ui/react@0.27.6 (as configured in the sandbox)