Skip to content

ariaHideOutside incorrect behavior inside shadow DOM. #6133

@MahmoudElsayad

Description

@MahmoudElsayad

Provide a general summary of the issue here

Using modal dialogs in a web component that is implemented with Shadow DOM. The ariaHideOutside function sets aria-hidden="true" on the document body, which is incorrectly inherited by elements within our Shadow DOM. That behavior doesn't happen in the case of iframes due to the separate document. I think that this behavior is incorrect as the modal is being used inside of the shadow DOM and shouldn't alter the accessibility state of what is outside the shadow DOM encapsulation.

🤔 Expected Behavior?

The expected behavior is that aria-hidden should be confined to the scope of the component's Shadow DOM, affecting only those elements and not leaking to the outer document.

😯 Current Behavior

The root body gets aria-hidden set to true causing all children to be hidden, including what is inside the shadow DOM.

💁 Possible Solution

ariaHideOutside function should check the targets argument if any target has a shadow root using getRootNode and in the hide function we add a condition not to hide the node if it is not inside the shadow DOM boundary.

  let hide = (node: Element) => {
    // Do not hide if the node is not inside the shadow DOM boundary
    if (shadowRootBoundary instanceof ShadowRoot && !isInsideShadowDOM(node, shadowRootBoundary)) {
      return;
    }

🔦 Context

We use shadow DOM for encapsulation, and when opening a modal inside our app, it results in all contents in the shadow DOM and consumer app to have aria-hidden set to true.

🖥️ Steps to Reproduce

Hopefully, the following illustration can help clarify the issue:

+-------------------------------------------------+
| Consuming Application (Parent Document)         |
| +---------------------------------------------+ |
| | Our Web Component (Shadow DOM)              | |
| | +----------------------------------------+  | |
| | |  Modal Dialog                           | | |
| | | (should remain visible)                 | | |
| | +----------------------------------------+  | |
| | [Content in Shadow DOM, should be hidden    | |
| |  by aria-hidden, respecting encapsulation]  | |
| +--------------------------------------------+  |
| [Content outside our component should not be    |
|  affected by aria-hidden from within our        |
|  component's Shadow DOM]                        |
+-------------------------------------------------+

In the above example, the Consuming Application will have aria-hidden=true, which will cause everything to inherit the property, and the modal inside the shadow DOM will be hidden.

Version

@react-aria/overlays - 3.21.1

What browsers are you seeing the problem on?

Firefox, Chrome, Safari, Microsoft Edge

If other, please specify.

No response

What operating system are you using?

Mac OS

🧢 Your Company/Team

PSPDFKit

No response

🕷 Tracking Issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions