Skip to content

Commit

Permalink
fix(material/datepicker): resolve repeater warnings in calendar (#29028)
Browse files Browse the repository at this point in the history
Fixes that the calendar was triggering some newly-introduced warnings from the framework.

Fixes #29008.

(cherry picked from commit 9a502e7)
  • Loading branch information
crisbeto committed May 9, 2024
1 parent 7a8e886 commit ec9e83d
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/material/datepicker/calendar-body.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
}

<!-- Create the first row separately so we can include a special spacer cell. -->
@for (row of rows; track row; let rowIndex = $index) {
@for (row of rows; track _trackRow(row); let rowIndex = $index) {
<tr role="row">
<!--
This cell is purely decorative, but we can't put `aria-hidden` or `role="presentation"` on it,
Expand All @@ -36,7 +36,7 @@
cell is interactable, as well as the selection state via `aria-pressed`. See #23476 for
background.
-->
@for (item of row; track item; let colIndex = $index) {
@for (item of row; track item.id; let colIndex = $index) {
<td
role="gridcell"
class="mat-calendar-body-cell-container"
Expand Down
11 changes: 11 additions & 0 deletions src/material/datepicker/calendar-body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,15 @@ export type MatCalendarCellClassFunction<D> = (
view: 'month' | 'year' | 'multi-year',
) => MatCalendarCellCssClasses;

let uniqueIdCounter = 0;

/**
* An internal class that represents the data corresponding to a single calendar cell.
* @docs-private
*/
export class MatCalendarCell<D = any> {
readonly id = uniqueIdCounter++;

constructor(
public value: number,
public displayValue: string,
Expand Down Expand Up @@ -192,6 +196,13 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView

private _injector = inject(Injector);

/**
* Tracking function for rows based on their identity. Ideally we would use some sort of
* key on the row, but that would require a breaking change for the `rows` input. We don't
* use the built-in identity tracking, because it logs warnings.
*/
_trackRow = (row: MatCalendarCell[]) => row;

constructor(
private _elementRef: ElementRef<HTMLElement>,
private _ngZone: NgZone,
Expand Down
2 changes: 1 addition & 1 deletion src/material/datepicker/month-view.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<table class="mat-calendar-table" role="grid">
<thead class="mat-calendar-table-header">
<tr>
@for (day of _weekdays; track day) {
@for (day of _weekdays; track day.id) {
<th scope="col">
<span class="cdk-visually-hidden">{{day.long}}</span>
<span aria-hidden="true">{{day.narrow}}</span>
Expand Down
6 changes: 4 additions & 2 deletions src/material/datepicker/month-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ import {

const DAYS_PER_WEEK = 7;

let uniqueIdCounter = 0;

/**
* An internal component used to display a single month in the datepicker.
* @docs-private
Expand Down Expand Up @@ -206,7 +208,7 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
_todayDate: number | null;

/** The names of the weekdays. */
_weekdays: {long: string; narrow: string}[];
_weekdays: {long: string; narrow: string; id: number}[];

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

// Rotate the labels for days of the week based on the configured first day of the week.
let weekdays = longWeekdays.map((long, i) => {
return {long, narrow: narrowWeekdays[i]};
return {long, narrow: narrowWeekdays[i], id: uniqueIdCounter++};
});
this._weekdays = weekdays.slice(firstDayOfWeek).concat(weekdays.slice(0, firstDayOfWeek));
}
Expand Down
4 changes: 4 additions & 0 deletions tools/public_api_guard/material/datepicker.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ export class MatCalendarBody<D = any> implements OnChanges, OnDestroy, AfterView
_startDateLabelId: string;
startValue: number;
todayValue: number;
_trackRow: (row: MatCalendarCell[]) => MatCalendarCell<any>[];
// (undocumented)
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>;
// (undocumented)
Expand All @@ -268,6 +269,8 @@ export class MatCalendarCell<D = any> {
// (undocumented)
enabled: boolean;
// (undocumented)
readonly id: number;
// (undocumented)
rawValue?: D | undefined;
// (undocumented)
value: number;
Expand Down Expand Up @@ -748,6 +751,7 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
_weekdays: {
long: string;
narrow: string;
id: number;
}[];
_weeks: MatCalendarCell[][];
// (undocumented)
Expand Down

0 comments on commit ec9e83d

Please sign in to comment.