Skip to content

Commit 2fd76ac

Browse files
committed
fix(autocomplete): don't reset active option if list of options changes
Currently we reset the active option whenever the list of items changes, however this means that the user's selection could be lost while they're interacting, if some items get added to the end of the list out of view (e.g. if the options are fetched via polling). These changes address the issue by only resetting the active option when the panel is opened. Fixes #16608.
1 parent 88631b9 commit 2fd76ac

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

src/material/autocomplete/autocomplete-trigger.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,6 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnChanges,
511511
// that were created, and flatten it so our stream only emits closing events...
512512
switchMap(() => {
513513
const wasOpen = this.panelOpen;
514-
this._resetActiveItem();
515514
this.autocomplete._setVisibility();
516515

517516
if (this.panelOpen) {
@@ -634,6 +633,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnChanges,
634633

635634
if (overlayRef && !overlayRef.hasAttached()) {
636635
overlayRef.attach(this._portal);
636+
this._resetActiveItem();
637637
this._closingActionsSubscription = this._subscribeToClosingActions();
638638
}
639639

src/material/autocomplete/autocomplete.spec.ts

+22
Original file line numberDiff line numberDiff line change
@@ -1755,6 +1755,28 @@ describe('MatAutocomplete', () => {
17551755
componentOptions.slice(1).forEach(option => expect(option.deselect).not.toHaveBeenCalled());
17561756
}));
17571757

1758+
it('should not reset the active item if the options list changes while open', fakeAsync(() => {
1759+
fixture.componentInstance.trigger.openPanel();
1760+
fixture.detectChanges();
1761+
zone.simulateZoneExit();
1762+
fixture.detectChanges();
1763+
1764+
const DOWN_ARROW_EVENT = createKeyboardEvent('keydown', DOWN_ARROW);
1765+
fixture.componentInstance.trigger._handleKeydown(DOWN_ARROW_EVENT);
1766+
fixture.detectChanges();
1767+
tick();
1768+
1769+
const classList = overlayContainerElement.querySelector('mat-option')!.classList;
1770+
expect(classList).toContain('mat-active', 'Expected first option to be highlighted.');
1771+
1772+
fixture.componentInstance.states.push({code: 'PR', name: 'Puerto Rico'});
1773+
fixture.detectChanges();
1774+
tick();
1775+
fixture.detectChanges();
1776+
1777+
expect(classList).toContain('mat-active', 'Expected first option to stay highlighted.');
1778+
}));
1779+
17581780
it('should be able to preselect the first option', fakeAsync(() => {
17591781
fixture.componentInstance.trigger.autocomplete.autoActiveFirstOption = true;
17601782
fixture.componentInstance.trigger.openPanel();

0 commit comments

Comments
 (0)