From d91beadbc4f972abe45ebd7e3a545ce1e69b29fd Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 2 Dec 2025 09:33:08 +0100 Subject: [PATCH] fix(material/datepicker): do not re-assign the same forms value The datepicker ControlValueAccessor produces a new date object for each keystroke as the user is typing. When used with the interop behavior from signal forms, this can end up reverting the user's value as they're typing. These changes ignore `writeValue` calls if they pass the exact same date object. Fixes #32442. --- src/material/datepicker/datepicker-input-base.ts | 15 ++++++++++----- src/material/datepicker/datepicker.spec.ts | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/material/datepicker/datepicker-input-base.ts b/src/material/datepicker/datepicker-input-base.ts index 01de0feb77b5..35db5b67f3d1 100644 --- a/src/material/datepicker/datepicker-input-base.ts +++ b/src/material/datepicker/datepicker-input-base.ts @@ -289,22 +289,27 @@ export abstract class MatDatepickerInputBase void): void { this._cvaOnChange = fn; } - // Implemented as part of ControlValueAccessor. + /** Implemented as part of ControlValueAccessor. */ registerOnTouched(fn: () => void): void { this._onTouched = fn; } - // Implemented as part of ControlValueAccessor. + /** Implemented as part of ControlValueAccessor. */ setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } diff --git a/src/material/datepicker/datepicker.spec.ts b/src/material/datepicker/datepicker.spec.ts index 9b6f5428bab1..d84dbba537b0 100644 --- a/src/material/datepicker/datepicker.spec.ts +++ b/src/material/datepicker/datepicker.spec.ts @@ -1160,6 +1160,22 @@ describe('MatDatepicker', () => { expect(formControl.hasError('matDatepickerParse')).toBe(true); }); + + it('should not re-format the input value if the forms module re-assigns the same date', () => { + const input = fixture.nativeElement.querySelector('input'); + const date = new Date(2017, JAN, 1); + testComponent.formControl.setValue(date); + fixture.detectChanges(); + expect(input.value).toContain('2017'); + + // Note: this isn't how users would behave, but it captures + // the sequence of events with signal forms. + input.value = 'foo'; + testComponent.formControl.setValue(date); + fixture.detectChanges(); + + expect(input.value).toBe('foo'); + }); }); describe('datepicker with mat-datepicker-toggle', () => {