Skip to content

Commit

Permalink
fix(autocomplete,datepicker,menu): closing parent dialog by pressing …
Browse files Browse the repository at this point in the history
…escape (#6226)

Prevents the autocomplete, datepicker and menu components from closing their parent dialog when the user presses escape.

Fixes #6223.
  • Loading branch information
crisbeto authored and tinayuangao committed Aug 2, 2017
1 parent a043bec commit 916d1f3
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/lib/autocomplete/autocomplete-trigger.ts
Expand Up @@ -298,6 +298,7 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
_handleKeydown(event: KeyboardEvent): void {
if (event.keyCode === ESCAPE && this.panelOpen) {
this.closePanel();
event.stopPropagation();
} else if (this.activeOption && event.keyCode === ENTER && this.panelOpen) {
this.activeOption._selectViaInteraction();
event.preventDefault();
Expand Down
2 changes: 2 additions & 0 deletions src/lib/autocomplete/autocomplete.spec.ts
Expand Up @@ -898,6 +898,7 @@ describe('MdAutocomplete', () => {
it('should close the panel when pressing escape', async(() => {
const trigger = fixture.componentInstance.trigger;
const escapeEvent = createKeyboardEvent('keydown', ESCAPE);
const stopPropagationSpy = spyOn(escapeEvent, 'stopPropagation').and.callThrough();

input.focus();

Expand All @@ -909,6 +910,7 @@ describe('MdAutocomplete', () => {

expect(document.activeElement).toBe(input, 'Expected input to continue to be focused.');
expect(trigger.panelOpen).toBe(false, 'Expected panel to be closed.');
expect(stopPropagationSpy).toHaveBeenCalled();
});
}));

Expand Down
15 changes: 12 additions & 3 deletions src/lib/datepicker/datepicker.spec.ts
Expand Up @@ -9,8 +9,13 @@ import {MdDatepickerInput} from './datepicker-input';
import {MdInputModule} from '../input/index';
import {MdNativeDateModule} from '../core/datetime/index';
import {ESCAPE, OverlayContainer} from '../core';
import {dispatchFakeEvent, dispatchMouseEvent, dispatchKeyboardEvent} from '@angular/cdk/testing';
import {DEC, JAN} from '../core/testing/month-constants';
import {
dispatchFakeEvent,
dispatchMouseEvent,
createKeyboardEvent,
dispatchEvent,
} from '@angular/cdk/testing';

describe('MdDatepicker', () => {
afterEach(inject([OverlayContainer], (container: OverlayContainer) => {
Expand Down Expand Up @@ -134,13 +139,17 @@ describe('MdDatepicker', () => {
let content = document.querySelector('.cdk-overlay-pane md-datepicker-content')!;
expect(content).toBeTruthy('Expected datepicker to be open.');

let keyboadEvent = dispatchKeyboardEvent(content, 'keydown', ESCAPE);
const keyboardEvent = createKeyboardEvent('keydown', ESCAPE);
const stopPropagationSpy = spyOn(keyboardEvent, 'stopPropagation').and.callThrough();

dispatchEvent(content, keyboardEvent);
fixture.detectChanges();

content = document.querySelector('.cdk-overlay-pane md-datepicker-content')!;

expect(content).toBeFalsy('Expected datepicker to be closed.');
expect(keyboadEvent.defaultPrevented)
expect(stopPropagationSpy).toHaveBeenCalled();
expect(keyboardEvent.defaultPrevented)
.toBe(true, 'Expected default ESCAPE action to be prevented.');
});

Expand Down
1 change: 1 addition & 0 deletions src/lib/datepicker/datepicker.ts
Expand Up @@ -106,6 +106,7 @@ export class MdDatepickerContent<D> implements AfterContentInit {
if (event.keyCode === ESCAPE) {
this.datepicker.close();
event.preventDefault();
event.stopPropagation();
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/menu/menu-directive.ts
Expand Up @@ -168,6 +168,7 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
switch (event.keyCode) {
case ESCAPE:
this.close.emit('keydown');
event.stopPropagation();
break;
case LEFT_ARROW:
if (this.parentMenu && this.direction === 'ltr') {
Expand Down
13 changes: 11 additions & 2 deletions src/lib/menu/menu.spec.ts
Expand Up @@ -29,7 +29,12 @@ import {
} from './index';
import {MENU_PANEL_TOP_PADDING} from './menu-trigger';
import {extendObject} from '../core/util/object-extend';
import {dispatchKeyboardEvent, dispatchMouseEvent} from '@angular/cdk/testing';
import {
dispatchKeyboardEvent,
dispatchMouseEvent,
dispatchEvent,
createKeyboardEvent,
} from '@angular/cdk/testing';


describe('MdMenu', () => {
Expand Down Expand Up @@ -103,11 +108,15 @@ describe('MdMenu', () => {
fixture.componentInstance.trigger.openMenu();

const panel = overlayContainerElement.querySelector('.mat-menu-panel')!;
dispatchKeyboardEvent(panel, 'keydown', ESCAPE);
const event = createKeyboardEvent('keydown', ESCAPE);
const stopPropagationSpy = spyOn(event, 'stopPropagation').and.callThrough();

dispatchEvent(panel, event);
fixture.detectChanges();
tick(500);

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

it('should open a custom menu', () => {
Expand Down

0 comments on commit 916d1f3

Please sign in to comment.