ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
829 lines (818 loc) • 188 kB
JavaScript
import * as i6 from '@angular/cdk/bidi';
import { BidiModule } from '@angular/cdk/bidi';
import * as i14 from '@angular/cdk/overlay';
import { CdkOverlayOrigin, CdkConnectedOverlay, OverlayModule } from '@angular/cdk/overlay';
import * as i2$1 from '@angular/common';
import { DOCUMENT, CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { EventEmitter, Component, ViewEncapsulation, ChangeDetectionStrategy, Input, Output, Injectable, Directive, forwardRef, Inject, Optional, Host, ViewChild, ViewChildren, NgModule } from '@angular/core';
import * as i10 from '@angular/forms';
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
import * as i2 from 'ng-zorro-antd/button';
import { NzButtonModule } from 'ng-zorro-antd/button';
import * as i7 from 'ng-zorro-antd/core/no-animation';
import { NzNoAnimationModule } from 'ng-zorro-antd/core/no-animation';
import * as i13 from 'ng-zorro-antd/core/outlet';
import { NzOutletModule } from 'ng-zorro-antd/core/outlet';
import * as i15 from 'ng-zorro-antd/core/overlay';
import { NzOverlayModule } from 'ng-zorro-antd/core/overlay';
import * as i11 from 'ng-zorro-antd/icon';
import { NzIconModule } from 'ng-zorro-antd/icon';
import * as i9 from 'ng-zorro-antd/time-picker';
import { NzTimePickerModule } from 'ng-zorro-antd/time-picker';
import { CandyDate, normalizeRangeValue, cloneDate, wrongSortOrder } from 'ng-zorro-antd/core/time';
import { isTemplateRef, isNonEmptyString, valueFunctionProp, toBoolean, InputBoolean } from 'ng-zorro-antd/core/util';
import * as i1 from 'ng-zorro-antd/i18n';
import { NzI18nModule } from 'ng-zorro-antd/i18n';
import * as i4 from 'ng-zorro-antd/core/wave';
import * as i5 from 'ng-zorro-antd/core/transition-patch';
import { __decorate } from 'tslib';
import { ESCAPE } from '@angular/cdk/keycodes';
import { ReplaySubject, Subject, merge, fromEvent } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { slideMotion } from 'ng-zorro-antd/core/animation';
import * as i1$1 from 'ng-zorro-antd/core/config';
import { WithConfig } from 'ng-zorro-antd/core/config';
import * as i4$1 from 'ng-zorro-antd/cdk/resize-observer';
import * as i5$1 from '@angular/cdk/platform';
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
const PREFIX_CLASS = 'ant-picker';
const defaultDisabledTime = {
nzDisabledHours() {
return [];
},
nzDisabledMinutes() {
return [];
},
nzDisabledSeconds() {
return [];
}
};
function getTimeConfig(value, disabledTime) {
let disabledTimeConfig = disabledTime ? disabledTime(value && value.nativeDate) : {};
disabledTimeConfig = {
...defaultDisabledTime,
...disabledTimeConfig
};
return disabledTimeConfig;
}
function isTimeValidByConfig(value, disabledTimeConfig) {
let invalidTime = false;
if (value) {
const hour = value.getHours();
const minutes = value.getMinutes();
const seconds = value.getSeconds();
const disabledHours = disabledTimeConfig.nzDisabledHours();
if (disabledHours.indexOf(hour) === -1) {
const disabledMinutes = disabledTimeConfig.nzDisabledMinutes(hour);
if (disabledMinutes.indexOf(minutes) === -1) {
const disabledSeconds = disabledTimeConfig.nzDisabledSeconds(hour, minutes);
invalidTime = disabledSeconds.indexOf(seconds) !== -1;
}
else {
invalidTime = true;
}
}
else {
invalidTime = true;
}
}
return !invalidTime;
}
function isTimeValid(value, disabledTime) {
const disabledTimeConfig = getTimeConfig(value, disabledTime);
return isTimeValidByConfig(value, disabledTimeConfig);
}
function isAllowedDate(value, disabledDate, disabledTime) {
if (!value) {
return false;
}
if (disabledDate) {
if (disabledDate(value.nativeDate)) {
return false;
}
}
if (disabledTime) {
if (!isTimeValid(value, disabledTime)) {
return false;
}
}
return true;
}
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
/**
* Compatible translate the moment-like format pattern to angular's pattern
* Why? For now, we need to support the existing language formats in AntD, and AntD uses the default temporal syntax.
*
* TODO: compare and complete all format patterns
* Each format docs as below:
*
* @link https://momentjs.com/docs/#/displaying/format/
* @link https://angular.io/api/common/DatePipe#description
* @param format input format pattern
*/
function transCompatFormat(format) {
return (format &&
format
.replace(/Y/g, 'y') // only support y, yy, yyy, yyyy
.replace(/D/g, 'd')); // d, dd represent of D, DD for momentjs, others are not support
}
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
class CalendarFooterComponent {
constructor(dateHelper) {
this.dateHelper = dateHelper;
this.showToday = false;
this.showNow = false;
this.hasTimePicker = false;
this.isRange = false;
this.okDisabled = false;
this.rangeQuickSelector = null;
this.clickOk = new EventEmitter();
this.clickToday = new EventEmitter();
this.prefixCls = PREFIX_CLASS;
this.isTemplateRef = isTemplateRef;
this.isNonEmptyString = isNonEmptyString;
this.isTodayDisabled = false;
this.todayTitle = '';
}
ngOnChanges(changes) {
const now = new Date();
if (changes.disabledDate) {
this.isTodayDisabled = !!(this.disabledDate && this.disabledDate(now));
}
if (changes.locale) {
// NOTE: Compat for DatePipe formatting rules
const dateFormat = transCompatFormat(this.locale.dateFormat);
this.todayTitle = this.dateHelper.format(now, dateFormat);
}
}
onClickToday() {
const now = new CandyDate();
this.clickToday.emit(now.clone()); // To prevent the "now" being modified from outside, we use clone
}
}
CalendarFooterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: CalendarFooterComponent, deps: [{ token: i1.DateHelperService }], target: i0.ɵɵFactoryTarget.Component });
CalendarFooterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: CalendarFooterComponent, selector: "calendar-footer", inputs: { locale: "locale", showToday: "showToday", showNow: "showNow", hasTimePicker: "hasTimePicker", isRange: "isRange", okDisabled: "okDisabled", disabledDate: "disabledDate", extraFooter: "extraFooter", rangeQuickSelector: "rangeQuickSelector" }, outputs: { clickOk: "clickOk", clickToday: "clickToday" }, exportAs: ["calendarFooter"], usesOnChanges: true, ngImport: i0, template: `
<div class="{{ prefixCls }}-footer">
<div *ngIf="extraFooter" class="{{ prefixCls }}-footer-extra">
<ng-container [ngSwitch]="true">
<ng-container *ngSwitchCase="isTemplateRef(extraFooter)">
<ng-container *ngTemplateOutlet="$any(extraFooter)"></ng-container>
</ng-container>
<ng-container *ngSwitchCase="isNonEmptyString(extraFooter)">
<span [innerHTML]="extraFooter"></span>
</ng-container>
</ng-container>
</div>
<a
*ngIf="showToday"
class="{{ prefixCls }}-today-btn {{ isTodayDisabled ? prefixCls + '-today-btn-disabled' : '' }}"
role="button"
(click)="isTodayDisabled ? null : onClickToday()"
title="{{ todayTitle }}"
>
{{ locale.today }}
</a>
<ul *ngIf="hasTimePicker || rangeQuickSelector" class="{{ prefixCls }}-ranges">
<ng-container *ngTemplateOutlet="rangeQuickSelector"></ng-container>
<li *ngIf="showNow" class="{{ prefixCls }}-now">
<a class="{{ prefixCls }}-now-btn" (click)="isTodayDisabled ? null : onClickToday()">
{{ locale.now }}
</a>
</li>
<li *ngIf="hasTimePicker" class="{{ prefixCls }}-ok">
<button
nz-button
type="button"
nzType="primary"
nzSize="small"
[disabled]="okDisabled"
(click)="okDisabled ? null : clickOk.emit()"
>
{{ locale.ok }}
</button>
</li>
</ul>
</div>
`, isInline: true, components: [{ type: i2.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }], directives: [{ type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i4.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { type: i5.ɵNzTransitionPatchDirective, selector: "[nz-button], nz-button-group, [nz-icon], [nz-menu-item], [nz-submenu], nz-select-top-control, nz-select-placeholder, nz-input-group", inputs: ["hidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: CalendarFooterComponent, decorators: [{
type: Component,
args: [{
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'calendar-footer',
exportAs: 'calendarFooter',
template: `
<div class="{{ prefixCls }}-footer">
<div *ngIf="extraFooter" class="{{ prefixCls }}-footer-extra">
<ng-container [ngSwitch]="true">
<ng-container *ngSwitchCase="isTemplateRef(extraFooter)">
<ng-container *ngTemplateOutlet="$any(extraFooter)"></ng-container>
</ng-container>
<ng-container *ngSwitchCase="isNonEmptyString(extraFooter)">
<span [innerHTML]="extraFooter"></span>
</ng-container>
</ng-container>
</div>
<a
*ngIf="showToday"
class="{{ prefixCls }}-today-btn {{ isTodayDisabled ? prefixCls + '-today-btn-disabled' : '' }}"
role="button"
(click)="isTodayDisabled ? null : onClickToday()"
title="{{ todayTitle }}"
>
{{ locale.today }}
</a>
<ul *ngIf="hasTimePicker || rangeQuickSelector" class="{{ prefixCls }}-ranges">
<ng-container *ngTemplateOutlet="rangeQuickSelector"></ng-container>
<li *ngIf="showNow" class="{{ prefixCls }}-now">
<a class="{{ prefixCls }}-now-btn" (click)="isTodayDisabled ? null : onClickToday()">
{{ locale.now }}
</a>
</li>
<li *ngIf="hasTimePicker" class="{{ prefixCls }}-ok">
<button
nz-button
type="button"
nzType="primary"
nzSize="small"
[disabled]="okDisabled"
(click)="okDisabled ? null : clickOk.emit()"
>
{{ locale.ok }}
</button>
</li>
</ul>
</div>
`
}]
}], ctorParameters: function () { return [{ type: i1.DateHelperService }]; }, propDecorators: { locale: [{
type: Input
}], showToday: [{
type: Input
}], showNow: [{
type: Input
}], hasTimePicker: [{
type: Input
}], isRange: [{
type: Input
}], okDisabled: [{
type: Input
}], disabledDate: [{
type: Input
}], extraFooter: [{
type: Input
}], rangeQuickSelector: [{
type: Input
}], clickOk: [{
type: Output
}], clickToday: [{
type: Output
}] } });
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
class DatePickerService {
constructor() {
this.activeInput = 'left';
this.arrowLeft = 0;
this.isRange = false;
this.valueChange$ = new ReplaySubject(1);
this.emitValue$ = new Subject();
this.inputPartChange$ = new Subject();
}
initValue(reset = false) {
if (reset) {
this.initialValue = this.isRange ? [] : null;
}
this.setValue(this.initialValue);
}
hasValue(value = this.value) {
if (Array.isArray(value)) {
return !!value[0] || !!value[1];
}
else {
return !!value;
}
}
makeValue(value) {
if (this.isRange) {
return value ? value.map(val => new CandyDate(val)) : [];
}
else {
return value ? new CandyDate(value) : null;
}
}
setActiveDate(value, hasTimePicker = false, mode = 'month') {
const parentPanels = {
date: 'month',
month: 'year',
year: 'decade'
};
if (this.isRange) {
this.activeDate = normalizeRangeValue(value, hasTimePicker, parentPanels[mode], this.activeInput);
}
else {
this.activeDate = cloneDate(value);
}
}
setValue(value) {
this.value = value;
this.valueChange$.next(this.value);
}
getActiveIndex(part = this.activeInput) {
return { left: 0, right: 1 }[part];
}
ngOnDestroy() {
this.valueChange$.complete();
this.emitValue$.complete();
this.inputPartChange$.complete();
}
}
DatePickerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: DatePickerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
DatePickerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: DatePickerService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: DatePickerService, decorators: [{
type: Injectable
}] });
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
// eslint-disable-next-line @angular-eslint/directive-class-suffix
class AbstractPanelHeader {
constructor() {
this.prefixCls = `ant-picker-header`;
this.selectors = [];
this.showSuperPreBtn = true;
this.showSuperNextBtn = true;
this.showPreBtn = true;
this.showNextBtn = true;
this.panelModeChange = new EventEmitter();
this.valueChange = new EventEmitter();
}
superPreviousTitle() {
return this.locale.previousYear;
}
previousTitle() {
return this.locale.previousMonth;
}
superNextTitle() {
return this.locale.nextYear;
}
nextTitle() {
return this.locale.nextMonth;
}
superPrevious() {
this.changeValue(this.value.addYears(-1));
}
superNext() {
this.changeValue(this.value.addYears(1));
}
previous() {
this.changeValue(this.value.addMonths(-1));
}
next() {
this.changeValue(this.value.addMonths(1));
}
changeValue(value) {
if (this.value !== value) {
this.value = value;
this.valueChange.emit(this.value);
this.render();
}
}
changeMode(mode) {
this.panelModeChange.emit(mode);
}
render() {
if (this.value) {
this.selectors = this.getSelectors();
}
}
ngOnInit() {
if (!this.value) {
this.value = new CandyDate(); // Show today by default
}
this.selectors = this.getSelectors();
}
ngOnChanges(changes) {
if (changes.value || changes.locale) {
this.render();
}
}
}
AbstractPanelHeader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AbstractPanelHeader, deps: [], target: i0.ɵɵFactoryTarget.Directive });
AbstractPanelHeader.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.5", type: AbstractPanelHeader, inputs: { value: "value", locale: "locale", showSuperPreBtn: "showSuperPreBtn", showSuperNextBtn: "showSuperNextBtn", showPreBtn: "showPreBtn", showNextBtn: "showNextBtn" }, outputs: { panelModeChange: "panelModeChange", valueChange: "valueChange" }, usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AbstractPanelHeader, decorators: [{
type: Directive
}], propDecorators: { value: [{
type: Input
}], locale: [{
type: Input
}], showSuperPreBtn: [{
type: Input
}], showSuperNextBtn: [{
type: Input
}], showPreBtn: [{
type: Input
}], showNextBtn: [{
type: Input
}], panelModeChange: [{
type: Output
}], valueChange: [{
type: Output
}] } });
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
class DecadeHeaderComponent extends AbstractPanelHeader {
previous() { }
next() { }
get startYear() {
return parseInt(`${this.value.getYear() / 100}`, 10) * 100;
}
get endYear() {
return this.startYear + 99;
}
superPrevious() {
this.changeValue(this.value.addYears(-100));
}
superNext() {
this.changeValue(this.value.addYears(100));
}
getSelectors() {
return [
{
className: `${this.prefixCls}-decade-btn`,
title: '',
onClick: () => {
// noop
},
label: `${this.startYear}-${this.endYear}`
}
];
}
}
DecadeHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: DecadeHeaderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
DecadeHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: DecadeHeaderComponent, selector: "decade-header", exportAs: ["decadeHeader"], usesInheritance: true, ngImport: i0, template: "<div class=\"{{ prefixCls }}\">\n <button\n [style.visibility]=\"showSuperPreBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-super-prev-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ superPreviousTitle() }}\"\n (click)=\"superPrevious()\"\n >\n <span class=\"ant-picker-super-prev-icon\"></span>\n </button>\n <button\n [style.visibility]=\"showPreBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-prev-btn\"\n role=\"button\"\n type=\"button\"\n title=\"{{ previousTitle() }}\"\n tabindex=\"-1\"\n (click)=\"previous()\"\n >\n <span class=\"ant-picker-prev-icon\"></span>\n </button>\n\n <div class=\"{{ prefixCls }}-view\">\n <ng-container *ngFor=\"let selector of selectors\">\n <button\n class=\"{{ selector.className }}\"\n role=\"button\"\n type=\"button\"\n title=\"{{ selector.title || null }}\"\n (click)=\"selector.onClick()\"\n >\n {{ selector.label }}\n </button>\n </ng-container>\n </div>\n <button\n [style.visibility]=\"showNextBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-next-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ nextTitle() }}\"\n (click)=\"next()\"\n >\n <span class=\"ant-picker-next-icon\"></span>\n </button>\n <button\n [style.visibility]=\"showSuperNextBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-super-next-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ superNextTitle() }}\"\n (click)=\"superNext()\"\n >\n <span class=\"ant-picker-super-next-icon\"></span>\n </button>\n</div>\n", directives: [{ type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: DecadeHeaderComponent, decorators: [{
type: Component,
args: [{ encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, selector: 'decade-header', exportAs: 'decadeHeader', template: "<div class=\"{{ prefixCls }}\">\n <button\n [style.visibility]=\"showSuperPreBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-super-prev-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ superPreviousTitle() }}\"\n (click)=\"superPrevious()\"\n >\n <span class=\"ant-picker-super-prev-icon\"></span>\n </button>\n <button\n [style.visibility]=\"showPreBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-prev-btn\"\n role=\"button\"\n type=\"button\"\n title=\"{{ previousTitle() }}\"\n tabindex=\"-1\"\n (click)=\"previous()\"\n >\n <span class=\"ant-picker-prev-icon\"></span>\n </button>\n\n <div class=\"{{ prefixCls }}-view\">\n <ng-container *ngFor=\"let selector of selectors\">\n <button\n class=\"{{ selector.className }}\"\n role=\"button\"\n type=\"button\"\n title=\"{{ selector.title || null }}\"\n (click)=\"selector.onClick()\"\n >\n {{ selector.label }}\n </button>\n </ng-container>\n </div>\n <button\n [style.visibility]=\"showNextBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-next-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ nextTitle() }}\"\n (click)=\"next()\"\n >\n <span class=\"ant-picker-next-icon\"></span>\n </button>\n <button\n [style.visibility]=\"showSuperNextBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-super-next-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ superNextTitle() }}\"\n (click)=\"superNext()\"\n >\n <span class=\"ant-picker-super-next-icon\"></span>\n </button>\n</div>\n" }]
}] });
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
// eslint-disable-next-line @angular-eslint/directive-class-suffix
class AbstractTable {
constructor() {
this.isTemplateRef = isTemplateRef;
this.isNonEmptyString = isNonEmptyString;
this.headRow = [];
this.bodyRows = [];
this.MAX_ROW = 6;
this.MAX_COL = 7;
this.prefixCls = 'ant-picker';
this.activeDate = new CandyDate();
this.showWeek = false;
this.selectedValue = []; // Range ONLY
this.hoverValue = []; // Range ONLY
this.valueChange = new EventEmitter();
this.cellHover = new EventEmitter(); // Emitted when hover on a day by mouse enter
}
render() {
if (this.activeDate) {
this.headRow = this.makeHeadRow();
this.bodyRows = this.makeBodyRows();
}
}
trackByBodyRow(_index, item) {
return item.trackByIndex;
}
trackByBodyColumn(_index, item) {
return item.trackByIndex;
}
hasRangeValue() {
return this.selectedValue?.length > 0 || this.hoverValue?.length > 0;
}
getClassMap(cell) {
return {
[`ant-picker-cell`]: true,
[`ant-picker-cell-in-view`]: true,
[`ant-picker-cell-selected`]: cell.isSelected,
[`ant-picker-cell-disabled`]: cell.isDisabled,
[`ant-picker-cell-in-range`]: !!cell.isInSelectedRange,
[`ant-picker-cell-range-start`]: !!cell.isSelectedStart,
[`ant-picker-cell-range-end`]: !!cell.isSelectedEnd,
[`ant-picker-cell-range-start-single`]: !!cell.isStartSingle,
[`ant-picker-cell-range-end-single`]: !!cell.isEndSingle,
[`ant-picker-cell-range-hover`]: !!cell.isInHoverRange,
[`ant-picker-cell-range-hover-start`]: !!cell.isHoverStart,
[`ant-picker-cell-range-hover-end`]: !!cell.isHoverEnd,
[`ant-picker-cell-range-hover-edge-start`]: !!cell.isFirstCellInPanel,
[`ant-picker-cell-range-hover-edge-end`]: !!cell.isLastCellInPanel,
[`ant-picker-cell-range-start-near-hover`]: !!cell.isRangeStartNearHover,
[`ant-picker-cell-range-end-near-hover`]: !!cell.isRangeEndNearHover
};
}
ngOnInit() {
this.render();
}
ngOnChanges(changes) {
if (changes.activeDate && !changes.activeDate.currentValue) {
this.activeDate = new CandyDate();
}
if (changes.disabledDate ||
changes.locale ||
changes.showWeek ||
this.isDateRealChange(changes.activeDate) ||
this.isDateRealChange(changes.value) ||
this.isDateRealChange(changes.selectedValue) ||
this.isDateRealChange(changes.hoverValue)) {
this.render();
}
}
isDateRealChange(change) {
if (change) {
const previousValue = change.previousValue;
const currentValue = change.currentValue;
if (Array.isArray(currentValue)) {
return (!Array.isArray(previousValue) ||
currentValue.length !== previousValue.length ||
currentValue.some((value, index) => {
const previousCandyDate = previousValue[index];
return previousCandyDate instanceof CandyDate ? previousCandyDate.isSameDay(value) : previousCandyDate !== value;
}));
}
else {
return !this.isSameDate(previousValue, currentValue);
}
}
return false;
}
isSameDate(left, right) {
return (!left && !right) || (left && right && right.isSameDay(left));
}
}
AbstractTable.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AbstractTable, deps: [], target: i0.ɵɵFactoryTarget.Directive });
AbstractTable.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.5", type: AbstractTable, inputs: { prefixCls: "prefixCls", value: "value", locale: "locale", activeDate: "activeDate", showWeek: "showWeek", selectedValue: "selectedValue", hoverValue: "hoverValue", disabledDate: "disabledDate", cellRender: "cellRender", fullCellRender: "fullCellRender" }, outputs: { valueChange: "valueChange", cellHover: "cellHover" }, usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: AbstractTable, decorators: [{
type: Directive
}], propDecorators: { prefixCls: [{
type: Input
}], value: [{
type: Input
}], locale: [{
type: Input
}], activeDate: [{
type: Input
}], showWeek: [{
type: Input
}], selectedValue: [{
type: Input
}], hoverValue: [{
type: Input
}], disabledDate: [{
type: Input
}], cellRender: [{
type: Input
}], fullCellRender: [{
type: Input
}], valueChange: [{
type: Output
}], cellHover: [{
type: Output
}] } });
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
const MAX_ROW = 4;
const MAX_COL = 3;
class DecadeTableComponent extends AbstractTable {
get startYear() {
return parseInt(`${this.activeDate.getYear() / 100}`, 10) * 100;
}
get endYear() {
return this.startYear + 99;
}
makeHeadRow() {
return [];
}
makeBodyRows() {
const decades = [];
const currentYear = this.value && this.value.getYear();
const startYear = this.startYear;
const endYear = this.endYear;
const previousYear = startYear - 10;
let index = 0;
for (let rowIndex = 0; rowIndex < MAX_ROW; rowIndex++) {
const row = {
dateCells: [],
trackByIndex: rowIndex
};
for (let colIndex = 0; colIndex < MAX_COL; colIndex++) {
const start = previousYear + index * 10;
const end = previousYear + index * 10 + 9;
const content = `${start}-${end}`;
const cell = {
trackByIndex: colIndex,
value: this.activeDate.setYear(start).nativeDate,
content,
title: content,
isDisabled: false,
isSelected: currentYear >= start && currentYear <= end,
isLowerThanStart: end < startYear,
isBiggerThanEnd: start > endYear,
classMap: {},
onClick() { },
onMouseEnter() { }
};
cell.classMap = this.getClassMap(cell);
cell.onClick = () => this.chooseDecade(start);
index++;
row.dateCells.push(cell);
}
decades.push(row);
}
return decades;
}
getClassMap(cell) {
return {
[`${this.prefixCls}-cell`]: true,
[`${this.prefixCls}-cell-in-view`]: !cell.isBiggerThanEnd && !cell.isLowerThanStart,
[`${this.prefixCls}-cell-selected`]: cell.isSelected,
[`${this.prefixCls}-cell-disabled`]: cell.isDisabled
};
}
chooseDecade(year) {
this.value = this.activeDate.setYear(year);
this.valueChange.emit(this.value);
}
}
DecadeTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: DecadeTableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
DecadeTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: DecadeTableComponent, selector: "decade-table", exportAs: ["decadeTable"], usesInheritance: true, ngImport: i0, template: "<table class=\"ant-picker-content\" cellspacing=\"0\" role=\"grid\">\n <thead *ngIf=\"headRow && headRow.length > 0\">\n <tr role=\"row\">\n <th *ngIf=\"showWeek\" role=\"columnheader\"></th>\n <th *ngFor=\"let cell of headRow\" role=\"columnheader\" title=\"{{ cell.title }}\">\n {{ cell.content }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of bodyRows; trackBy: trackByBodyRow\" [ngClass]=\"row.classMap!\" role=\"row\">\n <td *ngIf=\"row.weekNum\" role=\"gridcell\" class=\"{{ prefixCls }}-cell-week\">\n {{ row.weekNum }}\n </td>\n <td\n *ngFor=\"let cell of row.dateCells; trackBy: trackByBodyColumn\"\n title=\"{{ cell.title }}\"\n role=\"gridcell\"\n [ngClass]=\"cell.classMap!\"\n (click)=\"cell.isDisabled ? null : cell.onClick()\"\n (mouseenter)=\"cell.onMouseEnter()\"\n >\n <ng-container [ngSwitch]=\"prefixCls\">\n <ng-container *ngSwitchCase=\"'ant-picker'\">\n <ng-container [ngSwitch]=\"true\">\n <ng-container *ngSwitchCase=\"isTemplateRef(cell.cellRender)\">\n <!-- *ngSwitchCase not has type assertion support, the cellRender type here is TemplateRef -->\n <ng-container\n *ngTemplateOutlet=\"$any(cell.cellRender); context: { $implicit: cell.value }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"isNonEmptyString(cell.cellRender)\">\n <span [innerHTML]=\"cell.cellRender\"></span>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <div\n class=\"{{ prefixCls }}-cell-inner\"\n [attr.aria-selected]=\"cell.isSelected\"\n [attr.aria-disabled]=\"cell.isDisabled\"\n >\n {{ cell.content }}\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'ant-picker-calendar'\">\n <div\n class=\"{{ prefixCls }}-date ant-picker-cell-inner\"\n [class.ant-picker-calendar-date-today]=\"cell.isToday\"\n >\n <ng-container *ngIf=\"cell.fullCellRender; else defaultCell\">\n <ng-container\n *ngTemplateOutlet=\"$any(cell.fullCellRender); context: { $implicit: cell.value }\"\n >\n </ng-container>\n </ng-container>\n <ng-template #defaultCell>\n <div class=\"{{ prefixCls }}-date-value\">{{ cell.content }}</div>\n <div class=\"{{ prefixCls }}-date-content\">\n <ng-container\n *ngTemplateOutlet=\"$any(cell.cellRender); context: { $implicit: cell.value }\"\n >\n </ng-container>\n </div>\n </ng-template>\n </div>\n </ng-container>\n </ng-container>\n </td>\n </tr>\n </tbody>\n</table>\n", directives: [{ type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i2$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: DecadeTableComponent, decorators: [{
type: Component,
args: [{ encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, selector: 'decade-table', exportAs: 'decadeTable', template: "<table class=\"ant-picker-content\" cellspacing=\"0\" role=\"grid\">\n <thead *ngIf=\"headRow && headRow.length > 0\">\n <tr role=\"row\">\n <th *ngIf=\"showWeek\" role=\"columnheader\"></th>\n <th *ngFor=\"let cell of headRow\" role=\"columnheader\" title=\"{{ cell.title }}\">\n {{ cell.content }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of bodyRows; trackBy: trackByBodyRow\" [ngClass]=\"row.classMap!\" role=\"row\">\n <td *ngIf=\"row.weekNum\" role=\"gridcell\" class=\"{{ prefixCls }}-cell-week\">\n {{ row.weekNum }}\n </td>\n <td\n *ngFor=\"let cell of row.dateCells; trackBy: trackByBodyColumn\"\n title=\"{{ cell.title }}\"\n role=\"gridcell\"\n [ngClass]=\"cell.classMap!\"\n (click)=\"cell.isDisabled ? null : cell.onClick()\"\n (mouseenter)=\"cell.onMouseEnter()\"\n >\n <ng-container [ngSwitch]=\"prefixCls\">\n <ng-container *ngSwitchCase=\"'ant-picker'\">\n <ng-container [ngSwitch]=\"true\">\n <ng-container *ngSwitchCase=\"isTemplateRef(cell.cellRender)\">\n <!-- *ngSwitchCase not has type assertion support, the cellRender type here is TemplateRef -->\n <ng-container\n *ngTemplateOutlet=\"$any(cell.cellRender); context: { $implicit: cell.value }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"isNonEmptyString(cell.cellRender)\">\n <span [innerHTML]=\"cell.cellRender\"></span>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <div\n class=\"{{ prefixCls }}-cell-inner\"\n [attr.aria-selected]=\"cell.isSelected\"\n [attr.aria-disabled]=\"cell.isDisabled\"\n >\n {{ cell.content }}\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'ant-picker-calendar'\">\n <div\n class=\"{{ prefixCls }}-date ant-picker-cell-inner\"\n [class.ant-picker-calendar-date-today]=\"cell.isToday\"\n >\n <ng-container *ngIf=\"cell.fullCellRender; else defaultCell\">\n <ng-container\n *ngTemplateOutlet=\"$any(cell.fullCellRender); context: { $implicit: cell.value }\"\n >\n </ng-container>\n </ng-container>\n <ng-template #defaultCell>\n <div class=\"{{ prefixCls }}-date-value\">{{ cell.content }}</div>\n <div class=\"{{ prefixCls }}-date-content\">\n <ng-container\n *ngTemplateOutlet=\"$any(cell.cellRender); context: { $implicit: cell.value }\"\n >\n </ng-container>\n </div>\n </ng-template>\n </div>\n </ng-container>\n </ng-container>\n </td>\n </tr>\n </tbody>\n</table>\n" }]
}] });
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
class YearHeaderComponent extends AbstractPanelHeader {
get startYear() {
return parseInt(`${this.value.getYear() / 10}`, 10) * 10;
}
get endYear() {
return this.startYear + 9;
}
superPrevious() {
this.changeValue(this.value.addYears(-10));
}
superNext() {
this.changeValue(this.value.addYears(10));
}
getSelectors() {
return [
{
className: `${this.prefixCls}-year-btn`,
title: '',
onClick: () => this.changeMode('decade'),
label: `${this.startYear}-${this.endYear}`
}
];
}
}
YearHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: YearHeaderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
YearHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: YearHeaderComponent, selector: "year-header", exportAs: ["yearHeader"], usesInheritance: true, ngImport: i0, template: "<div class=\"{{ prefixCls }}\">\n <button\n [style.visibility]=\"showSuperPreBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-super-prev-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ superPreviousTitle() }}\"\n (click)=\"superPrevious()\"\n >\n <span class=\"ant-picker-super-prev-icon\"></span>\n </button>\n <button\n [style.visibility]=\"showPreBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-prev-btn\"\n role=\"button\"\n type=\"button\"\n title=\"{{ previousTitle() }}\"\n tabindex=\"-1\"\n (click)=\"previous()\"\n >\n <span class=\"ant-picker-prev-icon\"></span>\n </button>\n\n <div class=\"{{ prefixCls }}-view\">\n <ng-container *ngFor=\"let selector of selectors\">\n <button\n class=\"{{ selector.className }}\"\n role=\"button\"\n type=\"button\"\n title=\"{{ selector.title || null }}\"\n (click)=\"selector.onClick()\"\n >\n {{ selector.label }}\n </button>\n </ng-container>\n </div>\n <button\n [style.visibility]=\"showNextBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-next-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ nextTitle() }}\"\n (click)=\"next()\"\n >\n <span class=\"ant-picker-next-icon\"></span>\n </button>\n <button\n [style.visibility]=\"showSuperNextBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-super-next-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ superNextTitle() }}\"\n (click)=\"superNext()\"\n >\n <span class=\"ant-picker-super-next-icon\"></span>\n </button>\n</div>\n", directives: [{ type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: YearHeaderComponent, decorators: [{
type: Component,
args: [{ encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, selector: 'year-header', exportAs: 'yearHeader', template: "<div class=\"{{ prefixCls }}\">\n <button\n [style.visibility]=\"showSuperPreBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-super-prev-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ superPreviousTitle() }}\"\n (click)=\"superPrevious()\"\n >\n <span class=\"ant-picker-super-prev-icon\"></span>\n </button>\n <button\n [style.visibility]=\"showPreBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-prev-btn\"\n role=\"button\"\n type=\"button\"\n title=\"{{ previousTitle() }}\"\n tabindex=\"-1\"\n (click)=\"previous()\"\n >\n <span class=\"ant-picker-prev-icon\"></span>\n </button>\n\n <div class=\"{{ prefixCls }}-view\">\n <ng-container *ngFor=\"let selector of selectors\">\n <button\n class=\"{{ selector.className }}\"\n role=\"button\"\n type=\"button\"\n title=\"{{ selector.title || null }}\"\n (click)=\"selector.onClick()\"\n >\n {{ selector.label }}\n </button>\n </ng-container>\n </div>\n <button\n [style.visibility]=\"showNextBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-next-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ nextTitle() }}\"\n (click)=\"next()\"\n >\n <span class=\"ant-picker-next-icon\"></span>\n </button>\n <button\n [style.visibility]=\"showSuperNextBtn ? 'visible' : 'hidden'\"\n class=\"{{ prefixCls }}-super-next-btn\"\n role=\"button\"\n type=\"button\"\n tabindex=\"-1\"\n title=\"{{ superNextTitle() }}\"\n (click)=\"superNext()\"\n >\n <span class=\"ant-picker-super-next-icon\"></span>\n </button>\n</div>\n" }]
}] });
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
class YearTableComponent extends AbstractTable {
constructor(dateHelper) {
super();
this.dateHelper = dateHelper;
this.MAX_ROW = 4;
this.MAX_COL = 3;
}
makeHeadRow() {
return [];
}
makeBodyRows() {
const currentYear = this.activeDate && this.activeDate.getYear();
const startYear = parseInt(`${currentYear / 10}`, 10) * 10;
const endYear = startYear + 9;
const previousYear = startYear - 1;
const years = [];
let yearValue = 0;
for (let rowIndex = 0; rowIndex < this.MAX_ROW; rowIndex++) {
const row = {
dateCells: [],
trackByIndex: rowIndex
};
for (let colIndex = 0; colIndex < this.MAX_COL; colIndex++) {
const yearNum = previousYear + yearValue;
const year = this.activeDate.setYear(yearNum);
const content = this.dateHelper.format(year.nativeDate, 'yyyy');
const isDisabled = this.isDisabledYear(year);
const cell = {
trackByIndex: colIndex,
value: year.nativeDate,
isDisabled,
isSameDecade: yearNum >= startYear && yearNum <= endYear,
isSelected: yearNum === (this.value && this.value.getYear()),
content,
title: content,
classMap: {},
isLastCellInPanel: year.getYear() === endYear,
isFirstCellInPanel: year.getYear() === startYear,
cellRender: valueFunctionProp(this.cellRender, year),
fullCellRender: valueFunctionProp(this.fullCellRender, year),
onClick: () => this.chooseYear(cell.value.getFullYear()),
onMouseEnter: () => this.cellHover.emit(year)
};
this.addCellProperty(cell, year);
row.dateCells.push(cell);
yearValue++;
}
years.push(row);
}
return years;
}
getClassMap(cell) {
return {
...super.getClassMap(cell),
[`ant-picker-cell-in-view`]: !!cell.isSameDecade
};
}
isDisabledYear(year) {
if (!this.disabledDate) {
return false;
}
const firstOfMonth = year.setMonth(0).setDate(1);
for (let date = firstOfMonth; date.getYear() === year.getYear(); date = date.addDays(1)) {
if (!this.disabledDate(date.nativeDate)) {
return false;
}
}
return true;
}
addCellProperty(cell, year) {
if (this.hasRangeValue()) {
const [startHover, endHover] = this.hoverValue;
const [startSelected, endSelected] = this.selectedValue;
// Selected
if (startSelected?.isSameYear(year)) {
cell.isSelectedStart = true;
cell.isSelected = true;
}
if (endSelected?.isSameYear(year)) {
cell.isSelectedEnd = true;
cell.isSelected = true;
}
if (startHover && endHover) {
cell.isHoverStart = startHover.isSameYear(year);
cell.isHoverEnd = endHover.isSameYear(year);
cell.isInHoverRange = startHover.isBeforeYear(year) && year.isBeforeYear(endHover);
}
cell.isStartSingle = startSelected && !endSelected;
cell.isEndSingle = !startSelected && endSelected;
cell.isInSelectedRange = startSelected?.isBeforeYear(year) && year?.isBeforeYear(endSelected);
cell.isRangeStartNearHover = startSelected && cell.isInHoverRange;
cell.isRangeEndNearHover = endSelected && cell.isInHoverRange;
}
else if (year.isSameYear(this.value)) {
cell.isSelected = true;
}
cell.classMap = this.getClassMap(cell);
}
chooseYear(year) {
this.value = this.activeDate.setYear(year);
this.valueChange.emit(this.value);
this.render();
}
}
YearTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: YearTableComponent, deps: [{ token: i1.DateHelperService }], target: i0.ɵɵFactoryTarget.Component });
YearTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: YearTableComponent, selector: "year-table", exportAs: ["yearTable"], usesInheritance: true, ngImport: i0, template: "<table class=\"ant-picker-content\" cellspacing=\"0\" role=\"grid\">\n <thead *ngIf=\"headRow && headRow.length > 0\">\n <tr role=\"row\">\n <th *ngIf=\"showWeek\" role=\"columnheader\"></th>\n <th *ngFor=\"let cell of headRow\" role=\"columnheader\" title=\"{{ cell.title }}\">\n {{ cell.content }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of bodyRows; trackBy: trackByBodyRow\" [ngClass]=\"row.classMap!\" role=\"row\">\n <td *ngIf=\"row.weekNum\" role=\"gridcell\" class=\"{{ prefixCls }}-cell-week\">\n {{ row.weekNum }}\n </td>\n <td\n *ngFor=\"let cell of row.dateCells; trackBy: trackByBodyColumn\"\n title=\"{{ cell.title }}\"\n role=\"gridcell\"\n [ngClass]=\"cell.classMap!\"\n (click)=\"cell.isDis