Skip to content

bug(cdk/menu): Trigger does not update ARIA values correctly in OnPush components #27725

Closed
@sbarfurth

Description

@sbarfurth

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

I recently noticed that the menu trigger (CdkMenuTrigger) misbehaves when inside OnPush components because the OnPush change detection strategy will cascade into child directives implicitly. Specifically, the aria-expanded property will not correctly follow the open sub-menu. After some investigation this seems to simply be caused by the CdkMenuTrigger not using detectChanges() or markForCheck() from the ChangeDetectorRef after opening and closing the menu overlay. The attachment state of the menu overlay is used to populate aria-expanded directly.

This can be worked around by having the OnPush parent listen to (opened) and (closed) events emitted by the trigger, but that is not very scalable since each menu item would then require two additional handlers inside every OnPush component.

I will be sending a pull request that will make the CdkMenuTrigger call relevant methods from the ChangeDetectorRef at appropriate times to support being placed in OnPush components.

Reproduction

StackBlitz link: https://stackblitz.com/edit/components-issue-uc7xxl

Note: In the StackBlitz the style of menu items is changed based on the aria-expanded property of the element. If the element has aria-expanded set to true the item will appear with a black background and white text. This is supposed to make it easy to see how aria-expanded updates.

Steps to reproduce:

  1. Create a an inline CdkMenu or a CdkMenuBar in a component using ChangeDetectionStrategy.OnPush
  2. Add sub-menus to the items of the inline menu
  3. Click any of the items to open its sub-menu
  4. Hover to any other item with a sub-menu

Expected Behavior

When hovering over another item with a sub-menu, the aria-expanded property of the newly hovered item should be set to true and that of the previous item should be set to false. The aria-expanded property should be true for the item that has an open sub-menu at all times. When clicking outside the menu all sub-menus should close and aria-expanded should be false for all items in the menu.

Actual Behavior

The aria-expanded property continues to be true on the initially clicked element regardless of the item hovered and where the open sub-menu is. It also continues to be true for an item even when all sub-menus are closed.

Environment

  • Angular: 16.2.1
  • CDK/Material: 16.2.1
  • Browser(s): Version 116.0.5845.110 (Official Build) (arm64)
  • Operating System (e.g. Windows, macOS, Ubuntu): macOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    AccessibilityThis issue is related to accessibility (a11y)P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgentarea: cdk/menu

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions