Skip to content

Commit 1fd0353

Browse files
committed
fix(material/datepicker): prevent crash during range picker navigation
1 parent d02338b commit 1fd0353

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

src/material/datepicker/calendar-body.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
}
1515

1616
<!-- Create the first row separately so we can include a special spacer cell. -->
17-
@for (row of rows; track _trackRow(row); let rowIndex = $index) {
17+
@for (row of rows; track _trackRow($index, row); let rowIndex = $index) {
1818
<tr role="row">
1919
<!--
2020
This cell is purely decorative, but we can't put `aria-hidden` or `role="presentation"` on it,

src/material/datepicker/calendar-body.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,11 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView
221221
* key on the row, but that would require a breaking change for the `rows` input. We don't
222222
* use the built-in identity tracking, because it logs warnings.
223223
*/
224-
_trackRow = (row: MatCalendarCell[]) => row;
224+
_trackRow = (index: number, row: MatCalendarCell[]) => {
225+
// Use a combination of index and first cell value for more stable tracking
226+
// This prevents LView detachment errors when navigating between months
227+
return row.length > 0 ? `${index}-${row[0].value}` : index;
228+
};
225229

226230
constructor(...args: unknown[]);
227231

src/material/datepicker/month-view.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,29 @@ describe('MatMonthView', () => {
353353
expect(calendarInstance.date).toEqual(new Date(2017, JAN, 19));
354354
});
355355

356+
it('should not crash when navigating to next month with down arrow in range mode', () => {
357+
// Set up a range selection to reproduce the bug scenario
358+
testComponent.selected = new DateRange(new Date(2017, JAN, 15), null);
359+
fixture.changeDetectorRef.markForCheck();
360+
fixture.detectChanges();
361+
362+
// Navigate to a date near the end of the month
363+
calendarInstance.date = new Date(2017, JAN, 28);
364+
fixture.changeDetectorRef.markForCheck();
365+
fixture.detectChanges();
366+
367+
// This should trigger month navigation and test the fix for the LView detachment error
368+
expect(() => {
369+
for (let i = 0; i < 10; i++) {
370+
dispatchKeyboardEvent(calendarBodyEl, 'keydown', DOWN_ARROW);
371+
fixture.detectChanges();
372+
}
373+
}).not.toThrow();
374+
375+
// Verify we navigated to the next month
376+
expect(calendarInstance.date.getMonth()).toBe(FEB);
377+
});
378+
356379
it('should go to beginning of the month on home press', () => {
357380
dispatchKeyboardEvent(calendarBodyEl, 'keydown', HOME);
358381
fixture.detectChanges();

0 commit comments

Comments
 (0)