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:
Kristiyan Kostadinov
2018-01-23 16:24:08 +01:00
committed by Jeremy Elbourn
parent a6f9fc25d2
commit 9dc43de540
2 changed files with 24 additions and 4 deletions
+19
View File
@@ -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;
+5 -4
View File
@@ -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();
}
});