Skip to content

Commit 088f0a8

Browse files
authored
refactor(material/form-field): allow AbstractControlDirective as MatFormFieldControl.ngControl (angular#18206)
Allows for an `AbstractControlDirective` to be passed in as the `MatFormFieldControl.ngControl`. The advantage of passing in the abstract control directive is that it allows both form controls and form groups. This is necessary for the date range picker.
1 parent c176670 commit 088f0a8

File tree

4 files changed

+22
-15
lines changed

4 files changed

+22
-15
lines changed

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

+8-5
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
ViewChild,
2828
ViewEncapsulation,
2929
} from '@angular/core';
30-
import {NgControl} from '@angular/forms';
30+
import {AbstractControlDirective} from '@angular/forms';
3131
import {ThemePalette} from '@angular/material-experimental/mdc-core';
3232
import {
3333
getMatFormFieldDuplicatedHintError,
@@ -628,10 +628,13 @@ export class MatFormField
628628
return this._control.shouldLabelFloat || this._shouldAlwaysFloat();
629629
}
630630

631-
/** Determines whether a class from the NgControl should be forwarded to the host element. */
632-
_shouldForward(prop: keyof NgControl): boolean {
633-
const ngControl = this._control ? this._control.ngControl : null;
634-
return ngControl && ngControl[prop];
631+
/**
632+
* Determines whether a class from the AbstractControlDirective
633+
* should be forwarded to the host element.
634+
*/
635+
_shouldForward(prop: keyof AbstractControlDirective): boolean {
636+
const control = this._control ? this._control.ngControl : null;
637+
return control && control[prop];
635638
}
636639

637640
/** Determines whether to display hints or errors. */

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {Observable} from 'rxjs';
10-
import {NgControl} from '@angular/forms';
10+
import {AbstractControlDirective, NgControl} from '@angular/forms';
1111
import {Directive} from '@angular/core';
1212

1313
/** An interface which allows a control to work inside of a `MatFormField`. */
@@ -28,8 +28,8 @@ export abstract class MatFormFieldControl<T> {
2828
/** The placeholder for this control. */
2929
readonly placeholder: string;
3030

31-
/** Gets the NgControl for this control. */
32-
readonly ngControl: NgControl | null;
31+
/** Gets the AbstractControlDirective for this control. */
32+
readonly ngControl: NgControl | AbstractControlDirective | null;
3333

3434
/** Whether the control is focused. */
3535
readonly focused: boolean;

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

+8-5
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import {MatPlaceholder} from './placeholder';
4545
import {MAT_PREFIX, MatPrefix} from './prefix';
4646
import {MAT_SUFFIX, MatSuffix} from './suffix';
4747
import {Platform} from '@angular/cdk/platform';
48-
import {NgControl} from '@angular/forms';
48+
import {AbstractControlDirective} from '@angular/forms';
4949
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
5050

5151
let nextUniqueId = 0;
@@ -393,10 +393,13 @@ export class MatFormField
393393
this._destroyed.complete();
394394
}
395395

396-
/** Determines whether a class from the NgControl should be forwarded to the host element. */
397-
_shouldForward(prop: keyof NgControl): boolean {
398-
const ngControl = this._control ? this._control.ngControl : null;
399-
return ngControl && ngControl[prop];
396+
/**
397+
* Determines whether a class from the AbstractControlDirective
398+
* should be forwarded to the host element.
399+
*/
400+
_shouldForward(prop: keyof AbstractControlDirective): boolean {
401+
const control = this._control ? this._control.ngControl : null;
402+
return control && control[prop];
400403
}
401404

402405
_hasPlaceholder() {

tools/public_api_guard/material/form-field.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
```ts
66

77
import { _AbstractConstructor } from '@angular/material/core';
8+
import { AbstractControlDirective } from '@angular/forms';
89
import { AfterContentChecked } from '@angular/core';
910
import { AfterContentInit } from '@angular/core';
1011
import { AfterViewInit } from '@angular/core';
@@ -132,7 +133,7 @@ export class MatFormField extends _MatFormFieldBase implements AfterContentInit,
132133
// (undocumented)
133134
_prefixChildren: QueryList<MatPrefix>;
134135
_shouldAlwaysFloat(): boolean;
135-
_shouldForward(prop: keyof NgControl): boolean;
136+
_shouldForward(prop: keyof AbstractControlDirective): boolean;
136137
// (undocumented)
137138
_shouldLabelFloat(): boolean;
138139
_subscriptAnimationState: string;
@@ -163,7 +164,7 @@ export abstract class MatFormFieldControl<T> {
163164
readonly errorState: boolean;
164165
readonly focused: boolean;
165166
readonly id: string;
166-
readonly ngControl: NgControl | null;
167+
readonly ngControl: NgControl | AbstractControlDirective | null;
167168
abstract onContainerClick(event: MouseEvent): void;
168169
readonly placeholder: string;
169170
readonly required: boolean;

0 commit comments

Comments
 (0)