From 405f5d02cfcdc2f07eff8257e606482095960fc9 Mon Sep 17 00:00:00 2001 From: mmalerba Date: Tue, 15 Oct 2019 11:08:38 -0700 Subject: [PATCH] fix(menu): trigger should aria-controls panel (#17365) * fix(menu): trigger should aria-controls panel * update api golden * update mdc-based menu --- src/material-experimental/mdc-menu/menu.html | 1 + src/material-experimental/mdc-menu/menu.spec.ts | 9 +++++++++ src/material/menu/menu-panel.ts | 1 + src/material/menu/menu-trigger.ts | 1 + src/material/menu/menu.html | 1 + src/material/menu/menu.spec.ts | 9 +++++++++ src/material/menu/menu.ts | 4 ++++ tools/public_api_guard/material/menu.d.ts | 2 ++ 8 files changed, 28 insertions(+) diff --git a/src/material-experimental/mdc-menu/menu.html b/src/material-experimental/mdc-menu/menu.html index df113c78caa1..c2c2c285c999 100644 --- a/src/material-experimental/mdc-menu/menu.html +++ b/src/material-experimental/mdc-menu/menu.html @@ -1,6 +1,7 @@
{ overlayContainer.ngOnDestroy(); })); + it('should aria-controls the menu panel', () => { + const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + fixture.detectChanges(); + fixture.componentInstance.trigger.openMenu(); + fixture.detectChanges(); + expect(fixture.componentInstance.triggerEl.nativeElement.getAttribute('aria-controls')) + .toBe(fixture.componentInstance.menu.panelId); + }); + it('should open the menu as an idempotent operation', () => { const fixture = createComponent(SimpleMenu, [], [FakeIcon]); fixture.detectChanges(); diff --git a/src/material/menu/menu-panel.ts b/src/material/menu/menu-panel.ts index df11370daaaa..c48ca0f07dbf 100644 --- a/src/material/menu/menu-panel.ts +++ b/src/material/menu/menu-panel.ts @@ -37,6 +37,7 @@ export interface MatMenuPanel { lazyContent?: MatMenuContent; backdropClass?: string; hasBackdrop?: boolean; + readonly panelId?: string; /** * @deprecated To be removed. diff --git a/src/material/menu/menu-trigger.ts b/src/material/menu/menu-trigger.ts index e40dc3a2b951..dff3b6a2c2f8 100644 --- a/src/material/menu/menu-trigger.ts +++ b/src/material/menu/menu-trigger.ts @@ -76,6 +76,7 @@ const passiveEventListenerOptions = normalizePassiveListenerOptions({passive: tr 'class': 'mat-menu-trigger', 'aria-haspopup': 'true', '[attr.aria-expanded]': 'menuOpen || null', + '[attr.aria-controls]': 'menuOpen ? menu.panelId : null', '(mousedown)': '_handleMousedown($event)', '(keydown)': '_handleKeydown($event)', '(click)': '_handleClick($event)', diff --git a/src/material/menu/menu.html b/src/material/menu/menu.html index b0713131299e..acd80470095e 100644 --- a/src/material/menu/menu.html +++ b/src/material/menu/menu.html @@ -1,6 +1,7 @@
{ overlayContainer.ngOnDestroy(); })); + it('should aria-controls the menu panel', () => { + const fixture = createComponent(SimpleMenu, [], [FakeIcon]); + fixture.detectChanges(); + fixture.componentInstance.trigger.openMenu(); + fixture.detectChanges(); + expect(fixture.componentInstance.triggerEl.nativeElement.getAttribute('aria-controls')) + .toBe(fixture.componentInstance.menu.panelId); + }); + it('should open the menu as an idempotent operation', () => { const fixture = createComponent(SimpleMenu, [], [FakeIcon]); fixture.detectChanges(); diff --git a/src/material/menu/menu.ts b/src/material/menu/menu.ts index e1b5c17b9cd2..4ecb6c2d9779 100644 --- a/src/material/menu/menu.ts +++ b/src/material/menu/menu.ts @@ -90,6 +90,8 @@ export function MAT_MENU_DEFAULT_OPTIONS_FACTORY(): MatMenuDefaultOptions { */ const MAT_MENU_BASE_ELEVATION = 4; +let menuPanelUid = 0; + /** Base class with all of the `MatMenu` functionality. */ @Directive({ // TODO(devversion): this selector can be removed when we update to Angular 9.0. @@ -237,6 +239,8 @@ export class _MatMenuBase implements AfterContentInit, MatMenuPanel */ @Output() close = this.closed; + readonly panelId = `mat-menu-panel-${menuPanelUid++}`; + constructor( private _elementRef: ElementRef, private _ngZone: NgZone, diff --git a/tools/public_api_guard/material/menu.d.ts b/tools/public_api_guard/material/menu.d.ts index a39b9276a9a9..2e22eabccd76 100644 --- a/tools/public_api_guard/material/menu.d.ts +++ b/tools/public_api_guard/material/menu.d.ts @@ -20,6 +20,7 @@ export declare class _MatMenuBase implements AfterContentInit, MatMenuPanel; xPosition: MenuPositionX; @@ -105,6 +106,7 @@ export interface MatMenuPanel { hasBackdrop?: boolean; lazyContent?: MatMenuContent; overlapTrigger: boolean; + readonly panelId?: string; parentMenu?: MatMenuPanel | undefined; removeItem?: (item: T) => void; resetActiveItem: () => void;