Skip to content

Commit 6c9c3fe

Browse files
crisbetotinayuangao
authored andcommitted
fix(select): don't blur label when trigger is blurred while the panel is opened (#11537)
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 d083d76 commit 6c9c3fe

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

src/lib/select/select.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,26 @@ describe('MatSelect', () => {
10711071
expect(document.querySelectorAll('.cdk-overlay-container mat-option').length)
10721072
.toBeGreaterThan(0, 'Expected at least one option to be rendered.');
10731073
}));
1074+
1075+
it('should not consider itself as blurred if the trigger loses focus while the ' +
1076+
'panel is still open', fakeAsync(() => {
1077+
const selectElement = fixture.nativeElement.querySelector('.mat-select');
1078+
const selectInstance = fixture.componentInstance.select;
1079+
1080+
dispatchFakeEvent(selectElement, 'focus');
1081+
fixture.detectChanges();
1082+
1083+
expect(selectInstance.focused).toBe(true, 'Expected select to be focused.');
1084+
1085+
selectInstance.open();
1086+
fixture.detectChanges();
1087+
flush();
1088+
dispatchFakeEvent(selectElement, 'blur');
1089+
fixture.detectChanges();
1090+
1091+
expect(selectInstance.focused).toBe(true, 'Expected select element to remain focused.');
1092+
}));
1093+
10741094
});
10751095

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

src/lib/select/select.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,17 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
310310
private _disableOptionCentering: boolean = false;
311311

312312
/** Whether the select is focused. */
313-
focused: boolean = false;
313+
get focused(): boolean {
314+
return this._focused || this._panelOpen;
315+
}
316+
/**
317+
* @deprecated Setter to be removed as this property is intended to be readonly.
318+
* @deletion-target 8.0.0
319+
*/
320+
set focused(value: boolean) {
321+
this._focused = value;
322+
}
323+
private _focused = false;
314324

315325
/** A name for this control that can be used by `mat-form-field`. */
316326
controlType = 'mat-select';
@@ -718,7 +728,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
718728

719729
_onFocus() {
720730
if (!this.disabled) {
721-
this.focused = true;
731+
this._focused = true;
722732
this.stateChanges.next();
723733
}
724734
}
@@ -728,7 +738,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
728738
* "blur" to the panel when it opens, causing a false positive.
729739
*/
730740
_onBlur() {
731-
this.focused = false;
741+
this._focused = false;
732742

733743
if (!this.disabled && !this.panelOpen) {
734744
this._onTouched();

0 commit comments

Comments
 (0)