Skip to content

Commit ec9e83d

Browse files
committed
fix(material/datepicker): resolve repeater warnings in calendar (#29028)
Fixes that the calendar was triggering some newly-introduced warnings from the framework. Fixes #29008. (cherry picked from commit 9a502e7)
1 parent 7a8e886 commit ec9e83d

File tree

5 files changed

+22
-5
lines changed

5 files changed

+22
-5
lines changed

src/material/datepicker/calendar-body.html

Lines changed: 2 additions & 2 deletions
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 row; let rowIndex = $index) {
17+
@for (row of rows; track _trackRow(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,
@@ -36,7 +36,7 @@
3636
cell is interactable, as well as the selection state via `aria-pressed`. See #23476 for
3737
background.
3838
-->
39-
@for (item of row; track item; let colIndex = $index) {
39+
@for (item of row; track item.id; let colIndex = $index) {
4040
<td
4141
role="gridcell"
4242
class="mat-calendar-body-cell-container"

src/material/datepicker/calendar-body.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,15 @@ export type MatCalendarCellClassFunction<D> = (
3535
view: 'month' | 'year' | 'multi-year',
3636
) => MatCalendarCellCssClasses;
3737

38+
let uniqueIdCounter = 0;
39+
3840
/**
3941
* An internal class that represents the data corresponding to a single calendar cell.
4042
* @docs-private
4143
*/
4244
export class MatCalendarCell<D = any> {
45+
readonly id = uniqueIdCounter++;
46+
4347
constructor(
4448
public value: number,
4549
public displayValue: string,
@@ -192,6 +196,13 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView
192196

193197
private _injector = inject(Injector);
194198

199+
/**
200+
* Tracking function for rows based on their identity. Ideally we would use some sort of
201+
* key on the row, but that would require a breaking change for the `rows` input. We don't
202+
* use the built-in identity tracking, because it logs warnings.
203+
*/
204+
_trackRow = (row: MatCalendarCell[]) => row;
205+
195206
constructor(
196207
private _elementRef: ElementRef<HTMLElement>,
197208
private _ngZone: NgZone,

src/material/datepicker/month-view.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<table class="mat-calendar-table" role="grid">
22
<thead class="mat-calendar-table-header">
33
<tr>
4-
@for (day of _weekdays; track day) {
4+
@for (day of _weekdays; track day.id) {
55
<th scope="col">
66
<span class="cdk-visually-hidden">{{day.long}}</span>
77
<span aria-hidden="true">{{day.narrow}}</span>

src/material/datepicker/month-view.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ import {
5555

5656
const DAYS_PER_WEEK = 7;
5757

58+
let uniqueIdCounter = 0;
59+
5860
/**
5961
* An internal component used to display a single month in the datepicker.
6062
* @docs-private
@@ -206,7 +208,7 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
206208
_todayDate: number | null;
207209

208210
/** The names of the weekdays. */
209-
_weekdays: {long: string; narrow: string}[];
211+
_weekdays: {long: string; narrow: string; id: number}[];
210212

211213
constructor(
212214
readonly _changeDetectorRef: ChangeDetectorRef,
@@ -508,7 +510,7 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
508510

509511
// Rotate the labels for days of the week based on the configured first day of the week.
510512
let weekdays = longWeekdays.map((long, i) => {
511-
return {long, narrow: narrowWeekdays[i]};
513+
return {long, narrow: narrowWeekdays[i], id: uniqueIdCounter++};
512514
});
513515
this._weekdays = weekdays.slice(firstDayOfWeek).concat(weekdays.slice(0, firstDayOfWeek));
514516
}

tools/public_api_guard/material/datepicker.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView
248248
_startDateLabelId: string;
249249
startValue: number;
250250
todayValue: number;
251+
_trackRow: (row: MatCalendarCell[]) => MatCalendarCell<any>[];
251252
// (undocumented)
252253
static ɵcmp: i0.ɵɵComponentDeclaration<MatCalendarBody<any>, "[mat-calendar-body]", ["matCalendarBody"], { "label": { "alias": "label"; "required": false; }; "rows": { "alias": "rows"; "required": false; }; "todayValue": { "alias": "todayValue"; "required": false; }; "startValue": { "alias": "startValue"; "required": false; }; "endValue": { "alias": "endValue"; "required": false; }; "labelMinRequiredCells": { "alias": "labelMinRequiredCells"; "required": false; }; "numCols": { "alias": "numCols"; "required": false; }; "activeCell": { "alias": "activeCell"; "required": false; }; "isRange": { "alias": "isRange"; "required": false; }; "cellAspectRatio": { "alias": "cellAspectRatio"; "required": false; }; "comparisonStart": { "alias": "comparisonStart"; "required": false; }; "comparisonEnd": { "alias": "comparisonEnd"; "required": false; }; "previewStart": { "alias": "previewStart"; "required": false; }; "previewEnd": { "alias": "previewEnd"; "required": false; }; "startDateAccessibleName": { "alias": "startDateAccessibleName"; "required": false; }; "endDateAccessibleName": { "alias": "endDateAccessibleName"; "required": false; }; }, { "selectedValueChange": "selectedValueChange"; "previewChange": "previewChange"; "activeDateChange": "activeDateChange"; "dragStarted": "dragStarted"; "dragEnded": "dragEnded"; }, never, never, true, never>;
253254
// (undocumented)
@@ -268,6 +269,8 @@ export class MatCalendarCell<D = any> {
268269
// (undocumented)
269270
enabled: boolean;
270271
// (undocumented)
272+
readonly id: number;
273+
// (undocumented)
271274
rawValue?: D | undefined;
272275
// (undocumented)
273276
value: number;
@@ -748,6 +751,7 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
748751
_weekdays: {
749752
long: string;
750753
narrow: string;
754+
id: number;
751755
}[];
752756
_weeks: MatCalendarCell[][];
753757
// (undocumented)

0 commit comments

Comments
 (0)