Skip to content

Commit 6be0462

Browse files
crisbetoandrewseguin
authored andcommitted
fix(autocomplete): empty not cleaning up on tab (#7270)
Fixes an issue that caused the autocomplete not to be cleaned up when the user tabs away, if there were no results when the autocomplete was open. Fixes #7268.
1 parent 5f8615f commit 6be0462

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

src/lib/autocomplete/autocomplete-trigger.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {Directionality} from '@angular/cdk/bidi';
10-
import {DOWN_ARROW, ENTER, ESCAPE, UP_ARROW} from '@angular/cdk/keycodes';
10+
import {DOWN_ARROW, ENTER, ESCAPE, UP_ARROW, TAB} from '@angular/cdk/keycodes';
1111
import {
1212
ConnectedPositionStrategy,
1313
Overlay,
@@ -259,19 +259,21 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
259259
}
260260

261261
_handleKeydown(event: KeyboardEvent): void {
262-
if (event.keyCode === ESCAPE && this.panelOpen) {
262+
const keyCode = event.keyCode;
263+
264+
if (keyCode === ESCAPE && this.panelOpen) {
263265
this._resetActiveItem();
264266
this.closePanel();
265267
event.stopPropagation();
266-
} else if (this.activeOption && event.keyCode === ENTER && this.panelOpen) {
268+
} else if (this.activeOption && keyCode === ENTER && this.panelOpen) {
267269
this.activeOption._selectViaInteraction();
268270
this._resetActiveItem();
269271
event.preventDefault();
270272
} else {
271273
const prevActiveItem = this.autocomplete._keyManager.activeItem;
272-
const isArrowKey = event.keyCode === UP_ARROW || event.keyCode === DOWN_ARROW;
274+
const isArrowKey = keyCode === UP_ARROW || keyCode === DOWN_ARROW;
273275

274-
if (this.panelOpen) {
276+
if (this.panelOpen || keyCode === TAB) {
275277
this.autocomplete._keyManager.onKeydown(event);
276278
} else if (isArrowKey) {
277279
this.openPanel();

src/lib/autocomplete/autocomplete.spec.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import {Direction, Directionality} from '@angular/cdk/bidi';
2-
import {DOWN_ARROW, ENTER, ESCAPE, SPACE, UP_ARROW} from '@angular/cdk/keycodes';
2+
import {DOWN_ARROW, ENTER, ESCAPE, SPACE, UP_ARROW, TAB} from '@angular/cdk/keycodes';
33
import {OverlayContainer} from '@angular/cdk/overlay';
44
import {map, RxChain, startWith} from '@angular/cdk/rxjs';
55
import {ScrollDispatcher} from '@angular/cdk/scrolling';
6-
import {createKeyboardEvent, dispatchFakeEvent, typeInElement} from '@angular/cdk/testing';
6+
import {
7+
createKeyboardEvent,
8+
dispatchKeyboardEvent,
9+
dispatchFakeEvent,
10+
typeInElement,
11+
} from '@angular/cdk/testing';
712
import {
813
ChangeDetectionStrategy,
914
Component,
@@ -958,6 +963,26 @@ describe('MatAutocomplete', () => {
958963
});
959964
}));
960965

966+
it('should close the panel when tabbing away from a trigger without results', async(() => {
967+
const trigger = fixture.componentInstance.trigger;
968+
969+
fixture.componentInstance.states = [];
970+
fixture.componentInstance.filteredStates = [];
971+
fixture.detectChanges();
972+
input.focus();
973+
974+
fixture.whenStable().then(() => {
975+
expect(overlayContainerElement.querySelector('.mat-autocomplete-panel'))
976+
.toBeTruthy('Expected panel to be rendered.');
977+
978+
dispatchKeyboardEvent(input, 'keydown', TAB);
979+
fixture.detectChanges();
980+
981+
expect(overlayContainerElement.querySelector('.mat-autocomplete-panel'))
982+
.toBeFalsy('Expected panel to be removed.');
983+
});
984+
}));
985+
961986
it('should reset the active option when closing with the escape key', fakeAsync(() => {
962987
const trigger = fixture.componentInstance.trigger;
963988

0 commit comments

Comments
 (0)