Skip to content

Commit 8168667

Browse files
crisbetoandrewseguin
authored andcommitted
fix(chips): programmatically selected chip stealing focus (#7978)
Currently chips that are selected programmatically (e.g. by setting the of `ngModel`) will moves focus to themselves, causing the page the scroll down. This can be observed in the demo app where the bottom chip instances have a preselected value which shifts focus to the bottom. These changes fix the issue by only moving focus if the selection was a result of a user interaction.
1 parent c8df2c1 commit 8168667

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

src/lib/chips/chip-list.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,17 @@ describe('MatChipList', () => {
577577
expect(falsyFixture.componentInstance.chips.first.selected)
578578
.toBe(true, 'Expected first option to be selected');
579579
});
580+
581+
it('should not focus the active chip when the value is set programmatically', () => {
582+
const chipArray = fixture.componentInstance.chips.toArray();
583+
584+
spyOn(chipArray[4], 'focus').and.callThrough();
585+
586+
fixture.componentInstance.control.setValue('chips-4');
587+
fixture.detectChanges();
588+
589+
expect(chipArray[4].focus).not.toHaveBeenCalled();
590+
});
580591
});
581592

582593
describe('multiple selection', () => {

src/lib/chips/chip-list.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,6 @@ export class MatChipList implements MatFormFieldControl<any>, ControlValueAccess
527527
private _isInputEmpty(element: HTMLElement): boolean {
528528
if (element && element.nodeName.toLowerCase() === 'input') {
529529
let input = element as HTMLInputElement;
530-
531530
return !input.value;
532531
}
533532

@@ -547,7 +546,14 @@ export class MatChipList implements MatFormFieldControl<any>, ControlValueAccess
547546
// Shift focus to the active item. Note that we shouldn't do this in multiple
548547
// mode, because we don't know what chip the user interacted with last.
549548
if (correspondingChip) {
550-
this._keyManager.setActiveItem(this.chips.toArray().indexOf(correspondingChip));
549+
const correspondingChipIndex = this.chips.toArray().indexOf(correspondingChip);
550+
551+
if (isUserInput) {
552+
this._keyManager.setActiveItem(correspondingChipIndex);
553+
} else {
554+
this._keyManager.updateActiveItemIndex(correspondingChipIndex);
555+
}
556+
551557
}
552558
}
553559
}

0 commit comments

Comments
 (0)