UNPKG

igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

1,203 lines (1,195 loc) 192 kB
import * as i0 from '@angular/core'; import { InjectionToken, inject, ElementRef, EventEmitter, HostListener, Output, Input, Directive, HostBinding, TemplateRef, NgZone, booleanAttribute, ViewChildren, Component, ChangeDetectionStrategy, Injectable, LOCALE_ID, ChangeDetectorRef, Pipe, DestroyRef, forwardRef, ContentChild, ViewChild, NgModule } from '@angular/core'; import { TitleCasePipe, getLocaleFirstDayOfWeek, NgTemplateOutlet, DatePipe } from '@angular/common'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { Subject, fromEvent, interval, noop } from 'rxjs'; import { debounce, takeUntil, tap, switchMap, skipLast } from 'rxjs/operators'; import { CalendarDay, PlatformUtil, isDate, getNextActiveDate, isDateInRanges, DateRangeType, calendarRange, areSameMonth, isPreviousMonth, isNextMonth, getYearRange, DateTimeUtil, getCurrentResourceStrings, CalendarResourceStringsEN, isEqual, THEME_TOKEN, getComponentTheme, getClosestActiveDate, getPreviousActiveDate, generateMonth, intoChunks, formatToParts } from 'igniteui-angular/core'; import { EventManager } from '@angular/platform-browser'; import { IgxIconComponent } from 'igniteui-angular/icon'; /** * This file contains all the directives used by the @link IgxCalendarComponent. * Except for the directives which are used for templating the calendar itself * you should generally not use them directly. * * @preferred */ const IGX_CALENDAR_VIEW_ITEM = new InjectionToken('IgxCalendarViewItem'); class IgxCalendarViewBaseDirective { constructor() { this.elementRef = inject(ElementRef); this.showActive = false; this.itemSelection = new EventEmitter(); } get nativeElement() { return this.elementRef.nativeElement; } onMouseDown(event) { event.preventDefault(); this.itemSelection.emit(this.value); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarViewBaseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxCalendarViewBaseDirective, isStandalone: true, inputs: { value: "value", date: "date", showActive: "showActive" }, outputs: { itemSelection: "itemSelection" }, host: { listeners: { "mousedown": "onMouseDown($event)" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarViewBaseDirective, decorators: [{ type: Directive }], propDecorators: { value: [{ type: Input }], date: [{ type: Input }], showActive: [{ type: Input }], itemSelection: [{ type: Output }], onMouseDown: [{ type: HostListener, args: ['mousedown', ['$event']] }] } }); /** * @hidden */ class IgxCalendarYearDirective extends IgxCalendarViewBaseDirective { get isCurrent() { return CalendarDay.today.year === this.value.getFullYear(); } get isSelected() { return this.value.getFullYear() === this.date.getFullYear(); } get isActive() { return this.isSelected && this.showActive; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarYearDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxCalendarYearDirective, isStandalone: true, selector: "[igxCalendarYear]", host: { properties: { "class.igx-calendar-view__item--current": "this.isCurrent", "class.igx-calendar-view__item--selected": "this.isSelected", "class.igx-calendar-view__item--active": "this.isActive" } }, providers: [ { provide: IGX_CALENDAR_VIEW_ITEM, useExisting: IgxCalendarYearDirective } ], exportAs: ["igxCalendarYear"], usesInheritance: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarYearDirective, decorators: [{ type: Directive, args: [{ selector: '[igxCalendarYear]', providers: [ { provide: IGX_CALENDAR_VIEW_ITEM, useExisting: IgxCalendarYearDirective } ], exportAs: 'igxCalendarYear', standalone: true }] }], propDecorators: { isCurrent: [{ type: HostBinding, args: ['class.igx-calendar-view__item--current'] }], isSelected: [{ type: HostBinding, args: ['class.igx-calendar-view__item--selected'] }], isActive: [{ type: HostBinding, args: ['class.igx-calendar-view__item--active'] }] } }); class IgxCalendarMonthDirective extends IgxCalendarViewBaseDirective { get isCurrent() { const today = CalendarDay.today; const date = CalendarDay.from(this.value); return date.year === today.year && date.month === today.month; } get isSelected() { return (this.value.getFullYear() === this.date.getFullYear() && this.value.getMonth() === this.date.getMonth()); } get isActive() { return this.isSelected && this.showActive; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarMonthDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxCalendarMonthDirective, isStandalone: true, selector: "[igxCalendarMonth]", host: { properties: { "class.igx-calendar-view__item--current": "this.isCurrent", "class.igx-calendar-view__item--selected": "this.isSelected", "class.igx-calendar-view__item--active": "this.isActive" } }, providers: [ { provide: IGX_CALENDAR_VIEW_ITEM, useExisting: IgxCalendarMonthDirective } ], exportAs: ["igxCalendarMonth"], usesInheritance: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarMonthDirective, decorators: [{ type: Directive, args: [{ selector: '[igxCalendarMonth]', providers: [ { provide: IGX_CALENDAR_VIEW_ITEM, useExisting: IgxCalendarMonthDirective } ], exportAs: 'igxCalendarMonth', standalone: true }] }], propDecorators: { isCurrent: [{ type: HostBinding, args: ['class.igx-calendar-view__item--current'] }], isSelected: [{ type: HostBinding, args: ['class.igx-calendar-view__item--selected'] }], isActive: [{ type: HostBinding, args: ['class.igx-calendar-view__item--active'] }] } }); /** * @hidden */ class IgxCalendarHeaderTitleTemplateDirective { constructor() { this.template = inject(TemplateRef); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarHeaderTitleTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxCalendarHeaderTitleTemplateDirective, isStandalone: true, selector: "[igxCalendarHeaderTitle]", ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarHeaderTitleTemplateDirective, decorators: [{ type: Directive, args: [{ selector: '[igxCalendarHeaderTitle]', standalone: true }] }] }); /** * @hidden */ class IgxCalendarHeaderTemplateDirective { constructor() { this.template = inject(TemplateRef); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarHeaderTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxCalendarHeaderTemplateDirective, isStandalone: true, selector: "[igxCalendarHeader]", ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarHeaderTemplateDirective, decorators: [{ type: Directive, args: [{ selector: '[igxCalendarHeader]', standalone: true }] }] }); /** * @hidden */ class IgxCalendarSubheaderTemplateDirective { constructor() { this.template = inject(TemplateRef); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarSubheaderTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxCalendarSubheaderTemplateDirective, isStandalone: true, selector: "[igxCalendarSubheader]", ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarSubheaderTemplateDirective, decorators: [{ type: Directive, args: [{ selector: '[igxCalendarSubheader]', standalone: true }] }] }); /** * @hidden */ class IgxCalendarScrollPageDirective { constructor() { this.element = inject(ElementRef); this.zone = inject(NgZone); this.platform = inject(PlatformUtil); /** * @hidden */ this.destroy$ = new Subject(); } /** * @hidden */ onMouseDown(event) { event.preventDefault(); this.startScroll(); } /** * @hidden */ onMouseUp(event) { this.stopScroll(event); } /** * @hidden */ ngAfterViewInit() { fromEvent(this.element.nativeElement, 'keyup').pipe(debounce(() => interval(100)), takeUntil(this.destroy$)).subscribe((event) => { this.stopScroll(event); }); this.zone.runOutsideAngular(() => { fromEvent(this.element.nativeElement, 'keydown').pipe(tap((event) => { if (this.platform.isActivationKey(event)) { event.preventDefault(); event.stopPropagation(); } }), debounce(() => interval(100)), takeUntil(this.destroy$)).subscribe((event) => { if (this.platform.isActivationKey(event)) { this.zone.run(() => this.startScroll(true)); } }); }); } /** * @hidden */ ngOnDestroy() { this.destroy$.next(true); this.destroy$.complete(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarScrollPageDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxCalendarScrollPageDirective, isStandalone: true, selector: "[igxCalendarScrollPage]", inputs: { startScroll: "startScroll", stopScroll: "stopScroll" }, host: { listeners: { "mousedown": "onMouseDown($event)", "mouseup": "onMouseUp($event)" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarScrollPageDirective, decorators: [{ type: Directive, args: [{ selector: '[igxCalendarScrollPage]', standalone: true }] }], propDecorators: { startScroll: [{ type: Input }], stopScroll: [{ type: Input }], onMouseDown: [{ type: HostListener, args: ['mousedown', ['$event']] }], onMouseUp: [{ type: HostListener, args: ['mouseup', ['$event']] }] } }); /** * Sets the selection type - single, multi or range. */ const CalendarSelection = { SINGLE: 'single', MULTI: 'multi', RANGE: 'range' }; const IgxCalendarView = { Month: 'month', Year: 'year', Decade: 'decade' }; const MDAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; const FEBRUARY = 1; const range = (start = 0, stop, step = 1) => { const res = []; const cur = (stop === undefined) ? 0 : start; const max = (stop === undefined) ? start : stop; for (let i = cur; step < 0 ? i > max : i < max; i += step) { res.push(i); } return res; }; /** * Returns true for leap years, false for non-leap years. * * @export * @param year * @returns */ const isLeap = (year) => (year % 4 === 0) && ((year % 100 !== 0) || (year % 400 === 0)); const weekDay = (year, month, day) => new Date(year, month, day).getDay(); /** * Return weekday and number of days for year, month. * * @export * @param year * @param month * @returns */ const monthRange = (year, month) => { if ((month < 0) || (month > 11)) { throw new Error('Invalid month specified'); } const day = weekDay(year, month, 1); let nDays = MDAYS[month]; if ((month === FEBRUARY) && (isLeap(year))) { nDays++; } return [day, nDays]; }; class Calendar { timedelta(date, interval, units) { const ret = new Date(date); const checkRollover = () => { if (ret.getDate() !== date.getDate()) { ret.setDate(0); } }; switch (interval.toLowerCase()) { case 'year': ret.setFullYear(ret.getFullYear() + units); checkRollover(); break; case 'quarter': ret.setMonth(ret.getMonth() + 3 * units); checkRollover(); break; case 'month': ret.setMonth(ret.getMonth() + units); checkRollover(); break; case 'week': ret.setDate(ret.getDate() + 7 * units); break; case 'day': ret.setDate(ret.getDate() + units); break; case 'hour': ret.setTime(ret.getTime() + units * 3600000); break; case 'minute': ret.setTime(ret.getTime() + units * 60000); break; case 'second': ret.setTime(ret.getTime() + units * 1000); break; default: throw new Error('Invalid interval specifier'); } return ret; } } var IgxCalendarNavDirection; (function (IgxCalendarNavDirection) { IgxCalendarNavDirection[IgxCalendarNavDirection["NEXT"] = 1] = "NEXT"; IgxCalendarNavDirection[IgxCalendarNavDirection["PREV"] = -1] = "PREV"; })(IgxCalendarNavDirection || (IgxCalendarNavDirection = {})); const DAY_INTERVAL_TOKEN = new InjectionToken("DAY_INTERVAL"); class IgxCalendarViewDirective { get activeDescendant() { if (this.tabIndex === -1) return; return this.date.getTime(); } /** * Gets/sets the selected date of the view. * By default it's the current date. * ```typescript * let date = this.view.date; * ``` * * @memberof IgxYearsViewComponent */ set date(value) { if (!isDate(value)) return; this._date = value; } get date() { return this._date; } /** * Gets the `locale` of the view. * Default value is `"en"`. * ```typescript * let locale = this.view.locale; * ``` * * @memberof IgxCalendarViewDirective */ get locale() { return this._locale; } /** * Sets the `locale` of the view. * Expects a valid BCP 47 language tag. * Default value is `"en"`. * * @memberof IgxCalendarViewDirective */ set locale(value) { this._locale = value; this.initFormatter(); } constructor() { this.dayInterval = inject(DAY_INTERVAL_TOKEN); this.role = 'grid'; this.tabIndex = 0; /** * Applies styles to the active item on view focus. */ this.showActive = false; /** * Emits an event when a selection is made in the view. * Provides reference the `date` property in the component. * @memberof IgxCalendarViewDirective */ this.selected = new EventEmitter(); /** * Emits an event when a page changes in the view. * Provides reference the `date` property in the component. * @memberof IgxCalendarViewDirective * @hidden @internal */ this.pageChanged = new EventEmitter(); /** * Emits an event when the active date has changed. * @memberof IgxCalendarViewDirective * @hidden @internal */ this.activeDateChanged = new EventEmitter(); /** * @hidden */ this._locale = "en"; /** * @hidden * @internal */ this._date = new Date(); /** * @hidden */ this._onTouchedCallback = noop; /** * @hidden */ this._onChangeCallback = noop; this.initFormatter(); } /** * @hidden */ onKeydownArrowDown(event) { this.navigateTo(event, IgxCalendarNavDirection.NEXT, 3); } /** * @hidden */ onKeydownArrowUp(event) { this.navigateTo(event, IgxCalendarNavDirection.PREV, 3); } /** * @hidden */ onKeydownArrowRight(event) { this.navigateTo(event, IgxCalendarNavDirection.NEXT, 1); } /** * @hidden */ onKeydownArrowLeft(event) { this.navigateTo(event, IgxCalendarNavDirection.PREV, 1); } /** * @hidden */ onKeydownHome(event) { event.preventDefault(); event.stopPropagation(); this.date = this.range.at(0); this.activeDateChanged.emit(this.date); } /** * @hidden */ onKeydownEnd(event) { event.preventDefault(); event.stopPropagation(); this.date = this.range.at(-1); this.activeDateChanged.emit(this.date); } /** * @hidden */ onKeydownEnter(event) { event.stopPropagation(); this.selected.emit(this.date); this._onChangeCallback(this.date); } /** * @hidden */ handleFocus() { this.showActive = true; } /** * @hidden */ handleBlur() { this.showActive = false; } /** * @hidden */ selectDate(value) { this.date = value; this.selected.emit(this.date); this._onChangeCallback(this.date); } /** * @hidden */ registerOnChange(fn) { this._onChangeCallback = fn; } /** * @hidden */ registerOnTouched(fn) { this._onTouchedCallback = fn; } /** * @hidden */ writeValue(value) { if (value) { this.date = value; } } /** * @hidden */ navigateTo(event, direction, delta) { event.preventDefault(); event.stopPropagation(); const date = getNextActiveDate(CalendarDay.from(this.date).add(this.dayInterval, direction * delta), []); const outOfRange = !isDateInRanges(date, [ { type: DateRangeType.Between, dateRange: [this.range.at(0), this.range.at(-1)], }, ]); if (outOfRange) { this.pageChanged.emit(date.native); } this.date = date.native; this.activeDateChanged.emit(this.date); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarViewDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.0.2", type: IgxCalendarViewDirective, isStandalone: true, inputs: { role: "role", tabIndex: "tabIndex", formatView: ["formatView", "formatView", booleanAttribute], showActive: ["showActive", "showActive", booleanAttribute], date: "date", locale: "locale" }, outputs: { selected: "selected", pageChanged: "pageChanged", activeDateChanged: "activeDateChanged" }, host: { listeners: { "keydown.arrowdown": "onKeydownArrowDown($event)", "keydown.arrowup": "onKeydownArrowUp($event)", "keydown.arrowright": "onKeydownArrowRight($event)", "keydown.arrowleft": "onKeydownArrowLeft($event)", "keydown.home": "onKeydownHome($event)", "keydown.end": "onKeydownEnd($event)", "keydown.enter": "onKeydownEnter($event)", "focus": "handleFocus()", "blur": "handleBlur()" }, properties: { "attr.role": "this.role", "attr.tabIndex": "this.tabIndex", "attr.aria-activeDescendant": "this.activeDescendant" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: IgxCalendarViewDirective, multi: true, }, ], viewQueries: [{ propertyName: "viewItems", predicate: IGX_CALENDAR_VIEW_ITEM, descendants: true, read: IGX_CALENDAR_VIEW_ITEM }], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxCalendarViewDirective, decorators: [{ type: Directive, args: [{ providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: IgxCalendarViewDirective, multi: true, }, ], standalone: true, }] }], ctorParameters: () => [], propDecorators: { role: [{ type: HostBinding, args: ["attr.role"] }, { type: Input }], tabIndex: [{ type: HostBinding, args: ["attr.tabIndex"] }, { type: Input }], activeDescendant: [{ type: HostBinding, args: ['attr.aria-activeDescendant'] }], formatView: [{ type: Input, args: [{ transform: booleanAttribute }] }], showActive: [{ type: Input, args: [{ transform: booleanAttribute }] }], selected: [{ type: Output }], pageChanged: [{ type: Output }], activeDateChanged: [{ type: Output }], viewItems: [{ type: ViewChildren, args: [IGX_CALENDAR_VIEW_ITEM, { read: IGX_CALENDAR_VIEW_ITEM }] }], date: [{ type: Input }], locale: [{ type: Input }], onKeydownArrowDown: [{ type: HostListener, args: ["keydown.arrowdown", ["$event"]] }], onKeydownArrowUp: [{ type: HostListener, args: ["keydown.arrowup", ["$event"]] }], onKeydownArrowRight: [{ type: HostListener, args: ["keydown.arrowright", ["$event"]] }], onKeydownArrowLeft: [{ type: HostListener, args: ["keydown.arrowleft", ["$event"]] }], onKeydownHome: [{ type: HostListener, args: ["keydown.home", ["$event"]] }], onKeydownEnd: [{ type: HostListener, args: ["keydown.end", ["$event"]] }], onKeydownEnter: [{ type: HostListener, args: ["keydown.enter", ["$event"]] }], handleFocus: [{ type: HostListener, args: ["focus"] }], handleBlur: [{ type: HostListener, args: ["blur"] }] } }); let NEXT_ID$3 = 0; class IgxMonthsViewComponent extends IgxCalendarViewDirective { constructor() { super(...arguments); this.el = inject(ElementRef); this.#standalone = true; this.platform = inject(PlatformUtil); /** * Sets/gets the `id` of the months view. * If not set, the `id` will have value `"igx-months-view-0"`. * ```html * <igx-months-view id="my-months-view"></igx-months-view> * ``` * ```typescript * let monthsViewId = this.monthsView.id; * ``` * * @memberof IgxMonthsViewComponent */ this.id = `igx-months-view-${NEXT_ID$3++}`; /** * The default css class applied to the component. * * @hidden */ this.viewClass = true; /** * Gets/sets whether the view should be rendered * according to the locale and format, if any. */ this.formatView = true; /** * @hidden */ this._monthFormat = "short"; } #standalone; /** * @hidden @internal */ get standalone() { return this.#standalone; } set standalone(value) { this.#standalone = value; } /** * Gets the month format option of the months view. * ```typescript * let monthFormat = this.monthsView.monthFormat. * ``` */ get monthFormat() { return this._monthFormat; } /** * Sets the month format option of the months view. * ```html * <igx-months-view> [monthFormat]="short'"</igx-months-view> * ``` * * @memberof IgxMonthsViewComponent */ set monthFormat(value) { this._monthFormat = value; this.initFormatter(); } /** * Returns an array of date objects which are then used to * properly render the month names. * * Used in the template of the component * * @hidden @internal */ get range() { const start = CalendarDay.from(this.date).set({ date: 1, month: 0 }); const end = start.add(this.dayInterval, 12); return Array.from(calendarRange({ start, end, unit: this.dayInterval })).map((m) => m.native); } /** * @hidden */ onMouseDown() { if (this.tabIndex !== -1 && this.platform.isBrowser && this.el?.nativeElement) { this.el.nativeElement.focus(); } } /** * Returns the locale representation of the month in the months view. * * @hidden */ formattedMonth(value) { const rawFormatter = new Intl.DateTimeFormat(this.locale, { month: "long", year: "numeric", }); if (this.formatView) { return { long: rawFormatter.format(value), formatted: this._formatter.format(value), }; } return { long: rawFormatter.format(value), formatted: `${value.getMonth()}`, }; } /** * @hidden */ monthTracker(_, item) { return `${item.getMonth()}}`; } /** * @hidden */ initFormatter() { this._formatter = new Intl.DateTimeFormat(this._locale, { month: this.monthFormat, }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxMonthsViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.2", type: IgxMonthsViewComponent, isStandalone: true, selector: "igx-months-view", inputs: { id: "id", standalone: "standalone", monthFormat: "monthFormat", formatView: ["formatView", "formatView", booleanAttribute] }, host: { properties: { "attr.id": "this.id", "class.igx-calendar-view": "this.viewClass", "class.igx-calendar-view--standalone": "this.standalone" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: IgxMonthsViewComponent, multi: true, }, { provide: DAY_INTERVAL_TOKEN, useValue: "month", }, ], usesInheritance: true, ngImport: i0, template: "<div class=\"igx-calendar-view__items\" role=\"row\">\n @for (month of range; track monthTracker($index, month)) {\n <span\n igxCalendarMonth\n #item=\"igxCalendarMonth\"\n class=\"igx-calendar-view__item\"\n role=\"gridcell\"\n [attr.id]=\"month.getTime()\"\n [attr.aria-label]=\"formattedMonth(month).long\"\n [attr.aria-selected]=\"item.isSelected\"\n [value]=\"month\"\n [date]=\"date\"\n [showActive]=\"showActive\"\n (itemSelection)=\"selectDate($event)\"\n (mousedown)=\"onMouseDown()\"\n >\n <span class=\"igx-calendar-view__item-inner\" aria-hidden=\"true\">\n {{ formattedMonth(month).formatted | titlecase }}\n </span>\n </span>\n }\n</div>\n", dependencies: [{ kind: "directive", type: IgxCalendarMonthDirective, selector: "[igxCalendarMonth]", exportAs: ["igxCalendarMonth"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxMonthsViewComponent, decorators: [{ type: Component, args: [{ providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: IgxMonthsViewComponent, multi: true, }, { provide: DAY_INTERVAL_TOKEN, useValue: "month", }, ], selector: "igx-months-view", imports: [IgxCalendarMonthDirective, TitleCasePipe], template: "<div class=\"igx-calendar-view__items\" role=\"row\">\n @for (month of range; track monthTracker($index, month)) {\n <span\n igxCalendarMonth\n #item=\"igxCalendarMonth\"\n class=\"igx-calendar-view__item\"\n role=\"gridcell\"\n [attr.id]=\"month.getTime()\"\n [attr.aria-label]=\"formattedMonth(month).long\"\n [attr.aria-selected]=\"item.isSelected\"\n [value]=\"month\"\n [date]=\"date\"\n [showActive]=\"showActive\"\n (itemSelection)=\"selectDate($event)\"\n (mousedown)=\"onMouseDown()\"\n >\n <span class=\"igx-calendar-view__item-inner\" aria-hidden=\"true\">\n {{ formattedMonth(month).formatted | titlecase }}\n </span>\n </span>\n }\n</div>\n" }] }], propDecorators: { id: [{ type: HostBinding, args: ["attr.id"] }, { type: Input }], viewClass: [{ type: HostBinding, args: ["class.igx-calendar-view"] }], standalone: [{ type: Input }, { type: HostBinding, args: ["class.igx-calendar-view--standalone"] }], monthFormat: [{ type: Input }], formatView: [{ type: Input, args: [{ transform: booleanAttribute }] }] } }); class IgxYearsViewComponent extends IgxCalendarViewDirective { constructor() { super(...arguments); this.el = inject(ElementRef); this.#standalone = true; this.platform = inject(PlatformUtil); /** * The default css class applied to the component. * * @hidden */ this.viewClass = true; /** * @hidden */ this._yearFormat = "numeric"; /** * @hidden */ this._yearsPerPage = 15; } #standalone; /** * @hidden @internal */ get standalone() { return this.#standalone; } set standalone(value) { this.#standalone = value; } /** * Gets the year format option of the years view. * ```typescript * let yearFormat = this.yearsView.yearFormat. * ``` */ get yearFormat() { return this._yearFormat; } /** * Sets the year format option of the years view. * ```html * <igx-years-view [yearFormat]="numeric"></igx-years-view> * ``` * * @memberof IgxYearsViewComponent */ set yearFormat(value) { this._yearFormat = value; this.initFormatter(); } /** * Returns an array of date objects which are then used to properly * render the years. * * Used in the template of the component. * * @hidden @internal */ get range() { const year = this.date.getFullYear(); const start = new CalendarDay({ year: Math.floor(year / this._yearsPerPage) * this._yearsPerPage, month: this.date.getMonth(), }); const end = start.add(this.dayInterval, this._yearsPerPage); return Array.from(calendarRange({ start, end, unit: this.dayInterval })).map((m) => m.native); } /** * Returns the locale representation of the year in the years view. * * @hidden */ formattedYear(value) { const rawFormatter = new Intl.DateTimeFormat(this.locale, { year: 'numeric' }); if (this.formatView) { return { long: rawFormatter.format(value), formatted: this._formatter.format(value) }; } return { long: rawFormatter.format(value), formatted: `${value.getFullYear()}` }; } /** * @hidden */ yearTracker(_, item) { return `${item.getFullYear()}}`; } /** * @hidden */ initFormatter() { this._formatter = new Intl.DateTimeFormat(this._locale, { year: this.yearFormat, }); } /** * @hidden */ onMouseDown() { if (this.tabIndex !== -1 && this.platform.isBrowser && this.el?.nativeElement) { this.el.nativeElement.focus(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxYearsViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.2", type: IgxYearsViewComponent, isStandalone: true, selector: "igx-years-view", inputs: { standalone: "standalone", yearFormat: "yearFormat" }, host: { properties: { "class.igx-calendar-view": "this.viewClass", "class.igx-calendar-view--standalone": "this.standalone" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: IgxYearsViewComponent, multi: true, }, { provide: DAY_INTERVAL_TOKEN, useValue: "year", }, ], usesInheritance: true, ngImport: i0, template: "<div class=\"igx-calendar-view__items\" role=\"row\">\n @for (year of range; track yearTracker($index, year)) {\n <span\n igxCalendarYear\n #item=\"igxCalendarYear\"\n class=\"igx-calendar-view__item\"\n role=\"gridcell\"\n [attr.id]=\"year.getTime()\"\n [attr.aria-label]=\"formattedYear(year).long\"\n [attr.aria-selected]=\"item.isSelected\"\n [attr.aria-current]=\"item.isCurrent\"\n [value]=\"year\"\n [date]=\"date\"\n [showActive]=\"showActive\"\n (itemSelection)=\"selectDate($event)\"\n (mousedown)=\"onMouseDown()\"\n >\n <span class=\"igx-calendar-view__item-inner\" aria-hidden=\"true\">\n {{ formattedYear(year).formatted }}\n </span>\n </span>\n }\n</div>\n", dependencies: [{ kind: "directive", type: IgxCalendarYearDirective, selector: "[igxCalendarYear]", exportAs: ["igxCalendarYear"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxYearsViewComponent, decorators: [{ type: Component, args: [{ providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: IgxYearsViewComponent, multi: true, }, { provide: DAY_INTERVAL_TOKEN, useValue: "year", }, ], selector: "igx-years-view", imports: [IgxCalendarYearDirective], template: "<div class=\"igx-calendar-view__items\" role=\"row\">\n @for (year of range; track yearTracker($index, year)) {\n <span\n igxCalendarYear\n #item=\"igxCalendarYear\"\n class=\"igx-calendar-view__item\"\n role=\"gridcell\"\n [attr.id]=\"year.getTime()\"\n [attr.aria-label]=\"formattedYear(year).long\"\n [attr.aria-selected]=\"item.isSelected\"\n [attr.aria-current]=\"item.isCurrent\"\n [value]=\"year\"\n [date]=\"date\"\n [showActive]=\"showActive\"\n (itemSelection)=\"selectDate($event)\"\n (mousedown)=\"onMouseDown()\"\n >\n <span class=\"igx-calendar-view__item-inner\" aria-hidden=\"true\">\n {{ formattedYear(year).formatted }}\n </span>\n </span>\n }\n</div>\n" }] }], propDecorators: { viewClass: [{ type: HostBinding, args: ["class.igx-calendar-view"] }], standalone: [{ type: Input }, { type: HostBinding, args: ['class.igx-calendar-view--standalone'] }], yearFormat: [{ type: Input }] } }); /** * @hidden */ class IgxDayItemComponent { constructor() { this.elementRef = inject(ElementRef); this.hideOutsideDays = false; this.isLastInRange = false; this.isFirstInRange = false; this.isWithinRange = false; this.isWithinPreviewRange = false; this.hideLeadingDays = false; this.hideTrailingDays = false; this.dateSelection = new EventEmitter(); this.mouseEnter = new EventEmitter(); this.mouseLeave = new EventEmitter(); this.mouseDown = new EventEmitter(); this.isActive = false; this._selected = false; } /** * Returns boolean indicating if the day is selected * */ get selected() { return this._selected; } /** * Selects the day */ set selected(value) { this._selected = value; } get hideLeading() { return this.hideLeadingDays && this.isPreviousMonth; } get hideTrailing() { return this.hideTrailingDays && this.isNextMonth; } get isCurrentMonth() { return areSameMonth(this.date, this.viewDate); } get isPreviousMonth() { return isPreviousMonth(this.date, this.viewDate); } get isNextMonth() { return isNextMonth(this.date, this.viewDate); } get nativeElement() { return this.elementRef.nativeElement; } get isSelectedCSS() { const selectable = !this.isInactive || this.isWithinPreviewRange || (this.isWithinRange && this.selection === "range"); return !this.isDisabled && selectable && this.selected; } get isInactive() { return !this.isCurrentMonth; } get isHidden() { return (this.hideLeading || this.hideTrailing) && this.isInactive; } get isToday() { return !this.isInactive && this.date.equalTo(CalendarDay.today); } get isWeekend() { return this.date.weekend; } get isDisabled() { if (!this.disabledDates) { return false; } return isDateInRanges(this.date, this.disabledDates); } get isFocusable() { return this.isCurrentMonth && !this.isHidden && !this.isDisabled; } onMouseEnter() { this.mouseEnter.emit(); } onMouseLeave() { this.mouseLeave.emit(); } onMouseDown(event) { event.preventDefault(); this.mouseDown.emit(); } get isWithinRangeCSS() { return !this.isSingleSelection && this.isWithinRange; } get isWithinPreviewRangeCSS() { return !this.isSingleSelection && this.isWithinPreviewRange; } get isSpecial() { if (!this.specialDates) { return false; } return !this.isInactive && isDateInRanges(this.date, this.specialDates); } get isDisabledCSS() { return this.isHidden || this.isDisabled; } get isSingleSelection() { return this.selection !== CalendarSelection.RANGE; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxDayItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "21.0.2", type: IgxDayItemComponent, isStandalone: true, selector: "igx-day-item", inputs: { date: "date", viewDate: "viewDate", selection: "selection", selected: "selected", disabledDates: "disabledDates", specialDates: "specialDates", hideOutsideDays: ["hideOutsideDays", "hideOutsideDays", booleanAttribute], isLastInRange: ["isLastInRange", "isLastInRange", booleanAttribute], isFirstInRange: ["isFirstInRange", "isFirstInRange", booleanAttribute], isWithinRange: ["isWithinRange", "isWithinRange", booleanAttribute], isWithinPreviewRange: ["isWithinPreviewRange", "isWithinPreviewRange", booleanAttribute], hideLeadingDays: ["hideLeadingDays", "hideLeadingDays", booleanAttribute], hideTrailingDays: ["hideTrailingDays", "hideTrailingDays", booleanAttribute], isActive: ["isActive", "isActive", booleanAttribute] }, outputs: { dateSelection: "dateSelection", mouseEnter: "mouseEnter", mouseLeave: "mouseLeave", mouseDown: "mouseDown" }, host: { properties: { "class.igx-days-view__date--last": "this.isLastInRange", "class.igx-days-view__date--first": "this.isFirstInRange", "class.igx-days-view__date--active": "this.isActive", "class.igx-days-view__date--selected": "this.isSelectedCSS", "class.igx-days-view__date--inactive": "this.isInactive", "class.igx-days-view__date--hidden": "this.isHidden", "class.igx-days-view__date--current": "this.isToday", "class.igx-days-view__date--weekend": "this.isWeekend", "class.igx-days-view__date--range": "this.isWithinRangeCSS", "class.igx-days-view__date--range-preview": "this.isWithinPreviewRangeCSS", "class.igx-days-view__date--special": "this.isSpecial", "class.igx-days-view__date--disabled": "this.isDisabledCSS", "class.igx-days-view__date--single": "this.isSingleSelection" } }, ngImport: i0, template: "<span\n aria-hidden=\"true\"\n class=\"igx-days-view__date-inner\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n (mousedown)=\"onMouseDown($event)\"\n>\n <ng-content></ng-content>\n</span>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxDayItemComponent, decorators: [{ type: Component, args: [{ selector: 'igx-day-item', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<span\n aria-hidden=\"true\"\n class=\"igx-days-view__date-inner\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n (mousedown)=\"onMouseDown($event)\"\n>\n <ng-content></ng-content>\n</span>\n" }] }], propDecorators: { date: [{ type: Input }], viewDate: [{ type: Input }], selection: [{ type: Input }], selected: [{ type: Input }], disabledDates: [{ type: Input }], specialDates: [{ type: Input }], hideOutsideDays: [{ type: Input, args: [{ transform: booleanAttribute }] }], isLastInRange: [{ type: Input, args: [{ transform: booleanAttribute }] }, { type: HostBinding, args: ['class.igx-days-view__date--last'] }], isFirstInRange: [{ type: Input, args: [{ transform: booleanAttribute }] }, { type: HostBinding, args: ['class.igx-days-view__date--first'] }], isWithinRange: [{ type: Input, args: [{ transform: booleanAttribute }] }], isWithinPreviewRange: [{ type: Input, args: [{ transform: booleanAttribute }] }], hideLeadingDays: [{ type: Input, args: [{ transform: booleanAttribute }] }], hideTrailingDays: [{ type: Input, args: [{ transform: booleanAttribute }] }], dateSelection: [{ type: Output }], mouseEnter: [{ type: Output }], mouseLeave: [{ type: Output }], mouseDown: [{ type: Output }], isActive: [{ type: Input, args: [{ transform: booleanAttribute }] }, { type: HostBinding, args: ['class.igx-days-view__date--active'] }], isSelectedCSS: [{ type: HostBinding, args: ['class.igx-days-view__date--selected'] }], isInactive: [{ type: HostBinding, args: ['class.igx-days-view__date--inactive'] }], isHidden: [{ type: HostBinding, args: ['class.igx-days-view__date--hidden'] }], isToday: [{ type: HostBinding, args: ['class.igx-days-view__date--current'] }], isWeekend: [{ type: HostBinding, args: ['class.igx-days-view__date--weekend'] }], isWithinRangeCSS: [{ type: HostBinding, args: ['class.igx-days-view__date--range'] }], isWithinPreviewRangeCSS: [{ type: HostBinding, args: ['class.igx-days-view__date--range-preview'] }], isSpecial: [{ type: HostBinding, args: ['class.igx-days-view__date--special'] }], isDisabledCSS: [{ type: HostBinding, args: ['class.igx-days-view__date--disabled'] }], isSingleSelection: [{ type: HostBinding, args: ['class.igx-days-view__date--single'] }] } }); class KeyboardNavigationService { constructor() { this.eventManager = inject(EventManager); this.ngZone = inject(NgZone); this.keyHandlers = new Map(); this.eventUnsubscribeFn = null; this.platform = inject(PlatformUtil); } attachKeyboardHandlers(elementRef, context) { if (!this.platform.isBrowser) { return this; } this.detachKeyboardHandlers(); // Clean up any existing listeners this.ngZone.runOutsideAngular(() => { this.eventUnsubscribeFn = this.eventManager.addEventListener(elementRef.nativeElement, 'keydown', (event) => { const handler = this.keyHandlers.get(event.key); if (handler) { this.ngZone.run(handler.bind(context, event)); } }); }); return this; } detachKeyboardHandlers() { if (this.eventUnsubscribeFn) { this.eventUnsubscribeFn(); this.eventUnsubscribeFn = null; } this.keyHandlers.clear(); } set(key, handler) { this.keyHandlers.set(key, handler); return this; } unset(key) { this.keyHandlers.delete(key); return this; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: KeyboardNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: KeyboardNavigationService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: KeyboardNavigationService, decorators: [{ type: Injectable }] }); /** @hidden @internal */ class IgxCalendarBaseDirective { /** * An accessor that sets the resource strings. * By default it uses EN resources. */ set resourceStrings(value) { this._resourceStrings = Object.assign({}, this._resourceStrings, value); } /** * An accessor that returns the resource strings. */ g