Skip to content

Commit 7409bd6

Browse files
authored
fix(autocomplete): restore focus after emitting option selected event (#18707)
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 33a07d2 commit 7409bd6

File tree

2 files changed

+29
-5
lines changed

2 files changed

+29
-5
lines changed

src/material/autocomplete/autocomplete-trigger.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -556,12 +556,14 @@ export abstract class _MatAutocompleteTriggerBase
556556
* stemmed from the user.
557557
*/
558558
private _setValueAndClose(event: MatOptionSelectionChange | null): void {
559-
if (event && event.source) {
560-
this._clearPreviousSelectedOption(event.source);
561-
this._setTriggerValue(event.source.value);
562-
this._onChange(event.source.value);
559+
const source = event && event.source;
560+
561+
if (source) {
562+
this._clearPreviousSelectedOption(source);
563+
this._setTriggerValue(source.value);
564+
this._onChange(source.value);
565+
this.autocomplete._emitSelectEvent(source);
563566
this._element.nativeElement.focus();
564-
this.autocomplete._emitSelectEvent(event.source);
565567
}
566568

567569
this.closePanel();

src/material/autocomplete/autocomplete.spec.ts

+22
Original file line numberDiff line numberDiff line change
@@ -2872,6 +2872,28 @@ describe('MatAutocomplete', () => {
28722872
expect(event.option.value).toBe('Washington');
28732873
}));
28742874

2875+
it('should refocus the input after the selection event is emitted', fakeAsync(() => {
2876+
const events: string[] = [];
2877+
const fixture = createComponent(AutocompleteWithSelectEvent);
2878+
fixture.detectChanges();
2879+
const input = fixture.nativeElement.querySelector('input');
2880+
2881+
fixture.componentInstance.trigger.openPanel();
2882+
zone.simulateZoneExit();
2883+
fixture.detectChanges();
2884+
2885+
const options =
2886+
overlayContainerElement.querySelectorAll('mat-option') as NodeListOf<HTMLElement>;
2887+
spyOn(input, 'focus').and.callFake(() => events.push('focus'));
2888+
fixture.componentInstance.optionSelected.and.callFake(() => events.push('select'));
2889+
2890+
options[1].click();
2891+
tick();
2892+
fixture.detectChanges();
2893+
2894+
expect(events).toEqual(['select', 'focus']);
2895+
}));
2896+
28752897
it('should emit an event when a newly-added option is selected', fakeAsync(() => {
28762898
const fixture = createComponent(AutocompleteWithSelectEvent);
28772899

0 commit comments

Comments
 (0)