Skip to content

Commit 80fea2e

Browse files
committed
fix: address feedback
1 parent 02e17b1 commit 80fea2e

File tree

4 files changed

+37
-20
lines changed

4 files changed

+37
-20
lines changed

src/material/form-field/directives/floating-label.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
Output,
1818
} from '@angular/core';
1919
import {SharedResizeObserver} from '../shared-resize-observer';
20-
import {Platform} from '@angular/cdk/platform';
2120
import {Subscription} from 'rxjs';
2221

2322
/**
@@ -54,28 +53,31 @@ export class MatFormFieldFloatingLabel implements OnDestroy {
5453
}
5554
private _floating = false;
5655

56+
/** Whether to monitor for resize events on the floating label. */
5757
@Input()
5858
get monitorResize() {
5959
return this._monitorResize;
6060
}
6161
set monitorResize(value: boolean) {
6262
this._monitorResize = value;
6363
if (this._monitorResize) {
64-
this._startResizeObserver();
64+
this._subscribeToResize();
6565
} else {
6666
this._resizeSubscription.unsubscribe();
6767
}
6868
}
6969
private _monitorResize = false;
7070

71-
@Output() resized = new EventEmitter<void>();
72-
73-
private _ngZone = inject(NgZone);
74-
75-
private _platform = inject(Platform);
71+
/** Emits when the label is resized (if resize events are being monitored). */
72+
resized = new EventEmitter<void>();
7673

74+
/** The shared ResizeObserver. */
7775
private _resizeObserver = inject(SharedResizeObserver);
7876

77+
/** The Angular zone. */
78+
private _ngZone = inject(NgZone);
79+
80+
/** The current resize event subscription. */
7981
private _resizeSubscription = new Subscription();
8082

8183
constructor(private _elementRef: ElementRef<HTMLElement>) {}
@@ -94,6 +96,7 @@ export class MatFormFieldFloatingLabel implements OnDestroy {
9496
return this._elementRef.nativeElement;
9597
}
9698

99+
/** Handles resize events from the ResizeObserver. */
97100
private _handleResize() {
98101
// In the case where the label grows in size, the following sequence of events occurs:
99102
// 1. The label grows by 1px triggering the ResizeObserver
@@ -106,13 +109,14 @@ export class MatFormFieldFloatingLabel implements OnDestroy {
106109
setTimeout(() => this.resized.emit());
107110
}
108111

109-
private _startResizeObserver() {
110-
if (this._platform.isBrowser) {
111-
this._resizeSubscription.unsubscribe();
112+
/** Subscribes to resize events. */
113+
private _subscribeToResize() {
114+
this._resizeSubscription.unsubscribe();
115+
this._ngZone.runOutsideAngular(() => {
112116
this._resizeSubscription = this._resizeObserver
113117
.observe(this._elementRef.nativeElement, {box: 'border-box'})
114118
.subscribe(() => this._handleResize());
115-
}
119+
});
116120
}
117121
}
118122

src/material/form-field/form-field.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@
1616
-->
1717
<label matFormFieldFloatingLabel
1818
[floating]="_shouldLabelFloat()"
19-
[monitorResize]="appearance === 'outline'"
19+
[monitorResize]="_hasOutline()"
2020
*ngIf="_hasFloatingLabel()"
2121
[id]="_labelId"
2222
[attr.for]="_control.id"
23-
[attr.aria-owns]="_control.id"
24-
(resized)="_refreshOutlineNotchWidth()">
23+
[attr.aria-owns]="_control.id">
2524
<ng-content select="mat-label"></ng-content>
2625
<!--
2726
We set the required marker as a separate element, in order to make it easier to target if

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,11 @@ export class MatFormField
314314
// Because the above changes a value used in the template after it was checked, we need
315315
// to trigger CD or the change might not be reflected if there is no other CD scheduled.
316316
this._changeDetectorRef.detectChanges();
317+
this._ngZone.runOutsideAngular(() => {
318+
this._floatingLabel?.resized
319+
.pipe(takeUntil(this._destroyed))
320+
.subscribe(() => this._refreshOutlineNotchWidth());
321+
});
317322
}
318323

319324
ngAfterContentInit() {

src/material/form-field/shared-resize-observer.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import {inject, Injectable, NgZone, OnDestroy} from '@angular/core';
99
import {Observable, Subject} from 'rxjs';
1010
import {filter, shareReplay, takeUntil} from 'rxjs/operators';
11+
import {Platform} from '@angular/cdk/platform';
1112

1213
/**
1314
* Handler that logs "ResizeObserver loop limit exceeded" errors.
@@ -32,14 +33,20 @@ class SingleBoxSharedResizeObserver {
3233
/** Stream of all events from the ResizeObserver. */
3334
private _resizeSubject = new Subject<ResizeObserverEntry[]>();
3435
/** ResizeObserver used to observe element resize events. */
35-
private _resizeObserver = new ResizeObserver(entries => this._resizeSubject.next(entries));
36+
private _resizeObserver?: ResizeObserver;
3637
/** A map of elements to streams of their resize events. */
3738
private _elementObservables = new Map<Element, Observable<ResizeObserverEntry[]>>();
3839

3940
constructor(
4041
/** The box type to observe for resizes. */
4142
private _box: ResizeObserverBoxOptions,
42-
) {}
43+
/** The platform. */
44+
platform: Platform,
45+
) {
46+
if (platform.isBrowser) {
47+
this._resizeObserver = new ResizeObserver(entries => this._resizeSubject.next(entries));
48+
}
49+
}
4350

4451
/**
4552
* Gets a stream of resize events for the given element.
@@ -54,9 +61,9 @@ class SingleBoxSharedResizeObserver {
5461
const subscription = this._resizeSubject
5562
.pipe(filter(entries => entries.some(entry => entry.target === target)))
5663
.subscribe(observer);
57-
this._resizeObserver.observe(target, {box: this._box});
64+
this._resizeObserver?.observe(target, {box: this._box});
5865
return () => {
59-
this._resizeObserver.unobserve(target);
66+
this._resizeObserver?.unobserve(target);
6067
subscription.unsubscribe();
6168
this._elementObservables.delete(target);
6269
};
@@ -78,7 +85,6 @@ class SingleBoxSharedResizeObserver {
7885
this._destroyed.complete();
7986
this._resizeSubject.complete();
8087
this._elementObservables.clear();
81-
this._resizeObserver.disconnect();
8288
}
8389
}
8490

@@ -102,6 +108,9 @@ export class SharedResizeObserver implements OnDestroy {
102108
/** The Angular zone. */
103109
private _ngZone = inject(NgZone);
104110

111+
/** The platform. */
112+
private _platform = inject(Platform);
113+
105114
constructor() {
106115
if (typeof ngDevMode === 'undefined' || ngDevMode) {
107116
this._ngZone.runOutsideAngular(() => {
@@ -129,7 +138,7 @@ export class SharedResizeObserver implements OnDestroy {
129138
observe(target: Element, options?: ResizeObserverOptions): Observable<ResizeObserverEntry[]> {
130139
const box = options?.box || 'content-box';
131140
if (!this._observers.has(box)) {
132-
this._observers.set(box, new SingleBoxSharedResizeObserver(box));
141+
this._observers.set(box, new SingleBoxSharedResizeObserver(box, this._platform));
133142
}
134143
return this._observers.get(box)!.observe(target);
135144
}

0 commit comments

Comments
 (0)