Skip to content

[Bug]: cds-popover _handleFocusOut fails when used inside shadow-root with slotted elements - relatedTarget contains check breaks focus management #21063

@rsrduarteEG

Description

@rsrduarteEG

Package

@carbon/web-components

Browser

No response

Package version

v2.42.0

React version

No response

Description

When using the cds-popove component inside a shadow root with slotted elements, the _handleFocusOut event handler incorrectly closes the popover when clicking on elements within the popover content. This occurs because the this.contains(relatedTarget) check in the _handleFocusOut function fails to properly identify slotted elements as being "inside" the popover component, leading to premature popover closure.

The issue stems from how shadow DOM and slots work - slotted elements maintain their original DOM position outside the shadow root, but are visually rendered inside the slot. The contains() method checks the actual DOM tree structure, not the composed/flattened tree that users see, causing slotted elements to appear as "outside" the popover component even when they are visually and functionally inside it.

Reproduction/example

https://stackblitz.com/edit/github-dog8nn3r?file=index.html

Steps to reproduce

  1. Use the example in the Stackblitz
  2. Open the popover by clicking the trigger button
  3. Click on any interactive element inside the popover content

Expected Result: The popover should remain open when interacting with elements inside the popover content.

Actual Result: The popover immediately closes when clicking on slotted elements within the popover content, making the popover unusable for interactive content.

Root Cause: The _handleFocusOut method uses this.contains(relatedTarget) to determine if focus is moving outside the popover. However, slotted elements are not actually DOM children of the popover element (they remain in their original DOM location), so contains() returns false even though the elements are visually inside the popover content slot.

Suggested Severity

Severity 2 = User cannot complete task, and/or no workaround within the user experience of a given component.

Application/PAL

No response

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions