Skip to content

Commit 7aa5e0b

Browse files
committed
fix(material/form-field): ensure that focused classes are in sync (#31568)
This is something that showed up in some internal tests a while ago. Because we set `mat-focused` through a host binding while `mdc-text-field--focused` is set through direct DOM manipulation, nothing guarantees that they'll be in sync and in some internal tests they aren't. These changes sync both of them up from the same place. (cherry picked from commit 8eae162)
1 parent 6ecb1a7 commit 7aa5e0b

File tree

1 file changed

+7
-9
lines changed

1 file changed

+7
-9
lines changed

src/material/form-field/form-field.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ interface MatFormFieldControl<T> extends _MatFormFieldControl<T> {}
160160
'[class.mat-form-field-appearance-fill]': 'appearance == "fill"',
161161
'[class.mat-form-field-appearance-outline]': 'appearance == "outline"',
162162
'[class.mat-form-field-hide-placeholder]': '_hasFloatingLabel() && !_shouldLabelFloat()',
163-
'[class.mat-focused]': '_control.focused',
164163
'[class.mat-primary]': 'color !== "accent" && color !== "warn"',
165164
'[class.mat-accent]': 'color === "accent"',
166165
'[class.mat-warn]': 'color === "warn"',
@@ -340,6 +339,7 @@ export class MatFormField
340339
private _stateChanges: Subscription | undefined;
341340
private _valueChanges: Subscription | undefined;
342341
private _describedByChanges: Subscription | undefined;
342+
private _outlineLabelOffsetResizeObserver: ResizeObserver | null = null;
343343
protected readonly _animationsDisabled = _animationsDisabled();
344344

345345
constructor(...args: unknown[]);
@@ -544,27 +544,25 @@ export class MatFormField
544544
}
545545

546546
private _updateFocusState() {
547+
const controlFocused = this._control.focused;
548+
547549
// Usually the MDC foundation would call "activateFocus" and "deactivateFocus" whenever
548550
// certain DOM events are emitted. This is not possible in our implementation of the
549551
// form field because we support abstract form field controls which are not necessarily
550552
// of type input, nor do we have a reference to a native form field control element. Instead
551553
// we handle the focus by checking if the abstract form field control focused state changes.
552-
if (this._control.focused && !this._isFocused) {
554+
if (controlFocused && !this._isFocused) {
553555
this._isFocused = true;
554556
this._lineRipple?.activate();
555-
} else if (!this._control.focused && (this._isFocused || this._isFocused === null)) {
557+
} else if (!controlFocused && (this._isFocused || this._isFocused === null)) {
556558
this._isFocused = false;
557559
this._lineRipple?.deactivate();
558560
}
559561

560-
this._textField?.nativeElement.classList.toggle(
561-
'mdc-text-field--focused',
562-
this._control.focused,
563-
);
562+
this._elementRef.nativeElement.classList.toggle('mat-focused', controlFocused);
563+
this._textField?.nativeElement.classList.toggle('mdc-text-field--focused', controlFocused);
564564
}
565565

566-
private _outlineLabelOffsetResizeObserver: ResizeObserver | null = null;
567-
568566
/**
569567
* The floating label in the docked state needs to account for prefixes. The horizontal offset
570568
* is calculated whenever the appearance changes to `outline`, the prefixes change, or when the

0 commit comments

Comments
 (0)