mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(select): don't restore focus unless an option was selected (#8964)
Currently `mat-select` always restores focus to its trigger whenever the panel is closed. This can be problematic, because the user might've scrolled away and restoring focus would scroll the page back up. These changes switch to only restoring focus if the user made a selection. Fixes #8915.
This commit is contained in:
committed by
Jeremy Elbourn
parent
a6f9fc25d2
commit
9dc43de540
@@ -2519,6 +2519,25 @@ describe('MatSelect', () => {
|
||||
expect(document.activeElement).toBe(select, 'Expected trigger to be focused.');
|
||||
}));
|
||||
|
||||
it('should not restore focus to the host element when clicking outside', fakeAsync(() => {
|
||||
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
|
||||
const select = fixture.debugElement.nativeElement.querySelector('mat-select');
|
||||
|
||||
fixture.detectChanges();
|
||||
fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement.click();
|
||||
fixture.detectChanges();
|
||||
flush();
|
||||
|
||||
expect(document.activeElement).toBe(select, 'Expected trigger to be focused.');
|
||||
|
||||
select.blur(); // Blur manually since the programmatic click might not do it.
|
||||
(overlayContainerElement.querySelector('.cdk-overlay-backdrop') as HTMLElement).click();
|
||||
fixture.detectChanges();
|
||||
flush();
|
||||
|
||||
expect(document.activeElement).not.toBe(select, 'Expected trigger not to be focused.');
|
||||
}));
|
||||
|
||||
it('should update the data binding before emitting the change event', fakeAsync(() => {
|
||||
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
|
||||
const instance = fixture.componentInstance;
|
||||
|
||||
@@ -298,7 +298,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
|
||||
];
|
||||
|
||||
/** Whether the select is focused. */
|
||||
focused = false;
|
||||
focused: boolean = false;
|
||||
|
||||
/** A name for this control that can be used by `mat-form-field`. */
|
||||
controlType = 'mat-select';
|
||||
@@ -548,7 +548,6 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
|
||||
this._panelOpen = false;
|
||||
this._changeDetectorRef.markForCheck();
|
||||
this._onTouched();
|
||||
this.focus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -715,8 +714,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
|
||||
* "blur" to the panel when it opens, causing a false positive.
|
||||
*/
|
||||
_onBlur() {
|
||||
this.focused = false;
|
||||
|
||||
if (!this.disabled && !this.panelOpen) {
|
||||
this.focused = false;
|
||||
this._onTouched();
|
||||
this._changeDetectorRef.markForCheck();
|
||||
this.stateChanges.next();
|
||||
@@ -844,8 +844,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
|
||||
).subscribe(event => {
|
||||
this._onSelect(event.source);
|
||||
|
||||
if (!this.multiple) {
|
||||
if (!this.multiple && this._panelOpen) {
|
||||
this.close();
|
||||
this.focus();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user