From 9e2a66cbc294c893d378080e644c38de8ed631de Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 26 May 2017 20:34:39 +0200 Subject: [PATCH] fix(autocomplete): handle escape key (#4703) * Closes the autocomplete panel when pressing escape. * Switches the autocomplete unit tests to using the common utility for creating fake keyboard events. --- src/lib/autocomplete/autocomplete-trigger.ts | 6 ++++-- src/lib/autocomplete/autocomplete.spec.ts | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index cb675d1fc9e3..5dd5c1f8fce5 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -19,7 +19,7 @@ import {PositionStrategy} from '../core/overlay/position/position-strategy'; import {ConnectedPositionStrategy} from '../core/overlay/position/connected-position-strategy'; import {Observable} from 'rxjs/Observable'; import {MdOptionSelectionChange, MdOption} from '../core/option/option'; -import {ENTER, UP_ARROW, DOWN_ARROW} from '../core/keyboard/keycodes'; +import {ENTER, UP_ARROW, DOWN_ARROW, ESCAPE} from '../core/keyboard/keycodes'; import {Dir} from '../core/rtl/dir'; import {MdInputContainer} from '../input/input-container'; import {ScrollDispatcher} from '../core/overlay/scroll/scroll-dispatcher'; @@ -231,7 +231,9 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy { } _handleKeydown(event: KeyboardEvent): void { - if (this.activeOption && event.keyCode === ENTER) { + if (event.keyCode === ESCAPE && this.panelOpen) { + this.closePanel(); + } else if (this.activeOption && event.keyCode === ENTER) { this.activeOption._selectViaInteraction(); event.preventDefault(); } else { diff --git a/src/lib/autocomplete/autocomplete.spec.ts b/src/lib/autocomplete/autocomplete.spec.ts index 3da5ea9552fc..0199c1746788 100644 --- a/src/lib/autocomplete/autocomplete.spec.ts +++ b/src/lib/autocomplete/autocomplete.spec.ts @@ -16,7 +16,7 @@ import {MdInputModule} from '../input/index'; import {Dir, LayoutDirection} from '../core/rtl/dir'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {Subscription} from 'rxjs/Subscription'; -import {ENTER, DOWN_ARROW, SPACE, UP_ARROW} from '../core/keyboard/keycodes'; +import {ENTER, DOWN_ARROW, SPACE, UP_ARROW, ESCAPE} from '../core/keyboard/keycodes'; import {MdOption} from '../core/option/option'; import {MdAutocomplete} from './autocomplete'; import {MdInputContainer} from '../input/input-container'; @@ -758,6 +758,23 @@ describe('MdAutocomplete', () => { expect(scrollContainer.scrollTop).toEqual(272, `Expected panel to reveal last option.`); })); + it('should close the panel when pressing escape', async(() => { + const trigger = fixture.componentInstance.trigger; + const escapeEvent = createKeyboardEvent('keydown', ESCAPE); + + input.focus(); + + fixture.whenStable().then(() => { + expect(document.activeElement).toBe(input, 'Expected input to be focused.'); + expect(trigger.panelOpen).toBe(true, 'Expected panel to be open.'); + + trigger._handleKeydown(escapeEvent); + + expect(document.activeElement).toBe(input, 'Expected input to continue to be focused.'); + expect(trigger.panelOpen).toBe(false, 'Expected panel to be closed.'); + }); + })); + }); describe('aria', () => {