Skip to content

Commit

Permalink
fix(menu): close menu panel on escape (#4666)
Browse files Browse the repository at this point in the history
Fixes to #3601
  • Loading branch information
jelbourn authored and tinayuangao committed May 22, 2017
1 parent fa5b427 commit 210e57c
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 13 deletions.
35 changes: 24 additions & 11 deletions src/lib/menu/menu-directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {FocusKeyManager} from '../core/a11y/focus-key-manager';
import {MdMenuPanel} from './menu-panel';
import {Subscription} from 'rxjs/Subscription';
import {transformMenu, fadeInItems} from './menu-animations';
import {ESCAPE} from '../core/keyboard/keycodes';


@Component({
moduleId: module.id,
Expand Down Expand Up @@ -75,17 +77,6 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
/** Whether the menu should overlap its trigger. */
@Input() overlapTrigger = true;

ngAfterContentInit() {
this._keyManager = new FocusKeyManager(this.items).withWrap();
this._tabSubscription = this._keyManager.tabOut.subscribe(() => this._emitCloseEvent());
}

ngOnDestroy() {
if (this._tabSubscription) {
this._tabSubscription.unsubscribe();
}
}

/**
* This method takes classes set on the host md-menu element and applies them on the
* menu template that displays in the overlay container. Otherwise, it's difficult
Expand All @@ -104,6 +95,28 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
/** Event emitted when the menu is closed. */
@Output() close = new EventEmitter<void>();

ngAfterContentInit() {
this._keyManager = new FocusKeyManager(this.items).withWrap();
this._tabSubscription = this._keyManager.tabOut.subscribe(() => this._emitCloseEvent());
}

ngOnDestroy() {
if (this._tabSubscription) {
this._tabSubscription.unsubscribe();
}
}

/** Handle a keyboard event from the menu, delegating to the appropriate action. */
_handleKeydown(event: KeyboardEvent) {
switch (event.keyCode) {
case ESCAPE:
this._emitCloseEvent();
return;
default:
this._keyManager.onKeydown(event);
}
}

/**
* Focus the first item in the menu. This method is used by the menu trigger
* to focus the first item when the menu is opened by the ENTER key.
Expand Down
2 changes: 1 addition & 1 deletion src/lib/menu/menu.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<ng-template>
<div class="mat-menu-panel" [ngClass]="_classList" (keydown)="_keyManager.onKeydown($event)"
<div class="mat-menu-panel" [ngClass]="_classList" (keydown)="_handleKeydown($event)"
(click)="_emitCloseEvent()" [@transformMenu]="'showing'">
<div class="mat-menu-content" [@fadeInItems]="'showing'">
<ng-content></ng-content>
Expand Down
16 changes: 15 additions & 1 deletion src/lib/menu/menu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ import {
MenuPositionY
} from './index';
import {OverlayContainer} from '../core/overlay/overlay-container';
import {ViewportRuler} from '../core/overlay/position/viewport-ruler';
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';


describe('MdMenu', () => {
let overlayContainerElement: HTMLElement;
Expand Down Expand Up @@ -80,6 +82,18 @@ describe('MdMenu', () => {
expect(overlayContainerElement.textContent).toBe('');
});

it('should close the menu when pressing escape', () => {
const fixture = TestBed.createComponent(SimpleMenu);
fixture.detectChanges();
fixture.componentInstance.trigger.openMenu();

const panel = overlayContainerElement.querySelector('.mat-menu-panel');
dispatchKeyboardEvent(panel, 'keydown', ESCAPE);
fixture.detectChanges();

expect(overlayContainerElement.textContent).toBe('');
});

it('should open a custom menu', () => {
const fixture = TestBed.createComponent(CustomMenu);
fixture.detectChanges();
Expand Down

0 comments on commit 210e57c

Please sign in to comment.