Skip to content

Commit 6cf8081

Browse files
committed
fix(select): don't blur label when trigger is blurred while the panel is opened
Considers a select as focused as long as a its panel is open, even if the trigger loses focus. This avoids cases where the label can be seen blinking in the background when an option is toggled in multi-select mode.
1 parent 9062640 commit 6cf8081

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

src/lib/select/select.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,26 @@ describe('MatSelect', () => {
10471047
expect(document.querySelectorAll('.cdk-overlay-container mat-option').length)
10481048
.toBeGreaterThan(0, 'Expected at least one option to be rendered.');
10491049
}));
1050+
1051+
it('should not consider itself as blurred if the trigger loses focus while the ' +
1052+
'panel is still open', fakeAsync(() => {
1053+
const selectElement = fixture.nativeElement.querySelector('.mat-select');
1054+
const selectInstance = fixture.componentInstance.select;
1055+
1056+
dispatchFakeEvent(selectElement, 'focus');
1057+
fixture.detectChanges();
1058+
1059+
expect(selectInstance.focused).toBe(true, 'Expected select to be focused.');
1060+
1061+
selectInstance.open();
1062+
fixture.detectChanges();
1063+
flush();
1064+
dispatchFakeEvent(selectElement, 'blur');
1065+
fixture.detectChanges();
1066+
1067+
expect(selectInstance.focused).toBe(true, 'Expected select element to remain focused.');
1068+
}));
1069+
10501070
});
10511071

10521072
describe('selection logic', () => {

src/lib/select/select.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,10 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
299299
private _disableOptionCentering: boolean = false;
300300

301301
/** Whether the select is focused. */
302-
focused: boolean = false;
302+
get focused(): boolean {
303+
return this._focused || this._panelOpen;
304+
}
305+
private _focused = false;
303306

304307
/** A name for this control that can be used by `mat-form-field`. */
305308
controlType = 'mat-select';
@@ -701,7 +704,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
701704

702705
_onFocus() {
703706
if (!this.disabled) {
704-
this.focused = true;
707+
this._focused = true;
705708
this.stateChanges.next();
706709
}
707710
}
@@ -711,7 +714,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
711714
* "blur" to the panel when it opens, causing a false positive.
712715
*/
713716
_onBlur() {
714-
this.focused = false;
717+
this._focused = false;
715718

716719
if (!this.disabled && !this.panelOpen) {
717720
this._onTouched();

0 commit comments

Comments
 (0)