Skip to content

Commit bab3b98

Browse files
authored
refactor(material/core): no longer define stateChanges in mixinErrorState (#22875)
The error state mixin provided in `@angular/material/core` currently defines the `stateChanges` class member as part of the mixin. This is unexpected as consumers might deal with the `stateChanges` member differently. e.g. in some components the `stateChanges` field is intended to show up in the docs, or the JSDoc descripton varies. e.g. the observable could emit whenever form-field state changes, and it should be updated, or it emits always when something changes (e.g. even a component input which is not relevant for the form-field control). In general we want to avoid this member being defined in the mixin as the mixin is rather about the error state, and not defining a subject that can emit whenever "state" changes. BREAKING CHANGE: Previously the `mixinErrorState` mixin function defined a class member for `stateChanges`. This is no longer the case, and consumers need to provide the `stateChanges` class member themselves.
1 parent 761f5fd commit bab3b98

File tree

7 files changed

+58
-15
lines changed

7 files changed

+58
-15
lines changed

src/material-experimental/mdc-chips/chip-grid.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import {
4343
import {MatFormFieldControl} from '@angular/material-experimental/mdc-form-field';
4444
import {LiveAnnouncer} from '@angular/cdk/a11y';
4545
import {MatChipTextControl} from './chip-text-control';
46-
import {Observable} from 'rxjs';
46+
import {Observable, Subject} from 'rxjs';
4747
import {startWith, takeUntil} from 'rxjs/operators';
4848
import {MatChipEvent} from './chip';
4949
import {MatChipRow} from './chip-row';
@@ -64,6 +64,13 @@ export class MatChipGridChange {
6464
* @docs-private
6565
*/
6666
class MatChipGridBase extends MatChipSet {
67+
/**
68+
* Emits whenever the component state changes and should cause the parent
69+
* form-field to update. Implemented as part of `MatFormFieldControl`.
70+
* @docs-private
71+
*/
72+
readonly stateChanges = new Subject<void>();
73+
6774
constructor(
6875
liveAnnouncer: LiveAnnouncer,
6976
document: any,
@@ -72,7 +79,11 @@ class MatChipGridBase extends MatChipSet {
7279
public _defaultErrorStateMatcher: ErrorStateMatcher,
7380
public _parentForm: NgForm,
7481
public _parentFormGroup: FormGroupDirective,
75-
/** @docs-private */
82+
/**
83+
* Form control bound to the component.
84+
* Implemented as part of `MatFormFieldControl`.
85+
* @docs-private
86+
*/
7687
public ngControl: NgControl,
7788
) {
7889
super(liveAnnouncer, document, elementRef, changeDetectorRef);

src/material/chips/chip-list.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,22 @@ import {MatChipTextControl} from './chip-text-control';
4646
/** @docs-private */
4747
const _MatChipListBase = mixinErrorState(
4848
class {
49+
/**
50+
* Emits whenever the component state changes and should cause the parent
51+
* form-field to update. Implemented as part of `MatFormFieldControl`.
52+
* @docs-private
53+
*/
54+
readonly stateChanges = new Subject<void>();
55+
4956
constructor(
5057
public _defaultErrorStateMatcher: ErrorStateMatcher,
5158
public _parentForm: NgForm,
5259
public _parentFormGroup: FormGroupDirective,
53-
/** @docs-private */
60+
/**
61+
* Form control bound to the component.
62+
* Implemented as part of `MatFormFieldControl`.
63+
* @docs-private
64+
*/
5465
public ngControl: NgControl,
5566
) {}
5667
},

src/material/core/common-behaviors/error-state.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ import {AbstractConstructor, Constructor} from './constructor';
1313

1414
/** @docs-private */
1515
export interface CanUpdateErrorState {
16-
/** Emits whenever the component state changes. */
17-
readonly stateChanges: Subject<void>;
1816
/** Updates the error state based on the provided error state matcher. */
1917
updateErrorState(): void;
2018
/** Whether the component is in an error state. */
@@ -31,7 +29,12 @@ export interface HasErrorState {
3129
_parentFormGroup: FormGroupDirective;
3230
_parentForm: NgForm;
3331
_defaultErrorStateMatcher: ErrorStateMatcher;
32+
33+
// These properties are defined as per the `MatFormFieldControl` interface. Since
34+
// this mixin is commonly used with custom form-field controls, we respect the
35+
// properties (also with the public name they need according to `MatFormFieldControl`).
3436
ngControl: NgControl;
37+
stateChanges: Subject<void>;
3538
}
3639

3740
/**
@@ -45,13 +48,6 @@ export function mixinErrorState<T extends Constructor<HasErrorState>>(
4548
base: T,
4649
): CanUpdateErrorStateCtor & T {
4750
return class extends base {
48-
// This class member exists as an interop with `MatFormFieldControl` which expects
49-
// a public `stateChanges` observable to emit whenever the form field should be updated.
50-
// The description is not specifically mentioning the error state, as classes using this
51-
// mixin can/should emit an event in other cases too.
52-
/** Emits whenever the component state changes. */
53-
readonly stateChanges = new Subject<void>();
54-
5551
/** Whether the component is in an error state. */
5652
errorState: boolean = false;
5753

src/material/datepicker/date-range-input-parts.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ abstract class MatDateRangeInputPartBase<D>
7373
extends MatDatepickerInputBase<DateRange<D>>
7474
implements OnInit, DoCheck
7575
{
76-
/** @docs-private */
76+
/**
77+
* Form control bound to this input part.
78+
* @docs-private
79+
*/
7780
ngControl: NgControl;
7881

7982
/** @docs-private */

src/material/input/input.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,22 @@ let nextUniqueId = 0;
4848
/** @docs-private */
4949
const _MatInputBase = mixinErrorState(
5050
class {
51+
/**
52+
* Emits whenever the component state changes and should cause the parent
53+
* form-field to update. Implemented as part of `MatFormFieldControl`.
54+
* @docs-private
55+
*/
56+
readonly stateChanges = new Subject<void>();
57+
5158
constructor(
5259
public _defaultErrorStateMatcher: ErrorStateMatcher,
5360
public _parentForm: NgForm,
5461
public _parentFormGroup: FormGroupDirective,
55-
/** @docs-private */
62+
/**
63+
* Form control bound to the component.
64+
* Implemented as part of `MatFormFieldControl`.
65+
* @docs-private
66+
*/
5667
public ngControl: NgControl,
5768
) {}
5869
},

src/material/select/select.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,23 @@ const _MatSelectMixinBase = mixinDisableRipple(
192192
mixinDisabled(
193193
mixinErrorState(
194194
class {
195+
/**
196+
* Emits whenever the component state changes and should cause the parent
197+
* form-field to update. Implemented as part of `MatFormFieldControl`.
198+
* @docs-private
199+
*/
200+
readonly stateChanges = new Subject<void>();
201+
195202
constructor(
196203
public _elementRef: ElementRef,
197204
public _defaultErrorStateMatcher: ErrorStateMatcher,
198205
public _parentForm: NgForm,
199206
public _parentFormGroup: FormGroupDirective,
207+
/**
208+
* Form control bound to the component.
209+
* Implemented as part of `MatFormFieldControl`.
210+
* @docs-private
211+
*/
200212
public ngControl: NgControl,
201213
) {}
202214
},

tools/public_api_guard/material/core.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ export interface CanDisableRipple {
7777
export interface CanUpdateErrorState {
7878
errorState: boolean;
7979
errorStateMatcher: ErrorStateMatcher;
80-
readonly stateChanges: Subject<void>;
8180
updateErrorState(): void;
8281
}
8382

0 commit comments

Comments
 (0)