Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/material/chips/chip-grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
NgForm,
Validators,
} from '@angular/forms';
import {FORM_FIELD} from '@angular/forms/signals';
import {_ErrorStateTracker, ErrorStateMatcher} from '../core';
import {MatFormFieldControl} from '../form-field';
import {merge, Observable, Subject} from 'rxjs';
Expand Down Expand Up @@ -258,14 +259,15 @@ export class MatChipGrid
const parentForm = inject(NgForm, {optional: true});
const parentFormGroup = inject(FormGroupDirective, {optional: true});
const defaultErrorStateMatcher = inject(ErrorStateMatcher);
const formField = inject(FORM_FIELD, {optional: true, self: true});

if (this.ngControl) {
this.ngControl.valueAccessor = this;
}

this._errorStateTracker = new _ErrorStateTracker(
defaultErrorStateMatcher,
this.ngControl,
formField || this.ngControl,
parentFormGroup,
parentForm,
this.stateChanges,
Expand Down Expand Up @@ -492,7 +494,7 @@ export class MatChipGrid
this.stateChanges.next();
}

protected override _redirectDestroyedChipFocus() {
protected override _redirectDestroyedChipFocus() {
if (this._lastDestroyedFocusedChipIndex === null) {
return;
}
Expand All @@ -501,8 +503,7 @@ export class MatChipGrid

// If there are no chips left, or the set focuses the input,
// clear the active item silently to prevent stale references.
if (!this._chips.length ||
(this._chips.length === 1 && this._chips.first.disabled)) {
if (!this._chips.length || (this._chips.length === 1 && this._chips.first.disabled)) {
this._keyManager.updateActiveItem(-1);
}
}
Expand Down
32 changes: 11 additions & 21 deletions src/material/core/common-behaviors/error-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,31 +57,21 @@ export class _ErrorStateTracker {
/** Updates the error state based on the provided error state matcher. */
updateErrorState() {
const oldState = this.errorState;
const matcher = this.matcher || this._defaultMatcher;
let newState: boolean;

if (this.formField) {
if (
(typeof ngDevMode === 'undefined' || ngDevMode) &&
matcher &&
!matcher.isSignalErrorState
) {
throw new Error(
'Current error state matcher does not support signal forms. ' +
'Please implement the `isSignalErrorState` method.',
);
}

newState = matcher?.isSignalErrorState?.(this.formField.field()) ?? false;
} else {
const parent = this._parentFormGroup || this._parentForm;
const control = this.ngControl ? (this.ngControl.control as AbstractControl) : null;
newState = matcher?.isErrorState(control, parent) ?? false;
}
const newState = this._getCurrentErrorState(this.matcher || this._defaultMatcher);

if (newState !== oldState) {
this.errorState = newState;
this._stateChanges.next();
}
}

private _getCurrentErrorState(matcher: ErrorStateMatcher | undefined): boolean {
if (this.formField && matcher?.isSignalErrorState) {
return matcher.isSignalErrorState(this.formField.field()) ?? false;
}

const parent = this._parentFormGroup || this._parentForm;
const control = this.ngControl ? (this.ngControl.control as AbstractControl) : null;
return matcher?.isErrorState(control, parent) ?? false;
}
}
6 changes: 6 additions & 0 deletions src/material/datepicker/date-range-input-parts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
ValidatorFn,
Validators,
} from '@angular/forms';
import {FORM_FIELD} from '@angular/forms/signals';
import {ErrorStateMatcher, _ErrorStateTracker} from '../core';
import {_computeAriaAccessibleName} from './aria-accessible-name';
import {DateRange, DateSelectionModelChange} from './date-selection-model';
Expand Down Expand Up @@ -103,6 +104,11 @@ abstract class MatDateRangeInputPartBase<D>
// everything has been resolved.
const ngControl = this._injector.get(NgControl, null, {optional: true, self: true});

this._errorStateTracker.formField = this._injector.get(FORM_FIELD, null, {
optional: true,
self: true,
});

if (ngControl) {
this.ngControl = ngControl;
this._errorStateTracker.ngControl = ngControl;
Expand Down
4 changes: 3 additions & 1 deletion src/material/input/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
} from '@angular/core';
import {_IdGenerator} from '@angular/cdk/a11y';
import {FormGroupDirective, NgControl, NgForm, Validators} from '@angular/forms';
import {FORM_FIELD} from '@angular/forms/signals';
import {ErrorStateMatcher, _ErrorStateTracker} from '../core';
import {MatFormFieldControl, MatFormField, MAT_FORM_FIELD} from '../form-field';
import {Subject} from 'rxjs';
Expand Down Expand Up @@ -299,6 +300,7 @@ export class MatInput
const parentFormGroup = inject(FormGroupDirective, {optional: true});
const defaultErrorStateMatcher = inject(ErrorStateMatcher);
const accessor = inject(MAT_INPUT_VALUE_ACCESSOR, {optional: true, self: true});
const formField = inject(FORM_FIELD, {optional: true, self: true});

const element = this._elementRef.nativeElement;
const nodeName = element.nodeName.toLowerCase();
Expand Down Expand Up @@ -331,7 +333,7 @@ export class MatInput

this._errorStateTracker = new _ErrorStateTracker(
defaultErrorStateMatcher,
this.ngControl,
formField || this.ngControl,
parentFormGroup,
parentForm,
this.stateChanges,
Expand Down
4 changes: 3 additions & 1 deletion src/material/select/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import {
Validators,
} from '@angular/forms';
import {_getEventTarget} from '@angular/cdk/platform';
import {FORM_FIELD} from '@angular/forms/signals';
import {
_animationsDisabled,
_countGroupLabelsBeforeOption,
Expand Down Expand Up @@ -595,6 +596,7 @@ export class MatSelect
const parentFormGroup = inject(FormGroupDirective, {optional: true});
const tabIndex = inject(new HostAttributeToken('tabindex'), {optional: true});
const defaultPopoverConfig = inject(OVERLAY_DEFAULT_CONFIG, {optional: true});
const formField = inject(FORM_FIELD, {optional: true, self: true});

if (this.ngControl) {
// Note: we provide the value accessor through here, instead of
Expand All @@ -610,7 +612,7 @@ export class MatSelect

this._errorStateTracker = new _ErrorStateTracker(
defaultErrorStateMatcher,
this.ngControl,
formField || this.ngControl,
parentFormGroup,
parentForm,
this.stateChanges,
Expand Down
Loading