Which @angular/* package(s) are the source of the bug?
forms
Is this a regression?
Yes
Description
When using the Signal Forms API in Angular v22, <input type="date"> bound via the [formField] directive automatically defaults to a dirty state (dirty() === true) immediately upon component initialization. This premature evaluation causes validation error messages and styling states to display instantly on load before any user interaction occurs.
Angular v22.x (Signal Forms)
import { Component, signal } from '@angular/core';
interface FormModel {
fromDate: string | null;
toDate: string | null;
}
@Component({
selector: 'app-date-form',
templateUrl: './date-form.component.html'
})
export class DateFormComponent {
readonly formModel: FormModel = {
fromDate: '',
toDate: '',
};
readonly model = signal(this.formModel);
readonly f = form(this.model, (s) => {
required(s.fromDate, { message: 'required field' });
});
}
<form (submit)="onSubmit(); $event.preventDefault()" novalidate>
<div class="col-sm-6 col-md-4 col-lg-3 col-xxxl">
@let fromDtCtrl = f.fromDate();
<label class="small fw-bold text-body-secondary">FROM DATE</label>
<input
type="date"
[formField]="f.fromDate"
class="form-control form-control-sm"
[class.is-invalid]="fromDtCtrl.invalid() && (fromDtCtrl.touched() || fromDtCtrl.dirty())"
[class.is-valid]="fromDtCtrl.valid() && (fromDtCtrl.touched() || fromDtCtrl.dirty())"
/>
@if (fromDtCtrl.invalid() && (fromDtCtrl.touched() || fromDtCtrl.dirty())) {
<div class="invalid-feedback small m-0">
@for (err of fromDtCtrl.errors(); track err.kind) {
@if (err?.kind === 'required') { {{ err?.message }} }
@else if (err?.kind === 'minDate') { {{ err?.message }} }
@else if (err?.kind === 'maxDate') { {{ err?.message }} }
@else if (err.kind == 'parse') { invalid date }
@else { {{ err.kind }} error }
}
</div>
}
</div>
</form>
Please provide a link to a minimal reproduction of the bug
No response
Please provide the exception or error you saw
Please provide the environment you discovered this bug in (run ng version)
Angular CLI : 22.0.5
Angular : 22.0.5
Node.js : 25.9.0 (Unsupported)
Package Manager : npm 11.12.1
Operating System : win32 x64
┌───────────────────────────┬───────────────────┬───────────────────┐
│ Package │ Installed Version │ Requested Version │
├───────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build │ 22.0.5 │ ^22.0.5 │
│ @angular/cli │ 22.0.5 │ ^22.0.5 │
│ @angular/common │ 22.0.5 │ ^22.0.5 │
│ @angular/compiler │ 22.0.5 │ ^22.0.5 │
│ @angular/compiler-cli │ 22.0.5 │ ^22.0.5 │
│ @angular/core │ 22.0.5 │ ^22.0.5 │
│ @angular/forms │ 22.0.5 │ ^22.0.5 │
│ @angular/localize │ 22.0.5 │ ^22.0.5 │
│ @angular/platform-browser │ 22.0.5 │ ^22.0.5 │
│ @angular/router │ 22.0.5 │ ^22.0.5 │
│ rxjs │ 7.8.2 │ ~7.8.0 │
│ typescript │ 6.0.3 │ ~6.0.3 │
│ vitest │ 4.1.9 │ ^4.0.8 │
Anything else?
No response
Which @angular/* package(s) are the source of the bug?
forms
Is this a regression?
Yes
Description
When using the Signal Forms API in Angular v22,
<input type="date">bound via the [formField] directive automatically defaults to a dirty state (dirty() === true) immediately upon component initialization. This premature evaluation causes validation error messages and styling states to display instantly on load before any user interaction occurs.Angular v22.x (Signal Forms)
import { Component, signal } from '@angular/core'; interface FormModel { fromDate: string | null; toDate: string | null; } @Component({ selector: 'app-date-form', templateUrl: './date-form.component.html' }) export class DateFormComponent { readonly formModel: FormModel = { fromDate: '', toDate: '', }; readonly model = signal(this.formModel); readonly f = form(this.model, (s) => { required(s.fromDate, { message: 'required field' }); }); }Please provide a link to a minimal reproduction of the bug
No response
Please provide the exception or error you saw
Please provide the environment you discovered this bug in (run
ng version)Anything else?
No response