Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/lib/autocomplete/autocomplete-trigger.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -365,13 +365,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
event.preventDefault();
}

// Close when pressing ESCAPE or ALT + UP_ARROW, based on the a11y guidelines.
// See: https://www.w3.org/TR/wai-aria-practices-1.1/#textbox-keyboard-interaction
if (this.panelOpen && (keyCode === ESCAPE || (keyCode === UP_ARROW && event.altKey))) {
this._resetActiveItem();
this._closeKeyEventStream.next();
event.stopPropagation();
} else if (this.activeOption && keyCode === ENTER && this.panelOpen) {
if (this.activeOption && keyCode === ENTER && this.panelOpen) {
this.activeOption._selectViaInteraction();
this._resetActiveItem();
event.preventDefault();
Expand DownExpand Up@@ -574,6 +568,17 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
this._portal = new TemplatePortal(this.autocomplete.template, this._viewContainerRef);
this._overlayRef = this._overlay.create(this._getOverlayConfig());

// Use the `keydownEvents` in order to take advantage of
// the overlay event targeting provided by the CDK overlay.
this._overlayRef.keydownEvents().subscribe(event => {
// Close when pressing ESCAPE or ALT + UP_ARROW, based on the a11y guidelines.
// See: https://www.w3.org/TR/wai-aria-practices-1.1/#textbox-keyboard-interaction
if (event.keyCode === ESCAPE || (event.keyCode === UP_ARROW && event.altKey)) {
this._resetActiveItem();
this._closeKeyEventStream.next();
}
});

if (this._viewportRuler) {
this._viewportSubscription = this._viewportRuler.change().subscribe(() => {
if (this.panelOpen && this._overlayRef) {
Expand Down
14 changes: 5 additions & 9 deletions src/lib/autocomplete/autocomplete.spec.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,6 +8,7 @@ import {
dispatchKeyboardEvent,
MockNgZone,
typeInElement,
dispatchEvent,
} from '@angular/cdk/testing';
import {
ChangeDetectionStrategy,
Expand DownExpand Up@@ -1043,8 +1044,6 @@ describe('MatAutocomplete', () => {

it('should close the panel when pressing escape', fakeAsync(() => {
const trigger = fixture.componentInstance.trigger;
const escapeEvent = createKeyboardEvent('keydown', ESCAPE);
const stopPropagationSpy = spyOn(escapeEvent, 'stopPropagation').and.callThrough();

input.focus();
flush();
Expand All@@ -1053,12 +1052,11 @@ describe('MatAutocomplete', () => {
expect(document.activeElement).toBe(input, 'Expected input to be focused.');
expect(trigger.panelOpen).toBe(true, 'Expected panel to be open.');

trigger._handleKeydown(escapeEvent);
dispatchKeyboardEvent(document.body, 'keydown', ESCAPE);
fixture.detectChanges();

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();
}));

it('should prevent the default action when pressing escape', fakeAsync(() => {
Expand All@@ -1080,7 +1078,7 @@ describe('MatAutocomplete', () => {
expect(document.activeElement).toBe(input, 'Expected input to be focused.');
expect(trigger.panelOpen).toBe(true, 'Expected panel to be open.');

trigger._handleKeydown(upArrowEvent);
dispatchEvent(document.body, upArrowEvent);
fixture.detectChanges();

expect(document.activeElement).toBe(input, 'Expected input to continue to be focused.');
Expand DownExpand Up@@ -1125,7 +1123,7 @@ describe('MatAutocomplete', () => {
// from crashing when trying to stringify the option if the test fails.
expect(!!trigger.activeOption).toBe(true, 'Expected to find an active option.');

trigger._handleKeydown(createKeyboardEvent('keydown', ESCAPE));
dispatchKeyboardEvent(document.body, 'keydown', ESCAPE);
tick();

expect(!!trigger.activeOption).toBe(false, 'Expected no active options.');
Expand DownExpand Up@@ -1782,10 +1780,8 @@ describe('MatAutocomplete', () => {
});

it('should close the panel when pressing escape', () => {
const escapeEvent = createKeyboardEvent('keydown', ESCAPE);

expect(closingActionSpy).not.toHaveBeenCalled();
trigger._handleKeydown(escapeEvent);
dispatchKeyboardEvent(document.body, 'keydown', ESCAPE);
expect(closingActionSpy).toHaveBeenCalledWith(null);
});
});
Expand Down