From c3b2d4f2c4485f70bcf9f23e396e0f44155d08ab Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Sun, 26 Aug 2018 17:36:56 +0200 Subject: [PATCH] fix(chips): chip list removing focus from first chip when adding through the input (#12840) Fix regression in 3da390e36df3a3f63695535c4f9fdac9b137eaee. Currently when the user removes all the chips and then they add a new chip, the chip list will remove focus from the input and put it on the chip. These changes introduce the proper behavior, which is to keep focus on the input. --- src/lib/chips/chip-list.spec.ts | 36 ++++++++++++++++++++++++++++++++- src/lib/chips/chip-list.ts | 13 +++++------- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/lib/chips/chip-list.spec.ts b/src/lib/chips/chip-list.spec.ts index f39987cbfa6a..da3239147f63 100644 --- a/src/lib/chips/chip-list.spec.ts +++ b/src/lib/chips/chip-list.spec.ts @@ -17,6 +17,7 @@ import { dispatchFakeEvent, dispatchKeyboardEvent, dispatchMouseEvent, + typeInElement, MockNgZone, } from '@angular/cdk/testing'; import { @@ -993,6 +994,31 @@ describe('MatChipList', () => { .not.toBeNull(`Expected placeholder to have an asterisk, as control was required.`); }); + it('should keep focus on the input after adding the first chip', fakeAsync(() => { + const nativeInput = fixture.nativeElement.querySelector('input'); + const chipEls = Array.from(fixture.nativeElement.querySelectorAll('.mat-chip')).reverse(); + + // Remove the chips via backspace to simulate the user removing them. + chipEls.forEach((chip: HTMLElement) => { + chip.focus(); + dispatchKeyboardEvent(chip, 'keydown', BACKSPACE); + fixture.detectChanges(); + tick(); + }); + + nativeInput.focus(); + expect(fixture.componentInstance.foods).toEqual([], 'Expected all chips to be removed.'); + expect(document.activeElement).toBe(nativeInput, 'Expected input to be focused.'); + + typeInElement('123', nativeInput); + fixture.detectChanges(); + dispatchKeyboardEvent(nativeInput, 'keydown', ENTER); + fixture.detectChanges(); + tick(); + + expect(document.activeElement).toBe(nativeInput, 'Expected input to remain focused.'); + })); + describe('keyboard behavior', () => { beforeEach(() => { chipListDebugElement = fixture.debugElement.query(By.directive(MatChipList)); @@ -1322,7 +1348,7 @@ class MultiSelectionChipList { - + {{ food.viewValue }} @@ -1369,6 +1395,14 @@ class InputChipList { } } + remove(food: any): void { + const index = this.foods.indexOf(food); + + if (index > -1) { + this.foods.splice(index, 1); + } + } + @ViewChild(MatChipList) chipList: MatChipList; @ViewChildren(MatChip) chips: QueryList; } diff --git a/src/lib/chips/chip-list.ts b/src/lib/chips/chip-list.ts index 3e0701692051..1e2074a90997 100644 --- a/src/lib/chips/chip-list.ts +++ b/src/lib/chips/chip-list.ts @@ -498,18 +498,15 @@ export class MatChipList extends _MatChipListMixinBase implements MatFormFieldCo } /** - * If the amount of chips changed, we need to update the key manager state and make sure - * that to so that we can refocus the - * next closest one. + * If the amount of chips changed, we need to update the + * key manager state and focus the next closest chip. */ protected _updateFocusForDestroyedChips() { - if (this._lastDestroyedChipIndex == null || !this.chips.length) { - return; + if (this._lastDestroyedChipIndex != null && this.chips.length) { + const newChipIndex = Math.min(this._lastDestroyedChipIndex, this.chips.length - 1); + this._keyManager.setActiveItem(newChipIndex); } - const newChipIndex = Math.min(this._lastDestroyedChipIndex, this.chips.length - 1); - - this._keyManager.setActiveItem(newChipIndex); this._lastDestroyedChipIndex = null; }