From a5cc9671cdb2d156ede4637623d072d36bd98304 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sat, 27 May 2017 14:33:59 +0200 Subject: [PATCH] fix(menu): not handling keyboard events when opened by mouse Fixes the menu keyboard interactions not working when it is opened by a click. Fixes #4991. --- src/lib/menu/menu-trigger.ts | 13 +++++++++---- src/lib/menu/menu.html | 2 +- src/lib/menu/menu.scss | 1 + src/lib/menu/menu.spec.ts | 19 ++++++++++++++++++- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/lib/menu/menu-trigger.ts b/src/lib/menu/menu-trigger.ts index 11de10b053e7..23b67ffceaec 100644 --- a/src/lib/menu/menu-trigger.ts +++ b/src/lib/menu/menu-trigger.ts @@ -161,10 +161,15 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy { private _initMenu(): void { this._setIsMenuOpen(true); - // Should only set focus if opened via the keyboard, so keyboard users can - // can easily navigate menu items. According to spec, mouse users should not - // see the focus style. - if (!this._openedByMouse) { + // If the menu was opened by mouse, we focus the root node, which allows for the keyboard + // interactions to work. Otherwise, if the menu was opened by keyboard, we focus the first item. + if (this._openedByMouse) { + let rootNode = this._overlayRef.overlayElement.firstElementChild as HTMLElement; + + if (rootNode) { + rootNode.focus(); + } + } else { this.menu.focusFirstItem(); } } diff --git a/src/lib/menu/menu.html b/src/lib/menu/menu.html index 10972059e8c5..1ede330f980e 100644 --- a/src/lib/menu/menu.html +++ b/src/lib/menu/menu.html @@ -1,6 +1,6 @@
+ (click)="_emitCloseEvent()" [@transformMenu]="'showing'" tabindex="-1">
diff --git a/src/lib/menu/menu.scss b/src/lib/menu/menu.scss index abe8659c6545..603e273da218 100644 --- a/src/lib/menu/menu.scss +++ b/src/lib/menu/menu.scss @@ -12,6 +12,7 @@ $mat-menu-vertical-padding: 8px !default; @include mat-menu-base(); @include mat-menu-positions(); max-height: calc(100vh - #{$mat-menu-item-height}); + outline: 0; @include cdk-high-contrast { outline: solid 1px; diff --git a/src/lib/menu/menu.spec.ts b/src/lib/menu/menu.spec.ts index de9cabf903c4..73f98afcd5ae 100644 --- a/src/lib/menu/menu.spec.ts +++ b/src/lib/menu/menu.spec.ts @@ -21,7 +21,7 @@ import {OverlayContainer} from '../core/overlay/overlay-container'; import {Dir, LayoutDirection} from '../core/rtl/dir'; import {extendObject} from '../core/util/object-extend'; import {ESCAPE} from '../core/keyboard/keycodes'; -import {dispatchKeyboardEvent} from '../core/testing/dispatch-events'; +import {dispatchKeyboardEvent, dispatchFakeEvent} from '../core/testing/dispatch-events'; describe('MdMenu', () => { @@ -134,6 +134,23 @@ describe('MdMenu', () => { expect(panel.classList).toContain('custom-two'); }); + it('should focus the menu panel root node when it was opened by mouse', () => { + const fixture = TestBed.createComponent(SimpleMenu); + + fixture.detectChanges(); + + const triggerEl = fixture.componentInstance.triggerEl.nativeElement; + + dispatchFakeEvent(triggerEl, 'mousedown'); + triggerEl.click(); + fixture.detectChanges(); + + const panel = overlayContainerElement.querySelector('.mat-menu-panel'); + + expect(panel).toBeTruthy('Expected the panel to be rendered.'); + expect(document.activeElement).toBe(panel, 'Expected the panel to be focused.'); + }); + describe('positions', () => { let fixture: ComponentFixture; let panel: HTMLElement;