Skip to content

Commit 8eae162

Browse files
authored
fix(material/form-field): ensure that focused classes are in sync (angular#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.
1 parent 5d44cd7 commit 8eae162

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)