Skip to content

Commit cfaf552

Browse files
committed
fix(material/form-field): add hasFloatingLabel input and update classes if mat-label is added and removed dynamically
Currently, when `mat-Label` is added dynamically initially its not visible in DOM, this fix will add/remove classes for the same. Fixes #29939
1 parent dac7bc8 commit cfaf552

File tree

4 files changed

+41
-11
lines changed

4 files changed

+41
-11
lines changed

Diff for: goldens/material/form-field/index.api.md

+2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ import * as i2 from '@angular/cdk/observers';
1616
import { InjectionToken } from '@angular/core';
1717
import { NgControl } from '@angular/forms';
1818
import { Observable } from 'rxjs';
19+
import { OnChanges } from '@angular/core';
1920
import { OnDestroy } from '@angular/core';
2021
import { QueryList } from '@angular/core';
22+
import { SimpleChanges } from '@angular/core';
2123

2224
// @public
2325
export type FloatLabelType = 'always' | 'auto';

Diff for: goldens/material/input/index.api.md

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { OnChanges } from '@angular/core';
2525
import { OnDestroy } from '@angular/core';
2626
import { Platform } from '@angular/cdk/platform';
2727
import { QueryList } from '@angular/core';
28+
import { SimpleChanges } from '@angular/core';
2829
import { Subject } from 'rxjs';
2930
import { WritableSignal } from '@angular/core';
3031

Diff for: src/material/form-field/directives/notched-outline.ts

+25-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {
1313
ElementRef,
1414
Input,
1515
NgZone,
16+
OnChanges,
17+
SimpleChanges,
1618
ViewChild,
1719
ViewEncapsulation,
1820
inject,
@@ -36,22 +38,30 @@ import {
3638
changeDetection: ChangeDetectionStrategy.OnPush,
3739
encapsulation: ViewEncapsulation.None,
3840
})
39-
export class MatFormFieldNotchedOutline implements AfterViewInit {
41+
export class MatFormFieldNotchedOutline implements AfterViewInit, OnChanges {
4042
private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
4143
private _ngZone = inject(NgZone);
4244

4345
/** Whether the notch should be opened. */
4446
@Input('matFormFieldNotchedOutlineOpen') open: boolean = false;
4547

48+
/** Whether the floating label is present. */
49+
@Input('matFormFieldHasFloatingLabel') hasFloatingLabel: boolean = false;
50+
4651
@ViewChild('notch') _notch: ElementRef;
4752

53+
/** Gets the HTML element for the floating label. */
54+
get element(): HTMLElement {
55+
return this._elementRef.nativeElement;
56+
}
57+
4858
constructor(...args: unknown[]);
4959
constructor() {}
5060

5161
ngAfterViewInit(): void {
52-
const label = this._elementRef.nativeElement.querySelector<HTMLElement>('.mdc-floating-label');
62+
const label = this.element.querySelector<HTMLElement>('.mdc-floating-label');
5363
if (label) {
54-
this._elementRef.nativeElement.classList.add('mdc-notched-outline--upgraded');
64+
this.element.classList.add('mdc-notched-outline--upgraded');
5565

5666
if (typeof requestAnimationFrame === 'function') {
5767
label.style.transitionDuration = '0s';
@@ -60,7 +70,18 @@ export class MatFormFieldNotchedOutline implements AfterViewInit {
6070
});
6171
}
6272
} else {
63-
this._elementRef.nativeElement.classList.add('mdc-notched-outline--no-label');
73+
this.element.classList.add('mdc-notched-outline--no-label');
74+
}
75+
}
76+
77+
ngOnChanges(changes: SimpleChanges) {
78+
if (
79+
changes['hasFloatingLabel'] &&
80+
this.hasFloatingLabel &&
81+
this.element.classList.contains('mdc-notched-outline--no-label')
82+
) {
83+
this.element.classList.add('mdc-notched-outline--upgraded');
84+
this.element.classList.remove('mdc-notched-outline--no-label');
6485
}
6586
}
6687

Diff for: src/material/form-field/form-field.html

+13-7
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@
5050
}
5151
<div class="mat-mdc-form-field-flex">
5252
@if (_hasOutline()) {
53-
<div matFormFieldNotchedOutline [matFormFieldNotchedOutlineOpen]="_shouldLabelFloat()">
53+
<div
54+
matFormFieldNotchedOutline
55+
[matFormFieldNotchedOutlineOpen]="_shouldLabelFloat()"
56+
[matFormFieldHasFloatingLabel]="_hasFloatingLabel()"
57+
>
5458
@if (!_forceDisplayInfixLabel()) {
5559
<ng-template [ngTemplateOutlet]="labelTemplate"></ng-template>
5660
}
@@ -96,8 +100,8 @@
96100
</div>
97101

98102
<div
99-
class="mat-mdc-form-field-subscript-wrapper mat-mdc-form-field-bottom-align"
100-
[class.mat-mdc-form-field-subscript-dynamic-size]="subscriptSizing === 'dynamic'"
103+
class="mat-mdc-form-field-subscript-wrapper mat-mdc-form-field-bottom-align"
104+
[class.mat-mdc-form-field-subscript-dynamic-size]="subscriptSizing === 'dynamic'"
101105
>
102106
@let subscriptMessageType = _getSubscriptMessageType();
103107

@@ -106,10 +110,12 @@
106110
as having it appear post render will not consistently work. We also do not want to add
107111
additional divs as it causes styling regressions.
108112
-->
109-
<div aria-atomic="true" aria-live="polite"
110-
[class.mat-mdc-form-field-error-wrapper]="subscriptMessageType === 'error'"
111-
[class.mat-mdc-form-field-hint-wrapper]="subscriptMessageType === 'hint'"
112-
>
113+
<div
114+
aria-atomic="true"
115+
aria-live="polite"
116+
[class.mat-mdc-form-field-error-wrapper]="subscriptMessageType === 'error'"
117+
[class.mat-mdc-form-field-hint-wrapper]="subscriptMessageType === 'hint'"
118+
>
113119
@switch (subscriptMessageType) {
114120
@case ('error') {
115121
<ng-content select="mat-error, [matError]"></ng-content>

0 commit comments

Comments
 (0)