Skip to content

Commit 410b2a7

Browse files
crisbetommalerba
authored andcommitted
fix(autocomplete): restore focus after emitting option selected event
Currently we restore focus to the input and then we emit the change event, but we have a report that it may be making some use cases more difficult. From what I can tell, this shouldn't have much of an impact on existing users so these changes swap the order so that the focus event is last. Fixes #18650.
1 parent 8a71288 commit 410b2a7

File tree

2 files changed

+29
-5
lines changed

2 files changed

+29
-5
lines changed

src/material/autocomplete/autocomplete-trigger.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -592,12 +592,14 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, AfterViewIn
592592
* stemmed from the user.
593593
*/
594594
private _setValueAndClose(event: MatOptionSelectionChange | null): void {
595-
if (event && event.source) {
596-
this._clearPreviousSelectedOption(event.source);
597-
this._setTriggerValue(event.source.value);
598-
this._onChange(event.source.value);
595+
const source = event && event.source;
596+
597+
if (source) {
598+
this._clearPreviousSelectedOption(source);
599+
this._setTriggerValue(source.value);
600+
this._onChange(source.value);
601+
this.autocomplete._emitSelectEvent(source);
599602
this._element.nativeElement.focus();
600-
this.autocomplete._emitSelectEvent(event.source);
601603
}
602604

603605
this.closePanel();

src/material/autocomplete/autocomplete.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,6 +2468,28 @@ describe('MatAutocomplete', () => {
24682468
expect(event.option.value).toBe('Washington');
24692469
}));
24702470

2471+
it('should refocus the input after the selection event is emitted', fakeAsync(() => {
2472+
const events: string[] = [];
2473+
const fixture = createComponent(AutocompleteWithSelectEvent);
2474+
fixture.detectChanges();
2475+
const input = fixture.nativeElement.querySelector('input');
2476+
2477+
fixture.componentInstance.trigger.openPanel();
2478+
zone.simulateZoneExit();
2479+
fixture.detectChanges();
2480+
2481+
const options =
2482+
overlayContainerElement.querySelectorAll('mat-option') as NodeListOf<HTMLElement>;
2483+
spyOn(input, 'focus').and.callFake(() => events.push('focus'));
2484+
fixture.componentInstance.optionSelected.and.callFake(() => events.push('select'));
2485+
2486+
options[1].click();
2487+
tick();
2488+
fixture.detectChanges();
2489+
2490+
expect(events).toEqual(['select', 'focus']);
2491+
}));
2492+
24712493
it('should emit an event when a newly-added option is selected', fakeAsync(() => {
24722494
let fixture = createComponent(AutocompleteWithSelectEvent);
24732495

0 commit comments

Comments
 (0)