@bimeister/pupakit.calendar
Version:
PupaKit Calendar
617 lines (584 loc) • 102 kB
JavaScript
import * as i6 from '@angular/cdk/scrolling';
import { CdkVirtualScrollViewport, VIRTUAL_SCROLL_STRATEGY, ScrollingModule } from '@angular/cdk/scrolling';
import * as i3 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input, InjectionToken, Injectable, Optional, Inject, EventEmitter, Output, Pipe, ViewChild, NgModule } from '@angular/core';
import * as i2 from '@bimeister/pupakit.common';
import { PupaDirectivesModule, PupaPipesModule } from '@bimeister/pupakit.common';
import * as i1 from '@bimeister/pupakit.icons';
import { PupaIconsModule, appChevronDownIcon, appChevronUpIcon, iosRadioButtonOffIcon } from '@bimeister/pupakit.icons';
import * as i5 from '@bimeister/pupakit.kit';
import { PupaButtonsModule, PupaScrollableModule } from '@bimeister/pupakit.kit';
import { BehaviorSubject, combineLatest, Subject, throwError, Subscription } from 'rxjs';
import { switchMap, map, startWith, take, distinctUntilChanged } from 'rxjs/operators';
import { isEmpty, isNil, filterNotNil, shareReplayWithRefCount, filterTruthy, filterNotEmpty } from '@bimeister/utilities';
import '@angular/cdk/collections';
import { trigger, transition, style, animate } from '@angular/animations';
class CalendarCellEmptyComponent {
constructor() {
this.isInRange = false;
}
}
CalendarCellEmptyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarCellEmptyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
CalendarCellEmptyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CalendarCellEmptyComponent, selector: "pupa-calendar-cell-empty", inputs: { isInRange: "isInRange" }, ngImport: i0, template: "<div class=\"cell\" [class.cell_in-range]=\"isInRange\"></div>\n", styles: [".cell{flex-shrink:0;display:flex;justify-content:center;align-items:center;height:7rem;width:7rem;content:\"\"}.cell_in-range{background-color:rgba(var(--semantic-color_surface-tertiary),var(--semantic-color-alpha_surface-tertiary))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarCellEmptyComponent, decorators: [{
type: Component,
args: [{ selector: 'pupa-calendar-cell-empty', encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cell\" [class.cell_in-range]=\"isInRange\"></div>\n", styles: [".cell{flex-shrink:0;display:flex;justify-content:center;align-items:center;height:7rem;width:7rem;content:\"\"}.cell_in-range{background-color:rgba(var(--semantic-color_surface-tertiary),var(--semantic-color-alpha_surface-tertiary))}\n"] }]
}], propDecorators: { isInRange: [{
type: Input
}] } });
class CalendarCellSeparatorComponent {
constructor() {
this.isInRange = false;
}
}
CalendarCellSeparatorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarCellSeparatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
CalendarCellSeparatorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CalendarCellSeparatorComponent, selector: "pupa-calendar-cell-separator", inputs: { isInRange: "isInRange" }, ngImport: i0, template: "<div class=\"filler\" [class.filler_in-range]=\"isInRange\"></div>\n", styles: [":host{width:100%;height:100%;display:block;flex-grow:1}.filler{width:100%;height:100%;display:block;content:\"\"}.filler_in-range{background-color:rgba(var(--semantic-color_surface-tertiary),var(--semantic-color-alpha_surface-tertiary))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarCellSeparatorComponent, decorators: [{
type: Component,
args: [{ selector: 'pupa-calendar-cell-separator', encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"filler\" [class.filler_in-range]=\"isInRange\"></div>\n", styles: [":host{width:100%;height:100%;display:block;flex-grow:1}.filler{width:100%;height:100%;display:block;content:\"\"}.filler_in-range{background-color:rgba(var(--semantic-color_surface-tertiary),var(--semantic-color-alpha_surface-tertiary))}\n"] }]
}], propDecorators: { isInRange: [{
type: Input
}] } });
class CalendarCellComponent {
}
CalendarCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
CalendarCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CalendarCellComponent, selector: "pupa-calendar-cell", inputs: { positionInRange: "positionInRange" }, ngImport: i0, template: "<div class=\"cell\" [ngClass]=\"'cell_in-range-' + positionInRange\">\n <ng-content></ng-content>\n</div>\n", styles: [".cell{flex-shrink:0;display:flex;justify-content:center;align-items:center;height:7rem;width:7rem}.cell_in-range-first{border-top-left-radius:1rem;border-bottom-left-radius:1rem;background-color:rgba(var(--semantic-color_surface-tertiary),var(--semantic-color-alpha_surface-tertiary))}.cell_in-range-inside{background-color:rgba(var(--semantic-color_surface-tertiary),var(--semantic-color-alpha_surface-tertiary))}.cell_in-range-last{border-top-right-radius:1rem;border-bottom-right-radius:1rem;background-color:rgba(var(--semantic-color_surface-tertiary),var(--semantic-color-alpha_surface-tertiary))}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarCellComponent, decorators: [{
type: Component,
args: [{ selector: 'pupa-calendar-cell', encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cell\" [ngClass]=\"'cell_in-range-' + positionInRange\">\n <ng-content></ng-content>\n</div>\n", styles: [".cell{flex-shrink:0;display:flex;justify-content:center;align-items:center;height:7rem;width:7rem}.cell_in-range-first{border-top-left-radius:1rem;border-bottom-left-radius:1rem;background-color:rgba(var(--semantic-color_surface-tertiary),var(--semantic-color-alpha_surface-tertiary))}.cell_in-range-inside{background-color:rgba(var(--semantic-color_surface-tertiary),var(--semantic-color-alpha_surface-tertiary))}.cell_in-range-last{border-top-right-radius:1rem;border-bottom-right-radius:1rem;background-color:rgba(var(--semantic-color_surface-tertiary),var(--semantic-color-alpha_surface-tertiary))}\n"] }]
}], propDecorators: { positionInRange: [{
type: Input
}] } });
var CalendarQuickSelectMode;
(function (CalendarQuickSelectMode) {
CalendarQuickSelectMode["Month"] = "Month";
CalendarQuickSelectMode["Year"] = "Year";
})(CalendarQuickSelectMode || (CalendarQuickSelectMode = {}));
var CalendarTextKey;
(function (CalendarTextKey) {
CalendarTextKey["SelectYear"] = "SelectYear";
CalendarTextKey["SelectMonth"] = "SelectMonth";
})(CalendarTextKey || (CalendarTextKey = {}));
var DayOfWeek;
(function (DayOfWeek) {
DayOfWeek[DayOfWeek["Sunday"] = 0] = "Sunday";
DayOfWeek[DayOfWeek["Monday"] = 1] = "Monday";
DayOfWeek[DayOfWeek["Tuesday"] = 2] = "Tuesday";
DayOfWeek[DayOfWeek["Wednesday"] = 3] = "Wednesday";
DayOfWeek[DayOfWeek["Thursday"] = 4] = "Thursday";
DayOfWeek[DayOfWeek["Friday"] = 5] = "Friday";
DayOfWeek[DayOfWeek["Saturday"] = 6] = "Saturday";
})(DayOfWeek || (DayOfWeek = {}));
const MONTHS_IN_YEAR = 12;
const SMALL_CALENDAR_CYCLE_SIZE_IN_YEARS = 28;
const DEFAULT_CALENDAR_CONFIG = {
startWeekday: DayOfWeek.Monday,
yearsRange: SMALL_CALENDAR_CYCLE_SIZE_IN_YEARS * 7,
translations: {
en: {
weekdays: {
[DayOfWeek.Sunday]: 'Su',
[DayOfWeek.Monday]: 'Mo',
[DayOfWeek.Tuesday]: 'Tu',
[DayOfWeek.Wednesday]: 'We',
[DayOfWeek.Thursday]: 'Th',
[DayOfWeek.Friday]: 'Fr',
[DayOfWeek.Saturday]: 'Sa',
},
months: {
[0]: 'January',
[1]: 'February',
[2]: 'March',
[3]: 'April',
[4]: 'May',
[5]: 'June',
[6]: 'July',
[7]: 'August',
[8]: 'September',
[9]: 'October',
[10]: 'November',
[11]: 'December',
},
texts: {
[CalendarTextKey.SelectYear]: 'Select year',
[CalendarTextKey.SelectMonth]: 'Select month',
},
},
},
};
const CALENDAR_CONFIG_TOKEN = new InjectionToken('CALENDAR_CONFIG_TOKEN');
const LABEL_HEIGHT_PX = 16;
const DIVIDER_HEIGHT_PX$1 = 12;
const WEEK_HEIGHT_PX = 36;
const BUFFER_PX = 500;
class CalendarConfigService {
constructor(config) {
var _a, _b, _c;
this.startWeekday = (_a = config === null || config === void 0 ? void 0 : config.startWeekday) !== null && _a !== void 0 ? _a : DEFAULT_CALENDAR_CONFIG.startWeekday;
this.startYear = (_b = config === null || config === void 0 ? void 0 : config.startYear) !== null && _b !== void 0 ? _b : CalendarConfigService.getDefaultStartYear();
CalendarConfigService.validateYearsRange(config === null || config === void 0 ? void 0 : config.yearsRange);
this.yearsRange = (_c = config === null || config === void 0 ? void 0 : config.yearsRange) !== null && _c !== void 0 ? _c : CalendarConfigService.getDefaultEndYear() - this.startYear;
this.endYear = this.startYear + this.yearsRange;
this.translations = !isEmpty(config === null || config === void 0 ? void 0 : config.translations) ? config.translations : DEFAULT_CALENDAR_CONFIG.translations;
}
get virtualScrollConfig() {
return {
bufferPx: BUFFER_PX,
yearsRange: this.yearsRange,
labelHeightPx: LABEL_HEIGHT_PX,
dividerHeightPx: DIVIDER_HEIGHT_PX$1,
weekHeightPx: WEEK_HEIGHT_PX,
startWeekday: this.startWeekday,
startYear: this.startYear,
};
}
static getDefaultStartYear() {
return new Date().getFullYear() - Math.floor(DEFAULT_CALENDAR_CONFIG.yearsRange / 2);
}
static getDefaultEndYear() {
return new Date().getFullYear() + Math.floor(DEFAULT_CALENDAR_CONFIG.yearsRange / 2);
}
static validateYearsRange(yearsRange) {
const isValid = isNil(yearsRange) || yearsRange % SMALL_CALENDAR_CYCLE_SIZE_IN_YEARS === 0;
if (isValid) {
return;
}
throw new Error(`[CalendarConfigService] 'yearsRange' must be a multiple of ${SMALL_CALENDAR_CYCLE_SIZE_IN_YEARS}`);
}
}
CalendarConfigService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarConfigService, deps: [{ token: CALENDAR_CONFIG_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
CalendarConfigService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarConfigService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarConfigService, decorators: [{
type: Injectable
}], ctorParameters: function () {
return [{ type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [CALENDAR_CONFIG_TOKEN]
}] }];
} });
class CalendarManipulatorService {
constructor(calendarConfigService) {
this.calendarConfigService = calendarConfigService;
this.virtualScrollViewport$ = new BehaviorSubject(null);
this.currentIndex$ = this.virtualScrollViewport$.pipe(filterNotNil(), switchMap((viewport) => viewport.scrolledIndexChange), shareReplayWithRefCount());
this.virtualScrollInitialized$ = this.currentIndex$.pipe(map(() => true), startWith(false), shareReplayWithRefCount());
this.currentCalendarMonth$ = this.currentIndex$.pipe(map((currentIndex) => {
const monthIndex = currentIndex % MONTHS_IN_YEAR;
const yearsCount = (currentIndex - monthIndex) / MONTHS_IN_YEAR;
return {
year: yearsCount + this.calendarConfigService.startYear,
month: monthIndex,
};
}));
}
get initialCalendarMonth() {
const currentDate = new Date();
return {
month: currentDate.getMonth(),
year: currentDate.getFullYear(),
};
}
get initialMonthIndex() {
const initialCalendarMonth = this.initialCalendarMonth;
return ((initialCalendarMonth.year - this.calendarConfigService.startYear) * MONTHS_IN_YEAR +
Number(initialCalendarMonth.month));
}
setVirtualScrollViewport(viewport) {
if (isNil(viewport)) {
throw new Error('[CalendarStateService] viewport can not be null or undefined');
}
this.virtualScrollViewport$.next(viewport);
}
clearVirtualScrollViewport() {
this.virtualScrollViewport$.next(null);
}
resetScroll(behavior) {
this.scrollToMonthByIndex(this.initialMonthIndex, behavior);
}
scrollToYear(year, behavior) {
const yearFirstMonthIndex = (year - this.calendarConfigService.startYear) * MONTHS_IN_YEAR;
this.scrollToMonthByIndex(yearFirstMonthIndex, behavior);
}
scrollToMonth(calendarMonth, behavior) {
const monthIndex = (calendarMonth.year - this.calendarConfigService.startYear) * MONTHS_IN_YEAR + Number(calendarMonth.month);
this.scrollToMonthByIndex(monthIndex, behavior);
}
scrollToNextMonth(behavior) {
this.currentIndex$.pipe(take(1)).subscribe((currentIndex) => {
this.scrollToMonthByIndex(currentIndex + 1, behavior);
});
}
scrollToPreviousMonth(behavior) {
this.currentIndex$.pipe(take(1)).subscribe((currentIndex) => {
this.scrollToMonthByIndex(currentIndex - 1, behavior);
});
}
scrollToMonthByIndex(index, behavior) {
this.virtualScrollInitialized$
.pipe(filterTruthy(), switchMap(() => this.virtualScrollViewport$), take(1))
.subscribe((viewport) => requestAnimationFrame(() => viewport.scrollToIndex(index, behavior)));
}
}
CalendarManipulatorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarManipulatorService, deps: [{ token: CalendarConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
CalendarManipulatorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarManipulatorService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarManipulatorService, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: CalendarConfigService }]; } });
const DEFAULT_LOCALE = 'en';
class CalendarTranslationService {
constructor(calendarConfigService, localeService) {
this.calendarConfigService = calendarConfigService;
this.localeService = localeService;
this.locale$ = this.localeService.locale$.pipe(startWith(DEFAULT_LOCALE));
this.translation$ = this.locale$.pipe(map((locale) => this.getTranslationByLocale(locale)), filterNotEmpty());
}
getTranslationByLocale(locale) {
var _a, _b;
return (_b = (_a = this.calendarConfigService.translations) === null || _a === void 0 ? void 0 : _a[locale]) !== null && _b !== void 0 ? _b : null;
}
}
CalendarTranslationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarTranslationService, deps: [{ token: CalendarConfigService }, { token: i2.LocaleService }], target: i0.ɵɵFactoryTarget.Injectable });
CalendarTranslationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarTranslationService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarTranslationService, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: CalendarConfigService }, { type: i2.LocaleService }]; } });
function getClearDate() {
const date = new Date(null);
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0);
return date;
}
function getSortedDates(dates, sortDirection) {
const compareFn = (first, second) => sortDirection === 'ascending' ? first - second : second - first;
return [...dates].sort((first, second) => compareFn(first.getTime(), second.getTime()));
}
const MULTI_SELECTION_DATES_COUNT = 2;
function getDateWithClearedTime(date) {
const clearDate = getClearDate();
clearDate.setFullYear(date.getFullYear());
clearDate.setMonth(date.getMonth());
clearDate.setDate(date.getDate());
return clearDate;
}
function findDateIndexInArray(array, date) {
return array.findIndex((item) => item.getTime() === date.getTime());
}
function getUniqDates(dates) {
return dates.filter((date, index, array) => {
const foundIndex = findDateIndexInArray(array, date);
return foundIndex === index;
});
}
function getProcessedDates(dates) {
return getSortedDates(getUniqDates(dates.map(getDateWithClearedTime)), 'ascending');
}
class CalendarStateService {
constructor() {
this.isRange = false;
this.selectedDates$ = new BehaviorSubject([]);
this.quickSelectMode$ = new BehaviorSubject(null);
}
setSelectedDates(dates) {
this.selectedDates$.next(getProcessedDates(dates));
}
addSelectedDate(newDate) {
const preparedDate = getDateWithClearedTime(newDate);
this.selectedDates$.pipe(take(1)).subscribe((selectedDates) => {
const updatedDates = this.isRange
? this.patchDatesForRangeSelection(selectedDates, preparedDate)
: [preparedDate];
this.selectedDates$.next(updatedDates);
});
}
patchDatesForRangeSelection(dates, newDate) {
const hasAlreadyAdded = findDateIndexInArray(dates, newDate) >= 0;
const isResetNeeded = dates.length >= MULTI_SELECTION_DATES_COUNT;
if (hasAlreadyAdded || isResetNeeded) {
return [newDate];
}
return getProcessedDates([...dates, newDate]);
}
setQuickSelectMode(mode) {
this.quickSelectMode$.next(mode);
}
resetQuickSelectMode() {
this.quickSelectMode$.next(null);
}
setIsRange(isRange) {
this.isRange = isRange;
}
}
CalendarStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
CalendarStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarStateService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarStateService, decorators: [{
type: Injectable
}] });
class CalendarControlPanelComponent {
constructor(calendarManipulatorService, calendarTranslationService, calendarStateService) {
this.calendarManipulatorService = calendarManipulatorService;
this.calendarTranslationService = calendarTranslationService;
this.calendarStateService = calendarStateService;
this.monthTranslationByIndex$ = this.calendarTranslationService.translation$.pipe(map((translation) => translation.months));
this.displayedMonth$ = combineLatest([
this.calendarManipulatorService.currentCalendarMonth$,
this.monthTranslationByIndex$,
]).pipe(map(([calendarMonth, monthTranslationByIndex]) => ({
year: calendarMonth.year,
month: monthTranslationByIndex[calendarMonth.month],
})));
}
resetScroll() {
this.calendarManipulatorService.resetScroll('smooth');
}
scrollToNextMonth() {
this.calendarManipulatorService.scrollToNextMonth('smooth');
}
scrollToPreviousMonth() {
this.calendarManipulatorService.scrollToPreviousMonth('smooth');
}
setQuickSelectModeMonth() {
this.calendarStateService.setQuickSelectMode(CalendarQuickSelectMode.Month);
}
setQuickSelectModeYear() {
this.calendarStateService.setQuickSelectMode(CalendarQuickSelectMode.Year);
}
}
CalendarControlPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarControlPanelComponent, deps: [{ token: CalendarManipulatorService }, { token: CalendarTranslationService }, { token: CalendarStateService }], target: i0.ɵɵFactoryTarget.Component });
CalendarControlPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CalendarControlPanelComponent, selector: "pupa-calendar-control-panel", ngImport: i0, template: "<div class=\"selection\" *ngIf=\"displayedMonth$ | async as displayedMonth\">\n <pupa-button (click)=\"setQuickSelectModeMonth()\" kind=\"secondary\">\n {{ displayedMonth.month }}\n </pupa-button>\n\n <pupa-button (click)=\"setQuickSelectModeYear()\" kind=\"secondary\">\n {{ displayedMonth.year }}\n </pupa-button>\n</div>\n\n<div class=\"navigation\">\n <pupa-button-icon size=\"m\" kind=\"secondary\" icon=\"app-chevron-down\" (click)=\"scrollToNextMonth()\"></pupa-button-icon>\n\n <pupa-button-icon size=\"m\" kind=\"secondary\" icon=\"ios-radio-button-off\" (click)=\"resetScroll()\"></pupa-button-icon>\n\n <pupa-button-icon\n size=\"m\"\n kind=\"secondary\"\n icon=\"app-chevron-up\"\n (click)=\"scrollToPreviousMonth()\"\n ></pupa-button-icon>\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:space-between;height:12rem;padding:0 3rem}.selection{display:flex}.navigation{display:flex;gap:1rem}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5.ButtonComponent, selector: "pupa-button", inputs: ["size", "kind", "type", "disabled", "icon", "iconPosition", "loading", "active", "tabIndex"] }, { kind: "component", type: i5.ButtonIconComponent, selector: "pupa-button-icon", inputs: ["size", "kind", "type", "disabled", "icon", "loading", "active", "tabIndex"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarControlPanelComponent, decorators: [{
type: Component,
args: [{ selector: 'pupa-calendar-control-panel', encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"selection\" *ngIf=\"displayedMonth$ | async as displayedMonth\">\n <pupa-button (click)=\"setQuickSelectModeMonth()\" kind=\"secondary\">\n {{ displayedMonth.month }}\n </pupa-button>\n\n <pupa-button (click)=\"setQuickSelectModeYear()\" kind=\"secondary\">\n {{ displayedMonth.year }}\n </pupa-button>\n</div>\n\n<div class=\"navigation\">\n <pupa-button-icon size=\"m\" kind=\"secondary\" icon=\"app-chevron-down\" (click)=\"scrollToNextMonth()\"></pupa-button-icon>\n\n <pupa-button-icon size=\"m\" kind=\"secondary\" icon=\"ios-radio-button-off\" (click)=\"resetScroll()\"></pupa-button-icon>\n\n <pupa-button-icon\n size=\"m\"\n kind=\"secondary\"\n icon=\"app-chevron-up\"\n (click)=\"scrollToPreviousMonth()\"\n ></pupa-button-icon>\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:space-between;height:12rem;padding:0 3rem}.selection{display:flex}.navigation{display:flex;gap:1rem}\n"] }]
}], ctorParameters: function () { return [{ type: CalendarManipulatorService }, { type: CalendarTranslationService }, { type: CalendarStateService }]; } });
class CalendarDayComponent {
constructor() {
this.value = null;
this.isDisabled = false;
this.isEmpty = false;
this.isCurrent = false;
this.isSelected = false;
this.select = new EventEmitter();
}
handleClick() {
this.select.emit();
}
}
CalendarDayComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarDayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
CalendarDayComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CalendarDayComponent, selector: "pupa-calendar-day", inputs: { value: "value", isDisabled: "isDisabled", isEmpty: "isEmpty", isCurrent: "isCurrent", isSelected: "isSelected" }, outputs: { select: "select" }, ngImport: i0, template: "<div\n class=\"day\"\n [class.day_disabled]=\"isDisabled\"\n [class.day_empty]=\"isEmpty\"\n [class.day_current]=\"isCurrent\"\n [class.day_selected]=\"isSelected\"\n (click)=\"handleClick()\"\n [tabindex]=\"isEmpty ? -1 : 0\"\n>\n {{ value }}\n</div>\n", styles: [":host{display:block;width:6rem;height:6rem;aspect-ratio:1/1}.day{display:flex;justify-content:center;align-items:center;flex-grow:0;flex-shrink:0;width:100%;height:100%;box-sizing:border-box;border-color:transparent;background-color:transparent;border-radius:1rem;cursor:pointer;transition:var(--transition-duration_shortest) var(--transition-timing-function_common);font-family:NotoSans,sans-serif;font-weight:400;font-size:11px;line-height:16px}@media (hover: hover){.day:hover{background-color:rgba(var(--semantic-color_kind-neutral-hover),var(--semantic-color-alpha_kind-neutral-hover))}}.day:active{background-color:rgba(var(--semantic-color_kind-neutral-pressed),var(--semantic-color-alpha_kind-neutral-pressed))}.day:focus-visible{border:1px solid rgba(var(--color_primary-600),var(--alpha-1000));outline:none}.day_current{border:1px solid rgba(var(--semantic-color_kind-primary-normal),var(--semantic-color-alpha_kind-primary-normal))}.day_selected{background-color:rgba(var(--semantic-color_kind-primary-normal),var(--semantic-color-alpha_kind-primary-normal));color:rgba(var(--semantic-color_text-inverse),var(--semantic-color-alpha_text-inverse));font-family:NotoSans,sans-serif;font-weight:500;font-size:11px;line-height:16px}@media (hover: hover){.day_selected:hover{background-color:rgba(var(--semantic-color_kind-primary-hover),var(--semantic-color-alpha_kind-primary-hover))}}.day_selected:active{background-color:rgba(var(--semantic-color_kind-primary-pressed),var(--semantic-color-alpha_kind-primary-pressed))}.day_disabled{color:rgba(var(--semantic-color_text-disabled),var(--semantic-color-alpha_text-disabled));background-color:transparent}@media (hover: hover){.day_disabled:hover{background-color:transparent}}.day_empty{cursor:default;background-color:transparent;color:transparent;border:none}@media (hover: hover){.day_empty:hover{border:none;background-color:transparent}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarDayComponent, decorators: [{
type: Component,
args: [{ selector: 'pupa-calendar-day', encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"day\"\n [class.day_disabled]=\"isDisabled\"\n [class.day_empty]=\"isEmpty\"\n [class.day_current]=\"isCurrent\"\n [class.day_selected]=\"isSelected\"\n (click)=\"handleClick()\"\n [tabindex]=\"isEmpty ? -1 : 0\"\n>\n {{ value }}\n</div>\n", styles: [":host{display:block;width:6rem;height:6rem;aspect-ratio:1/1}.day{display:flex;justify-content:center;align-items:center;flex-grow:0;flex-shrink:0;width:100%;height:100%;box-sizing:border-box;border-color:transparent;background-color:transparent;border-radius:1rem;cursor:pointer;transition:var(--transition-duration_shortest) var(--transition-timing-function_common);font-family:NotoSans,sans-serif;font-weight:400;font-size:11px;line-height:16px}@media (hover: hover){.day:hover{background-color:rgba(var(--semantic-color_kind-neutral-hover),var(--semantic-color-alpha_kind-neutral-hover))}}.day:active{background-color:rgba(var(--semantic-color_kind-neutral-pressed),var(--semantic-color-alpha_kind-neutral-pressed))}.day:focus-visible{border:1px solid rgba(var(--color_primary-600),var(--alpha-1000));outline:none}.day_current{border:1px solid rgba(var(--semantic-color_kind-primary-normal),var(--semantic-color-alpha_kind-primary-normal))}.day_selected{background-color:rgba(var(--semantic-color_kind-primary-normal),var(--semantic-color-alpha_kind-primary-normal));color:rgba(var(--semantic-color_text-inverse),var(--semantic-color-alpha_text-inverse));font-family:NotoSans,sans-serif;font-weight:500;font-size:11px;line-height:16px}@media (hover: hover){.day_selected:hover{background-color:rgba(var(--semantic-color_kind-primary-hover),var(--semantic-color-alpha_kind-primary-hover))}}.day_selected:active{background-color:rgba(var(--semantic-color_kind-primary-pressed),var(--semantic-color-alpha_kind-primary-pressed))}.day_disabled{color:rgba(var(--semantic-color_text-disabled),var(--semantic-color-alpha_text-disabled));background-color:transparent}@media (hover: hover){.day_disabled:hover{background-color:transparent}}.day_empty{cursor:default;background-color:transparent;color:transparent;border:none}@media (hover: hover){.day_empty:hover{border:none;background-color:transparent}}\n"] }]
}], propDecorators: { value: [{
type: Input
}], isDisabled: [{
type: Input
}], isEmpty: [{
type: Input
}], isCurrent: [{
type: Input
}], isSelected: [{
type: Input
}], select: [{
type: Output
}] } });
class CalendarHeaderComponent {
}
CalendarHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
CalendarHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CalendarHeaderComponent, selector: "pupa-calendar-header", ngImport: i0, template: "<ng-content></ng-content>\n", styles: [":host{display:block;width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarHeaderComponent, decorators: [{
type: Component,
args: [{ selector: 'pupa-calendar-header', encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>\n", styles: [":host{display:block;width:100%}\n"] }]
}] });
class CalendarLabelComponent {
}
CalendarLabelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
CalendarLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CalendarLabelComponent, selector: "pupa-calendar-label", ngImport: i0, template: "<ng-content></ng-content>\n", styles: [":host{display:block;font-size:12px;line-height:16px;font-family:NotoSans,sans-serif;font-weight:500}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarLabelComponent, decorators: [{
type: Component,
args: [{ selector: 'pupa-calendar-label', encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>\n", styles: [":host{display:block;font-size:12px;line-height:16px;font-family:NotoSans,sans-serif;font-weight:500}\n"] }]
}] });
class CalendarSelectorButtonComponent {
constructor() {
this.isCurrent = false;
}
}
CalendarSelectorButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarSelectorButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
CalendarSelectorButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CalendarSelectorButtonComponent, selector: "pupa-calendar-selector-button", inputs: { isCurrent: "isCurrent" }, ngImport: i0, template: "<button class=\"button\" [class.button_current]=\"isCurrent\">\n <ng-content></ng-content>\n</button>\n", styles: [".button{all:unset;display:flex;align-items:center;justify-content:center;width:100%;height:8rem;border-radius:1rem;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-tap-highlight-color:transparent;pointer-events:auto;-webkit-user-select:none;user-select:none;cursor:pointer;font-family:NotoSans,sans-serif;font-weight:500;font-size:11px;line-height:16px;color:rgba(var(--semantic-color_text-primary),var(--semantic-color-alpha_text-primary));transition:var(--transition-duration_shortest) var(--transition-timing-function_common)}@media (hover: hover){.button:hover{background-color:rgba(var(--semantic-color_kind-primary-hover),var(--semantic-color-alpha_kind-primary-hover));color:rgba(var(--semantic-color_surface-primary),var(--semantic-color-alpha_surface-primary))}}.button:active{background-color:rgba(var(--semantic-color_kind-primary-active),var(--semantic-color-alpha_kind-primary-active))}.button_current{border:1px solid rgba(var(--semantic-color_kind-primary-active),var(--semantic-color-alpha_kind-primary-active))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarSelectorButtonComponent, decorators: [{
type: Component,
args: [{ selector: 'pupa-calendar-selector-button', encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<button class=\"button\" [class.button_current]=\"isCurrent\">\n <ng-content></ng-content>\n</button>\n", styles: [".button{all:unset;display:flex;align-items:center;justify-content:center;width:100%;height:8rem;border-radius:1rem;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-tap-highlight-color:transparent;pointer-events:auto;-webkit-user-select:none;user-select:none;cursor:pointer;font-family:NotoSans,sans-serif;font-weight:500;font-size:11px;line-height:16px;color:rgba(var(--semantic-color_text-primary),var(--semantic-color-alpha_text-primary));transition:var(--transition-duration_shortest) var(--transition-timing-function_common)}@media (hover: hover){.button:hover{background-color:rgba(var(--semantic-color_kind-primary-hover),var(--semantic-color-alpha_kind-primary-hover));color:rgba(var(--semantic-color_surface-primary),var(--semantic-color-alpha_surface-primary))}}.button:active{background-color:rgba(var(--semantic-color_kind-primary-active),var(--semantic-color-alpha_kind-primary-active))}.button_current{border:1px solid rgba(var(--semantic-color_kind-primary-active),var(--semantic-color-alpha_kind-primary-active))}\n"] }]
}], propDecorators: { isCurrent: [{
type: Input
}] } });
function getCurrentCalendarMonth() {
const date = new Date();
return {
year: date.getFullYear(),
month: date.getMonth(),
};
}
const currentCalendarMonth = getCurrentCalendarMonth();
class IsCurrentCalendarMonthPipe {
transform({ year, month }) {
return month === currentCalendarMonth.month && year === currentCalendarMonth.year;
}
}
IsCurrentCalendarMonthPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IsCurrentCalendarMonthPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
IsCurrentCalendarMonthPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: IsCurrentCalendarMonthPipe, name: "isCurrentCalendarMonth" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: IsCurrentCalendarMonthPipe, decorators: [{
type: Pipe,
args: [{
name: 'isCurrentCalendarMonth',
pure: true,
}]
}] });
const DIVIDER_HEIGHT_PX = 12;
const YEAR_LABEL_HEIGHT_PX = 16;
const YEAR_TABLE_HEIGHT_PX = 188;
const ITEM_HEIGHT_PX = DIVIDER_HEIGHT_PX * 2 + YEAR_LABEL_HEIGHT_PX + YEAR_TABLE_HEIGHT_PX;
class CalendarMonthSelectorComponent {
constructor(calendarTranslationService, calendarConfigService) {
this.calendarTranslationService = calendarTranslationService;
this.calendarConfigService = calendarConfigService;
this.select = new EventEmitter();
this.virtualScrollViewport$ = new Subject();
this.headerTitle$ = this.calendarTranslationService.translation$.pipe(map((translation) => translation.texts[CalendarTextKey.SelectMonth]));
this.itemHeight = ITEM_HEIGHT_PX;
this.startYear = this.calendarConfigService.startYear;
this.currentYearInScroll$ = this.virtualScrollViewport$.pipe(switchMap((viewport) => viewport.scrolledIndexChange), map((index) => index + this.startYear));
this.yearsIndexes = Array.from({
length: this.calendarConfigService.yearsRange,
});
this.monthsIndexes = Array.from({ length: MONTHS_IN_YEAR });
this.monthNameByIndex$ = this.calendarTranslationService.translation$.pipe(map((translation) => translation.months));
}
ngAfterViewInit() {
this.scrollToCurrentYear();
if (!isNil(this.virtualScrollViewport)) {
this.virtualScrollViewport$.next(this.virtualScrollViewport);
}
}
selectMonth(year, month) {
this.select.emit({
year,
month,
});
}
scrollToCurrentYear() {
if (isNil(this.virtualScrollViewport)) {
return;
}
const currentYearIndex = new Date().getFullYear() - this.startYear;
requestAnimationFrame(() => {
this.virtualScrollViewport.scrollToIndex(currentYearIndex);
});
}
}
CalendarMonthSelectorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarMonthSelectorComponent, deps: [{ token: CalendarTranslationService }, { token: CalendarConfigService }], target: i0.ɵɵFactoryTarget.Component });
CalendarMonthSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CalendarMonthSelectorComponent, selector: "pupa-calendar-month-selector", outputs: { select: "select" }, viewQueries: [{ propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], ngImport: i0, template: "<pupa-calendar-header>\n <div class=\"header-content\">\n <h4 class=\"header-title\">\n {{ headerTitle$ | async }}\n </h4>\n\n <div class=\"year-label\">{{ currentYearInScroll$ | async }}</div>\n </div>\n</pupa-calendar-header>\n\n<div class=\"scroller-wrapper\">\n <cdk-virtual-scroll-viewport\n *pupaLet=\"monthNameByIndex$ | async as monthNameByIndex\"\n pupaScrollableContent\n class=\"scroller\"\n [itemSize]=\"itemHeight\"\n >\n <div\n class=\"scroller__item\"\n *cdkVirtualFor=\"let _ of yearsIndexes; templateCacheSize: 10; let isLast = last; let yearIndex = index\"\n >\n <div class=\"scroller__divider\"></div>\n\n <div class=\"year-table\">\n <div class=\"year-table__month\" *ngFor=\"let __ of monthsIndexes; let month = index\">\n <pupa-calendar-selector-button\n [isCurrent]=\"{ year: startYear + yearIndex, month } | isCurrentCalendarMonth\"\n (click)=\"selectMonth(startYear + yearIndex, month)\"\n >\n {{ monthNameByIndex[month] }}\n </pupa-calendar-selector-button>\n </div>\n </div>\n\n <ng-container *ngIf=\"!isLast\">\n <div class=\"scroller__divider\"></div>\n <div class=\"year-label\">{{ yearIndex + startYear + 1 }}</div>\n </ng-container>\n </div>\n </cdk-virtual-scroll-viewport>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;width:100%;position:absolute;z-index:2;top:0;left:0;right:0;bottom:0;background-color:rgba(var(--semantic-color_surface-primary),var(--semantic-color-alpha_surface-primary))}.header-content{flex-direction:column;box-sizing:border-box;padding:0 4rem}.header-title{display:flex;align-items:center;margin:0;height:12rem}.scroller-wrapper{width:100%;height:100%;box-sizing:border-box;display:block}.scroller{width:100%;height:100%;display:block;box-sizing:border-box}.scroller__item{padding:0rem 4rem}.scroller__divider{display:block;width:100%;height:3rem}.year-label{font-family:NotoSans,sans-serif;font-weight:400;font-size:11px;line-height:16px}.year-table{display:grid;grid-template-columns:repeat(3,1fr);column-gap:2rem;row-gap:5rem}.year-table__month{width:100%}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.ScrollableContentDirective, selector: "[pupaScrollableContent]" }, { kind: "directive", type: i2.LetDirective, selector: "[pupaLet]", inputs: ["pupaLet"] }, { kind: "directive", type: i6.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i6.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i6.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: CalendarHeaderComponent, selector: "pupa-calendar-header" }, { kind: "component", type: CalendarSelectorButtonComponent, selector: "pupa-calendar-selector-button", inputs: ["isCurrent"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: IsCurrentCalendarMonthPipe, name: "isCurrentCalendarMonth" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarMonthSelectorComponent, decorators: [{
type: Component,
args: [{ selector: 'pupa-calendar-month-selector', encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<pupa-calendar-header>\n <div class=\"header-content\">\n <h4 class=\"header-title\">\n {{ headerTitle$ | async }}\n </h4>\n\n <div class=\"year-label\">{{ currentYearInScroll$ | async }}</div>\n </div>\n</pupa-calendar-header>\n\n<div class=\"scroller-wrapper\">\n <cdk-virtual-scroll-viewport\n *pupaLet=\"monthNameByIndex$ | async as monthNameByIndex\"\n pupaScrollableContent\n class=\"scroller\"\n [itemSize]=\"itemHeight\"\n >\n <div\n class=\"scroller__item\"\n *cdkVirtualFor=\"let _ of yearsIndexes; templateCacheSize: 10; let isLast = last; let yearIndex = index\"\n >\n <div class=\"scroller__divider\"></div>\n\n <div class=\"year-table\">\n <div class=\"year-table__month\" *ngFor=\"let __ of monthsIndexes; let month = index\">\n <pupa-calendar-selector-button\n [isCurrent]=\"{ year: startYear + yearIndex, month } | isCurrentCalendarMonth\"\n (click)=\"selectMonth(startYear + yearIndex, month)\"\n >\n {{ monthNameByIndex[month] }}\n </pupa-calendar-selector-button>\n </div>\n </div>\n\n <ng-container *ngIf=\"!isLast\">\n <div class=\"scroller__divider\"></div>\n <div class=\"year-label\">{{ yearIndex + startYear + 1 }}</div>\n </ng-container>\n </div>\n </cdk-virtual-scroll-viewport>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;width:100%;position:absolute;z-index:2;top:0;left:0;right:0;bottom:0;background-color:rgba(var(--semantic-color_surface-primary),var(--semantic-color-alpha_surface-primary))}.header-content{flex-direction:column;box-sizing:border-box;padding:0 4rem}.header-title{display:flex;align-items:center;margin:0;height:12rem}.scroller-wrapper{width:100%;height:100%;box-sizing:border-box;display:block}.scroller{width:100%;height:100%;display:block;box-sizing:border-box}.scroller__item{padding:0rem 4rem}.scroller__divider{display:block;width:100%;height:3rem}.year-label{font-family:NotoSans,sans-serif;font-weight:400;font-size:11px;line-height:16px}.year-table{display:grid;grid-template-columns:repeat(3,1fr);column-gap:2rem;row-gap:5rem}.year-table__month{width:100%}\n"] }]
}], ctorParameters: function () { return [{ type: CalendarTranslationService }, { type: CalendarConfigService }]; }, propDecorators: { select: [{
type: Output
}], virtualScrollViewport: [{
type: ViewChild,
args: [CdkVirtualScrollViewport]
}] } });
function getDateFromCalendarDay({ year, month, day }) {
return new Date(year, month, day);
}
class CalendarWeekComponent {
}
CalendarWeekComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarWeekComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
CalendarWeekComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CalendarWeekComponent, selector: "pupa-calendar-week", ngImport: i0, template: "<ng-content></ng-content>\n", styles: [":host{display:flex;align-items:center;justify-content:space-between;width:100%;height:100%;box-sizing:border-box;padding:1rem 0;height:9rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CalendarWeekComponent, decorators: [{
type: Component,
args: [{ selector: 'pupa-calendar-week', encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>\n", styles: [":host{display:flex;align-items:center;justify-content:space-between;width:100%;height:100%;box-sizing:border-box;padding:1rem 0;height:9rem}\n"] }]
}] });
const DAYS_IN_WEEK = 7;
function getCurrentCalendarDay() {
const date = new Date();
return {
year: date.getFullYear(),
month: date.getMonth(),
day: date.getDate(),
};
}
function getDaysCountInMonth(monthIndex, isLeapYear) {
switch (monthIndex) {
case 1:
return isLeapYear ? 29 : 28;
case 3:
case 5:
case 8:
case 10:
return 30;
default:
return 31;
}
}
const BIG_CALENDAR_CYCLE_SIZE_IN_YEARS = 400;
const SMALL_CALENDAR_CYCLE_WEEKDAYS_SEQUENCE = [
DayOfWeek.Monday,
DayOfWeek.Tuesday,
DayOfWeek.Wednesday,
DayOfWeek.Thursday,
DayOfWeek.Saturday,
DayOfWeek.Sunday,
DayOfWeek.Monday,
DayOfWeek.Tuesday,
DayOfWeek.Thursday,
DayOfWeek.Friday,
DayOfWeek.Saturday,
DayOfWeek.Sunday,
DayOfWeek.Tuesday,
DayOfWeek.Wednesday,
DayOfWeek.Thursday,
DayOfWeek.Friday,
DayOfWeek.Sunday,
DayOfWeek.Monday,
DayOfWeek.Tuesday,
DayOfWeek.Wednesday,
DayOfWeek.Friday,
DayOfWeek.Saturday,
DayOfWeek.Sunday,
DayOfWeek.Monday,
DayOfWeek.Wednesday,
DayOfWeek.Thursday,
DayOfWeek.Friday,
DayOfWeek.Saturday,
];
function isLeapYear(year) {
if (year % 400 === 0) {
return true;
}
if (year % 100 === 0) {
return false;
}
return year % 4 === 0;
}
const NORMAL_YEAR_OFFSETS_IN_SMALL_CYCLE = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5];
function getWeekdayIndex(yearNumber, monthIndex, dayNumber) {
const daysOffset = getDaysOffset(yearNumber, monthIndex);
const yearIndexInSmallCycle = getYearIndexInSmallCycle(yearNumber);
const dayIndex = dayNumber - 1;
const weekdayIndexInSmallCycle = SMALL_CALENDAR_CYCLE_WEEKDAYS_SEQUENCE[yearIndexInSmallCycle];
const weekdayIndex = (weekdayIndexInSmallCycle + daysOffset + dayIndex) % DAYS_IN_WEEK;
return weekdayIndex;
}
function getYearIndexInSmallCycle(yearNumber) {
const yearIndex = yearNumber - 1;
const yearIndexInBigCycle = yearIndex % BIG_CALENDAR_CYCLE_SIZE_IN_YEARS;
const centuryInBigCycle = Math.floor(yearIndexInBigCycle / 100);
const yearIndexRestoredWithBigCycle = 4 * centuryInBigCycle + (yearIndexInBigCycle % 100);
const yearIndexInSmallCycle = yearIndexRestoredWithBigCycle % SMALL_CALENDAR_CYCLE_SIZE_IN_YEARS;
return yearIndexInSmallCycle;
}
function getDaysOffset(yearNumber, monthIndex) {
const offset = NORMAL_YEAR_OFFSETS_IN_SMALL_CYCLE[monthIndex];