ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
864 lines (847 loc) • 212 kB
JavaScript
import * as i0 from '@angular/core';
import { EventEmitter, booleanAttribute, Output, Input, ChangeDetectionStrategy, ViewEncapsulation, Component, Injectable, Directive, inject, NgModule, computed, signal, forwardRef, ViewChildren, ViewChild } from '@angular/core';
import { NgTemplateOutlet, DOCUMENT } from '@angular/common';
import * as i2 from 'ng-zorro-antd/button';
import { NzButtonModule } from 'ng-zorro-antd/button';
import * as i10 from 'ng-zorro-antd/core/outlet';
import { NzStringTemplateOutletDirective, NzOutletModule } from 'ng-zorro-antd/core/outlet';
import { CandyDate, normalizeRangeValue, cloneDate, wrongSortOrder } from 'ng-zorro-antd/core/time';
import * as i1 from 'ng-zorro-antd/i18n';
import { DateHelperService, NzI18nService } from 'ng-zorro-antd/i18n';
import * as i3 from 'ng-zorro-antd/core/transition-patch';
import * as i4 from 'ng-zorro-antd/core/wave';
import { __esDecorate, __runInitializers } from 'tslib';
import { ESCAPE } from '@angular/cdk/keycodes';
import { CdkConnectedOverlay } from '@angular/cdk/overlay';
import * as i9 from '@angular/forms';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ReplaySubject, Subject, merge, of } from 'rxjs';
import { takeUntil, distinctUntilChanged, withLatestFrom, map } 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 { NzFormStatusService, NzFormNoStatusService, NzFormItemFeedbackIconComponent } from 'ng-zorro-antd/core/form';
import { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation';
import * as i12 from 'ng-zorro-antd/core/overlay';
import { DEFAULT_DATE_PICKER_POSITIONS, DATE_PICKER_POSITION_MAP, NzOverlayModule } from 'ng-zorro-antd/core/overlay';
import * as i6 from 'ng-zorro-antd/core/services';
import { NzDestroyService } from 'ng-zorro-antd/core/services';
import { valueFunctionProp, fromEventOutsideAngular, toBoolean, getStatusClassNames } from 'ng-zorro-antd/core/util';
import * as i11$1 from 'ng-zorro-antd/icon';
import { NzIconModule } from 'ng-zorro-antd/icon';
import * as i8 from 'ng-zorro-antd/space';
import { NZ_SPACE_COMPACT_SIZE, NZ_SPACE_COMPACT_ITEM_TYPE, NzSpaceCompactItemDirective } from 'ng-zorro-antd/space';
import * as i11 from 'ng-zorro-antd/time-picker';
import { NzTimePickerModule } from 'ng-zorro-antd/time-picker';
import { startOfQuarter } from 'date-fns';
import * as i4$1 from 'ng-zorro-antd/cdk/resize-observer';
import * as i5 from '@angular/cdk/platform';
import * as i7 from '@angular/cdk/bidi';
/**
* 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 {
dateHelper;
locale;
showToday = false;
showNow = false;
hasTimePicker = false;
isRange = false;
okDisabled = false;
disabledDate;
extraFooter;
rangeQuickSelector = null;
clickOk = new EventEmitter();
clickToday = new EventEmitter();
prefixCls = PREFIX_CLASS;
isTodayDisabled = false;
todayTitle = '';
constructor(dateHelper) {
this.dateHelper = dateHelper;
}
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
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: CalendarFooterComponent, deps: [{ token: i1.DateHelperService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.2", type: CalendarFooterComponent, isStandalone: true, selector: "calendar-footer", inputs: { locale: "locale", showToday: ["showToday", "showToday", booleanAttribute], showNow: ["showNow", "showNow", booleanAttribute], hasTimePicker: ["hasTimePicker", "hasTimePicker", booleanAttribute], isRange: ["isRange", "isRange", booleanAttribute], okDisabled: ["okDisabled", "okDisabled", booleanAttribute], disabledDate: "disabledDate", extraFooter: "extraFooter", rangeQuickSelector: "rangeQuickSelector" }, outputs: { clickOk: "clickOk", clickToday: "clickToday" }, exportAs: ["calendarFooter"], usesOnChanges: true, ngImport: i0, template: `
<div class="{{ prefixCls }}-footer">
@if (extraFooter) {
<div class="{{ prefixCls }}-footer-extra">
<ng-template [nzStringTemplateOutlet]="extraFooter">{{ extraFooter }}</ng-template>
</div>
}
@if (showToday) {
<a
class="{{ prefixCls }}-today-btn {{ isTodayDisabled ? prefixCls + '-today-btn-disabled' : '' }}"
role="button"
(click)="isTodayDisabled ? null : onClickToday()"
title="{{ todayTitle }}"
>
{{ locale.today }}
</a>
}
@if (hasTimePicker || rangeQuickSelector) {
<ul class="{{ prefixCls }}-ranges">
<ng-container *ngTemplateOutlet="rangeQuickSelector" />
@if (showNow) {
<li class="{{ prefixCls }}-now">
<a class="{{ prefixCls }}-now-btn" (click)="isTodayDisabled ? null : onClickToday()">
{{ locale.now }}
</a>
</li>
}
@if (hasTimePicker) {
<li 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, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i2.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i3.ɵNzTransitionPatchDirective, selector: "[nz-button], nz-button-group, [nz-icon], nz-icon, [nz-menu-item], [nz-submenu], nz-select-top-control, nz-select-placeholder, nz-input-group", inputs: ["hidden"] }, { kind: "directive", type: i4.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "directive", type: NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: CalendarFooterComponent, decorators: [{
type: Component,
args: [{
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'calendar-footer',
exportAs: 'calendarFooter',
imports: [NgTemplateOutlet, NzButtonModule, NzStringTemplateOutletDirective],
template: `
<div class="{{ prefixCls }}-footer">
@if (extraFooter) {
<div class="{{ prefixCls }}-footer-extra">
<ng-template [nzStringTemplateOutlet]="extraFooter">{{ extraFooter }}</ng-template>
</div>
}
@if (showToday) {
<a
class="{{ prefixCls }}-today-btn {{ isTodayDisabled ? prefixCls + '-today-btn-disabled' : '' }}"
role="button"
(click)="isTodayDisabled ? null : onClickToday()"
title="{{ todayTitle }}"
>
{{ locale.today }}
</a>
}
@if (hasTimePicker || rangeQuickSelector) {
<ul class="{{ prefixCls }}-ranges">
<ng-container *ngTemplateOutlet="rangeQuickSelector" />
@if (showNow) {
<li class="{{ prefixCls }}-now">
<a class="{{ prefixCls }}-now-btn" (click)="isTodayDisabled ? null : onClickToday()">
{{ locale.now }}
</a>
</li>
}
@if (hasTimePicker) {
<li 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>
`,
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
}]
}], ctorParameters: () => [{ type: i1.DateHelperService }], propDecorators: { locale: [{
type: Input
}], showToday: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], showNow: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], hasTimePicker: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], isRange: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], okDisabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], 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 {
initialValue;
value;
activeDate;
activeInput = 'left';
arrowLeft = 0;
isRange = false;
valueChange$ = new ReplaySubject(1);
emitValue$ = new Subject();
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',
quarter: '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();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: DatePickerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: DatePickerService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", 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
*/
class AbstractPanelHeader {
prefixCls = `ant-picker-header`;
selectors = [];
mode;
value;
locale;
showSuperPreBtn = true;
showSuperNextBtn = true;
showPreBtn = true;
showNextBtn = true;
panelChange = new EventEmitter();
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.changeMode(this.mode);
this.render();
}
}
changeMode(mode) {
this.panelChange.emit({ mode, date: this.value.nativeDate });
}
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();
}
}
trackBySelector(selector) {
return `${selector.title}-${selector.label}`;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AbstractPanelHeader, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.2.2", type: AbstractPanelHeader, isStandalone: true, inputs: { value: "value", locale: "locale", showSuperPreBtn: ["showSuperPreBtn", "showSuperPreBtn", booleanAttribute], showSuperNextBtn: ["showSuperNextBtn", "showSuperNextBtn", booleanAttribute], showPreBtn: ["showPreBtn", "showPreBtn", booleanAttribute], showNextBtn: ["showNextBtn", "showNextBtn", booleanAttribute] }, outputs: { panelChange: "panelChange", valueChange: "valueChange" }, usesOnChanges: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AbstractPanelHeader, decorators: [{
type: Directive
}], propDecorators: { value: [{
type: Input
}], locale: [{
type: Input
}], showSuperPreBtn: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], showSuperNextBtn: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], showPreBtn: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], showNextBtn: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], panelChange: [{
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() { }
mode = 'decade';
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: () => { },
label: `${this.startYear}-${this.endYear}`
}
];
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: DecadeHeaderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.2", type: DecadeHeaderComponent, isStandalone: true, 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 @for (selector of selectors; track trackBySelector(selector)) {\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 }\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", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", 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 @for (selector of selectors; track trackBySelector(selector)) {\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 }\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 AbstractTable {
headRow = [];
bodyRows = [];
MAX_ROW = 6;
MAX_COL = 7;
prefixCls = 'ant-picker';
value;
locale;
activeDate = new CandyDate();
showWeek = false;
selectedValue = []; // Range ONLY
hoverValue = []; // Range ONLY
disabledDate;
cellRender;
fullCellRender;
canSelectWeek = false;
valueChange = new EventEmitter();
cellHover = new EventEmitter(); // Emitted when hover on a day by mouse enter
render() {
if (this.activeDate) {
this.headRow = this.makeHeadRow();
this.bodyRows = this.makeBodyRows();
}
}
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 ||
changes.selectWeek ||
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));
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AbstractTable, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.2.2", type: AbstractTable, isStandalone: true, inputs: { prefixCls: "prefixCls", value: "value", locale: "locale", activeDate: "activeDate", showWeek: ["showWeek", "showWeek", booleanAttribute], selectedValue: "selectedValue", hoverValue: "hoverValue", disabledDate: "disabledDate", cellRender: "cellRender", fullCellRender: "fullCellRender", canSelectWeek: ["canSelectWeek", "canSelectWeek", booleanAttribute] }, outputs: { valueChange: "valueChange", cellHover: "cellHover" }, usesOnChanges: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: AbstractTable, decorators: [{
type: Directive
}], propDecorators: { prefixCls: [{
type: Input
}], value: [{
type: Input
}], locale: [{
type: Input
}], activeDate: [{
type: Input
}], showWeek: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], selectedValue: [{
type: Input
}], hoverValue: [{
type: Input
}], disabledDate: [{
type: Input
}], cellRender: [{
type: Input
}], fullCellRender: [{
type: Input
}], canSelectWeek: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], 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);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: DecadeTableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.2", type: DecadeTableComponent, isStandalone: true, selector: "decade-table", exportAs: ["decadeTable"], usesInheritance: true, ngImport: i0, template: "<table class=\"ant-picker-content\" cellspacing=\"0\" role=\"grid\">\n @if (headRow && headRow.length > 0) {\n <thead>\n <tr role=\"row\">\n @if (showWeek) {\n <th role=\"columnheader\"></th>\n }\n @for (cell of headRow; track $index) {\n <th role=\"columnheader\" [title]=\"cell.title\"> {{ cell.content }}</th>\n }\n </tr>\n </thead>\n }\n\n <tbody>\n @for (row of bodyRows; track row.trackByIndex) {\n <tr [class]=\"row.classMap!\" role=\"row\">\n @if (row.weekNum) {\n <td role=\"gridcell\" class=\"{{ prefixCls }}-cell-week\"> {{ row.weekNum }}</td>\n }\n @for (cell of row.dateCells; track cell.trackByIndex) {\n <td\n [title]=\"cell.title\"\n role=\"gridcell\"\n [class]=\"cell.classMap!\"\n (click)=\"cell.isDisabled ? null : cell.onClick()\"\n (mouseenter)=\"cell.onMouseEnter()\"\n >\n @switch (prefixCls) {\n @case ('ant-picker') {\n @if (cell.cellRender) {\n <ng-template\n [nzStringTemplateOutlet]=\"cell.cellRender\"\n [nzStringTemplateOutletContext]=\"{ $implicit: cell.value }\"\n >\n {{ cell.cellRender }}\n </ng-template>\n } @else {\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 }\n }\n @case ('ant-picker-calendar') {\n <div\n class=\"{{ prefixCls }}-date ant-picker-cell-inner\"\n [class.ant-picker-calendar-date-today]=\"cell.isToday\"\n >\n @if (cell.fullCellRender) {\n <ng-container *nzStringTemplateOutlet=\"cell.fullCellRender; context: { $implicit: cell.value }\">\n {{ cell.fullCellRender }}\n </ng-container>\n } @else {\n <div class=\"{{ prefixCls }}-date-value\">{{ cell.content }}</div>\n <div class=\"{{ prefixCls }}-date-content\">\n <ng-container *nzStringTemplateOutlet=\"cell.cellRender; context: { $implicit: cell.value }\">\n {{ cell.cellRender }}\n </ng-container>\n </div>\n }\n </div>\n }\n }\n </td>\n }\n </tr>\n }\n </tbody>\n</table>\n", dependencies: [{ kind: "directive", type: NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: DecadeTableComponent, decorators: [{
type: Component,
args: [{ encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, selector: 'decade-table', exportAs: 'decadeTable', imports: [NzStringTemplateOutletDirective], template: "<table class=\"ant-picker-content\" cellspacing=\"0\" role=\"grid\">\n @if (headRow && headRow.length > 0) {\n <thead>\n <tr role=\"row\">\n @if (showWeek) {\n <th role=\"columnheader\"></th>\n }\n @for (cell of headRow; track $index) {\n <th role=\"columnheader\" [title]=\"cell.title\"> {{ cell.content }}</th>\n }\n </tr>\n </thead>\n }\n\n <tbody>\n @for (row of bodyRows; track row.trackByIndex) {\n <tr [class]=\"row.classMap!\" role=\"row\">\n @if (row.weekNum) {\n <td role=\"gridcell\" class=\"{{ prefixCls }}-cell-week\"> {{ row.weekNum }}</td>\n }\n @for (cell of row.dateCells; track cell.trackByIndex) {\n <td\n [title]=\"cell.title\"\n role=\"gridcell\"\n [class]=\"cell.classMap!\"\n (click)=\"cell.isDisabled ? null : cell.onClick()\"\n (mouseenter)=\"cell.onMouseEnter()\"\n >\n @switch (prefixCls) {\n @case ('ant-picker') {\n @if (cell.cellRender) {\n <ng-template\n [nzStringTemplateOutlet]=\"cell.cellRender\"\n [nzStringTemplateOutletContext]=\"{ $implicit: cell.value }\"\n >\n {{ cell.cellRender }}\n </ng-template>\n } @else {\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 }\n }\n @case ('ant-picker-calendar') {\n <div\n class=\"{{ prefixCls }}-date ant-picker-cell-inner\"\n [class.ant-picker-calendar-date-today]=\"cell.isToday\"\n >\n @if (cell.fullCellRender) {\n <ng-container *nzStringTemplateOutlet=\"cell.fullCellRender; context: { $implicit: cell.value }\">\n {{ cell.fullCellRender }}\n </ng-container>\n } @else {\n <div class=\"{{ prefixCls }}-date-value\">{{ cell.content }}</div>\n <div class=\"{{ prefixCls }}-date-content\">\n <ng-container *nzStringTemplateOutlet=\"cell.cellRender; context: { $implicit: cell.value }\">\n {{ cell.cellRender }}\n </ng-container>\n </div>\n }\n </div>\n }\n }\n </td>\n }\n </tr>\n }\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 {
mode = 'year';
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.mode = 'decade';
this.changeMode('decade');
},
label: `${this.startYear}-${this.endYear}`
}
];
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: YearHeaderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.2", type: YearHeaderComponent, isStandalone: true, 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 @for (selector of selectors; track trackBySelector(selector)) {\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 }\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", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", 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 @for (selector of selectors; track trackBySelector(selector)) {\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 }\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 {
dateHelper;
MAX_ROW = 4;
MAX_COL = 3;
constructor(dateHelper) {
super();
this.dateHelper = dateHelper;
}
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), // Customized content
fullCellRender: valueFunctionProp(this.fullCellRender, year),
onClick: () => this.chooseYear(cell.value.getFullYear()), // don't use yearValue here,
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();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: YearTableComponent, deps: [{ token: i1.DateHelperService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.2", type: YearTableComponent, isStandalone: true, selector: "year-table", exportAs: ["yearTable"], usesInheritance: true, ngImport: i0, template: "<table class=\"ant-picker-content\" cellspacing=\"0\" role=\"grid\">\n @if (headRow && headRow.length > 0) {\n <thead>\n <tr role=\"row\">\n @if (showWeek) {\n <th role=\"columnheader\"></th>\n }\n @for (cell of headRow; track $index) {\n <th role=\"columnheader\" [title]=\"cell.title\"> {{ cell.content }}</th>\n }\n </tr>\n </thead>\n }\n\n <tbody>\n @for (row of bodyRows; track row.trackByIndex) {\n <tr [class]=\"row.classMap!\" role=\"row\">\n @if (row.weekNum) {\n <td role=\"gridcell\" class=\"{{ prefixCls }}-cell-week\"> {{ row.weekNum }}</td>\n }\n @for (cell of row.dateCells; track cell.trackByIndex) {\n <td\n [title]=\"cell.title\"\n role=\"gridcell\"\n [class]=\"cell.classMap!\"\n (click)=\"cell.isDisabled ? null : cell.onClick()\"\n (mouseenter)=\"cell.onM