fix(autocomplete,datepicker,menu): closing parent dialog by pressing escape (#6226)

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

Fixes #6223.
This commit is contained in:
Kristiyan Kostadinov
2017-08-03 01:17:12 +02:00
committed by tinayuangao
parent a043bec9da
commit 916d1f3bb0
6 changed files with 28 additions and 5 deletions
@@ -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();
@@ -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();
@@ -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();
});
}));
+12 -3
View File
@@ -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) => {
@@ -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.');
});
+1
View File
@@ -106,6 +106,7 @@ export class MdDatepickerContent<D> implements AfterContentInit {
if (event.keyCode === ESCAPE) {
this.datepicker.close();
event.preventDefault();
event.stopPropagation();
}
}
}
+1
View File
@@ -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') {
+11 -2
View File
@@ -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', () => {
@@ -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', () => {