@@ -149,7 +149,7 @@ interface MatFormFieldControl<T> extends _MatFormFieldControl<T> {}
149149 // Note that these classes reuse the same names as the non-MDC version, because they can be
150150 // considered a public API since custom form controls may use them to style themselves.
151151 // See https://github.com/angular/components/pull/20502#discussion_r486124901.
152- '[class.mat-form-field-invalid]' : '_control.errorState' ,
152+ '[class.mat-form-field-invalid]' : '_control.errorState || otherFormFieldControlsErrorState ' ,
153153 '[class.mat-form-field-disabled]' : '_control.disabled' ,
154154 '[class.mat-form-field-autofilled]' : '_control.autofilled' ,
155155 '[class.mat-form-field-appearance-fill]' : 'appearance == "fill"' ,
@@ -219,6 +219,9 @@ export class MatFormField
219219 } ) ;
220220
221221 @ContentChild ( _MatFormFieldControl ) _formFieldControl : MatFormFieldControl < any > ;
222+ @ContentChildren ( _MatFormFieldControl , { descendants : true } ) _formFieldControls : QueryList <
223+ MatFormFieldControl < any >
224+ > ;
222225 @ContentChildren ( MAT_PREFIX , { descendants : true } ) _prefixChildren : QueryList < MatPrefix > ;
223226 @ContentChildren ( MAT_SUFFIX , { descendants : true } ) _suffixChildren : QueryList < MatSuffix > ;
224227 @ContentChildren ( MAT_ERROR , { descendants : true } ) _errorChildren : QueryList < MatError > ;
@@ -327,12 +330,23 @@ export class MatFormField
327330 this . _explicitFormFieldControl = value ;
328331 }
329332
333+ /** Gets the other form field controls if any */
334+ get otherFormFieldControls ( ) : MatFormFieldControl < any > [ ] {
335+ return this . _formFieldControls . filter ( control => control . id !== this . _control . id ) ;
336+ }
337+
338+ /** Gets the error state of other form field controls if any */
339+ get otherFormFieldControlsErrorState ( ) : boolean {
340+ return this . otherFormFieldControls . some ( control => control . errorState ) ;
341+ }
342+
330343 private _destroyed = new Subject < void > ( ) ;
331344 private _isFocused : boolean | null = null ;
332345 private _explicitFormFieldControl : MatFormFieldControl < any > ;
333346 private _previousControl : MatFormFieldControl < unknown > | null = null ;
334347 private _previousControlValidatorFn : ValidatorFn | null = null ;
335348 private _stateChanges : Subscription | undefined ;
349+ private _otherControlStateChanges : Subscription | undefined ;
336350 private _valueChanges : Subscription | undefined ;
337351 private _describedByChanges : Subscription | undefined ;
338352 protected readonly _animationsDisabled = _animationsDisabled ( ) ;
@@ -412,6 +426,7 @@ export class MatFormField
412426 ngOnDestroy ( ) {
413427 this . _outlineLabelOffsetResizeObserver ?. disconnect ( ) ;
414428 this . _stateChanges ?. unsubscribe ( ) ;
429+ this . _otherControlStateChanges ?. unsubscribe ( ) ;
415430 this . _valueChanges ?. unsubscribe ( ) ;
416431 this . _describedByChanges ?. unsubscribe ( ) ;
417432 this . _destroyed . next ( ) ;
@@ -466,6 +481,16 @@ export class MatFormField
466481 this . _changeDetectorRef . markForCheck ( ) ;
467482 } ) ;
468483
484+ if ( this . otherFormFieldControls . length ) {
485+ this . _otherControlStateChanges ?. unsubscribe ( ) ;
486+ this . otherFormFieldControls . map ( control => {
487+ const subscription = control . stateChanges . subscribe ( ( ) =>
488+ this . _changeDetectorRef . markForCheck ( ) ,
489+ ) ;
490+ this . _otherControlStateChanges ?. add ( subscription ) ;
491+ } ) ;
492+ }
493+
469494 // Updating the `aria-describedby` touches the DOM. Only do it if it actually needs to change.
470495 this . _describedByChanges ?. unsubscribe ( ) ;
471496 this . _describedByChanges = control . stateChanges
@@ -632,7 +657,9 @@ export class MatFormField
632657
633658 /** Gets the type of subscript message to render (error or hint). */
634659 _getSubscriptMessageType ( ) : 'error' | 'hint' {
635- return this . _errorChildren && this . _errorChildren . length > 0 && this . _control . errorState
660+ return this . _errorChildren &&
661+ this . _errorChildren . length > 0 &&
662+ ( this . _control . errorState || this . otherFormFieldControlsErrorState )
636663 ? 'error'
637664 : 'hint' ;
638665 }
0 commit comments