UNPKG

@frxjs/ngx-timeline

Version:

The main goal of this angular library is to give you the possibility to integrate a timeline in your app. <br> Version 21.0.1 is compatible with angular 20. <br> Go [here](https://emanuelefricano93.github.io/frxjs-Ngx-Timeline/) and discover all possible

485 lines (480 loc) 63.9 kB
import * as i1 from '@angular/cdk/scrolling'; import { ScrollingModule } from '@angular/cdk/scrolling'; import { DatePipe, NgTemplateOutlet, TitleCasePipe, NgClass, registerLocaleData } from '@angular/common'; import * as i0 from '@angular/core'; import { Pipe, input, output, ChangeDetectionStrategy, Component, inject, IterableDiffers, NgModule } from '@angular/core'; import localeDe from '@angular/common/locales/de'; import localeEs from '@angular/common/locales/es'; import localeFr from '@angular/common/locales/fr'; import localeIt from '@angular/common/locales/it'; import localePl from '@angular/common/locales/pl'; import localePt from '@angular/common/locales/pt'; import localeRu from '@angular/common/locales/ru'; import localeSl from '@angular/common/locales/sl'; import localeTr from '@angular/common/locales/tr'; import localeNo from '@angular/common/locales/nb'; const supportedLanguageCodes = ['en', 'it', 'fr', 'de', 'es', 'sl', 'tr', 'pl', 'pt', 'ru', 'nb']; const defaultSupportedLanguageCode = supportedLanguageCodes[0]; const dateConfigMap = { en: { code: 'en-US', fullDate: 'MM/dd/yyyy h:mm a', dayMonthYear: 'dd MMMM yyyy', monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'hh:mm a', }, it: { code: 'it-IT', fullDate: 'dd/MM/yyyy H:mm', dayMonthYear: 'dd MMMM yyyy', monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'HH:mm', }, fr: { code: 'fr-FR', fullDate: 'dd/MM/yyyy H:mm', dayMonthYear: 'dd MMMM yyyy', monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'HH:mm', }, de: { code: 'de', fullDate: 'dd/MM/yyyy H:mm', dayMonthYear: 'dd MMMM yyyy', monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'HH:mm', }, es: { code: 'es', fullDate: 'dd/MM/yyyy H:mm', dayMonthYear: 'dd MMMM yyyy', monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'HH:mm', }, sl: { code: 'sl-SL', fullDate: 'dd/MM/yyyy H:mm', dayMonthYear: 'dd MMMM yyyy', monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'HH:mm', }, tr: { code: 'tr', fullDate: 'dd/MM/yyyy H:mm', dayMonthYear: 'dd MMMM yyyy', monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'HH:mm', }, pl: { code: 'pl', fullDate: 'dd/MM/yyyy H:mm', dayMonthYear: 'dd MMMM yyyy', monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'HH:mm', }, pt: { code: 'pt', fullDate: 'dd/MM/yyyy H:mm', dayMonthYear: 'dd MMMM yyyy', monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'HH:mm', }, ru: { code: 'ru-RU', fullDate: 'dd/MM/yyyy H:mm', dayMonthYear: 'dd MMMM yyyy', monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'HH:mm', }, nb: { code: 'nb-NO', fullDate: 'dd/MM/yyyy H:mm', dayMonthYear: 'dd MMMM yyyy', monthYear: 'MMMM yyyy', year: 'yyyy', hoursMinutes: 'HH:mm', }, }; var NgxDateFormat; (function (NgxDateFormat) { NgxDateFormat["DAY_MONTH_YEAR"] = "DAY_MONTH_YEAR"; NgxDateFormat["FULL_DATE"] = "FULL_DATE"; NgxDateFormat["HOURS_MINUTES"] = "HOURS_MINUTES"; NgxDateFormat["MONTH_YEAR"] = "MONTH_YEAR"; NgxDateFormat["YEAR"] = "YEAR"; })(NgxDateFormat || (NgxDateFormat = {})); const fieldConfigDate = { DAY_MONTH_YEAR: 'dayMonthYear', FULL_DATE: 'fullDate', HOURS_MINUTES: 'hoursMinutes', MONTH_YEAR: 'monthYear', YEAR: 'year', }; /** * Enum used to set the group event logic */ var NgxTimelineEventGroup; (function (NgxTimelineEventGroup) { NgxTimelineEventGroup["YEAR"] = "YEAR"; NgxTimelineEventGroup["MONTH_YEAR"] = "MONTH_YEAR"; NgxTimelineEventGroup["DAY_MONTH_YEAR"] = "DAY_MONTH_YEAR"; })(NgxTimelineEventGroup || (NgxTimelineEventGroup = {})); const fieldsToAddEventGroup = { YEAR: ['getFullYear'], MONTH_YEAR: ['getFullYear', 'getMonth'], DAY_MONTH_YEAR: ['getFullYear', 'getMonth', 'getDate'], }; const periodKeyDateFormat = { YEAR: NgxDateFormat.YEAR, MONTH_YEAR: NgxDateFormat.MONTH_YEAR, DAY_MONTH_YEAR: NgxDateFormat.DAY_MONTH_YEAR, }; /** * Enum used to set the group event logic. */ var NgxTimelineOrientation; (function (NgxTimelineOrientation) { NgxTimelineOrientation["HORIZONTAL"] = "HORIZONTAL"; NgxTimelineOrientation["VERTICAL"] = "VERTICAL"; })(NgxTimelineOrientation || (NgxTimelineOrientation = {})); /** * Enum used to set the change side event logic. */ var NgxTimelineEventChangeSide; (function (NgxTimelineEventChangeSide) { NgxTimelineEventChangeSide["ALL"] = "ALL"; NgxTimelineEventChangeSide["ALL_IN_GROUP"] = "ALL_IN_GROUP"; NgxTimelineEventChangeSide["ON_DIFFERENT_DAY_IN_GROUP"] = "ON_DIFFERENT_DAY_IN_GROUP"; NgxTimelineEventChangeSide["ON_DIFFERENT_HMS_IN_GROUP"] = "ON_DIFFERENT_HMS_IN_GROUP"; NgxTimelineEventChangeSide["ON_DIFFERENT_MONTH_IN_GROUP"] = "ON_DIFFERENT_MONTH_IN_GROUP"; })(NgxTimelineEventChangeSide || (NgxTimelineEventChangeSide = {})); const fieldsToCheckEventChangeSideInGroup = { ON_DIFFERENT_DAY_IN_GROUP: ['getFullYear', 'getMonth', 'getDate'], ON_DIFFERENT_MONTH_IN_GROUP: ['getFullYear', 'getMonth'], ON_DIFFERENT_HMS_IN_GROUP: ['getFullYear', 'getMonth', 'getDate', 'getHours', 'getMinutes', 'getSeconds'], }; var NgxTimelineItemPosition; (function (NgxTimelineItemPosition) { NgxTimelineItemPosition["ON_LEFT"] = "ON_LEFT"; NgxTimelineItemPosition["ON_RIGHT"] = "ON_RIGHT"; })(NgxTimelineItemPosition || (NgxTimelineItemPosition = {})); class NgxDatePipe { // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents transform(date, dateFormat, langCode) { const configDate = this.getDateConfig(langCode); let dateFormatString = 'yyyy'; if (dateFormat === undefined) { console.warn('frxjs-ngx-timeline: no date format defined.'); } else if (dateFormat in NgxDateFormat) { dateFormatString = this.dateFormat(dateFormat, configDate); } else if (typeof dateFormat === 'string') { dateFormatString = dateFormat; } return new DatePipe(configDate.code).transform(new Date(date), dateFormatString); } dateFormat(dateFormat, configDate) { return configDate[fieldConfigDate[dateFormat]]; } getDateConfig(langCode) { const code = langCode ?? defaultSupportedLanguageCode; return dateConfigMap[code]; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxDatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxDatePipe, isStandalone: true, name: "ngxdate" }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxDatePipe, decorators: [{ type: Pipe, args: [{ name: 'ngxdate', }] }] }); class NgxTimelineEventComponent { /** * Event to be displayed. */ event = input.required({ ...(ngDevMode ? { debugName: "event" } : {}) }); /** * Event position respect to the vertical line (LEFT or RIGHT). */ colSidePosition = input(undefined, { ...(ngDevMode ? { debugName: "colSidePosition" } : {}) }); /** * Language code used to format the dates. */ langCode = input(defaultSupportedLanguageCode, { ...(ngDevMode ? { debugName: "langCode" } : {}) }); /** * Inner custom template used to display the event detail. */ innerEventCustomTemplate = input(undefined, { ...(ngDevMode ? { debugName: "innerEventCustomTemplate" } : {}) }); /** * Inner custom template used to display the event description. */ eventDescriptionCustomTemplate = input(undefined, { ...(ngDevMode ? { debugName: "eventDescriptionCustomTemplate" } : {}) }); /** * Boolean used to enable or disable the animations. */ enableAnimation = input(true, { ...(ngDevMode ? { debugName: "enableAnimation" } : {}) }); /** * Orientation of the timeline. */ orientation = input(NgxTimelineOrientation.VERTICAL, { ...(ngDevMode ? { debugName: "orientation" } : {}) }); /** * Output click event emitter. */ clickEmitter = output(); ngxTimelineItemPosition = NgxTimelineItemPosition; ngxTimelineOrientation = NgxTimelineOrientation; monthAbbr = 'MMM'; dayFormat = 'dd'; getDateObj() { let day = undefined; let month = undefined; let year = undefined; const dateTimestamp = this.event().eventInfo?.timestamp; if (dateTimestamp) { const timestamp = new Date(dateTimestamp); const langCode = this.getLangCode(); month = new DatePipe(langCode).transform(timestamp, this.monthAbbr); day = new DatePipe(langCode).transform(timestamp, this.dayFormat); year = timestamp.getFullYear(); } return { day, month, year }; } getLangCode() { return this.langCode(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxTimelineEventComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: NgxTimelineEventComponent, isStandalone: true, selector: "ngx-timeline-event", inputs: { event: { classPropertyName: "event", publicName: "event", isSignal: true, isRequired: true, transformFunction: null }, colSidePosition: { classPropertyName: "colSidePosition", publicName: "colSidePosition", isSignal: true, isRequired: false, transformFunction: null }, langCode: { classPropertyName: "langCode", publicName: "langCode", isSignal: true, isRequired: false, transformFunction: null }, innerEventCustomTemplate: { classPropertyName: "innerEventCustomTemplate", publicName: "innerEventCustomTemplate", isSignal: true, isRequired: false, transformFunction: null }, eventDescriptionCustomTemplate: { classPropertyName: "eventDescriptionCustomTemplate", publicName: "eventDescriptionCustomTemplate", isSignal: true, isRequired: false, transformFunction: null }, enableAnimation: { classPropertyName: "enableAnimation", publicName: "enableAnimation", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickEmitter: "clickEmitter" }, ngImport: i0, template: "<div class=\"event-wrapper-container\" (click)=\"clickEmitter.emit(event())\" [class.horizontal]=\"orientation() === ngxTimelineOrientation.HORIZONTAL\">\n @if (colSidePosition()===ngxTimelineItemPosition.ON_RIGHT) {\n <div class=\"arrow left\"></div>\n }\n <div class=\"event\" [class.enableAnimation]=\"enableAnimation()\">\n <ng-container *ngTemplateOutlet=\"innerEventCustomTemplate() || innerEventContainer; context: {event: event()}\"></ng-container>\n </div>\n @if (colSidePosition() === ngxTimelineItemPosition.ON_LEFT) {\n <div class=\"arrow right\"></div>\n }\n</div>\n\n<ng-template #innerEventContainer let-event=event>\n <div class=\"event-container\" [class.reverse]=\"colSidePosition() === ngxTimelineItemPosition.ON_LEFT\">\n <div class=\"event-info-container\">\n <div class=\"event-info-header\">\n <div class=\"title-container\">{{event?.eventInfo?.title | titlecase}}</div>\n </div>\n <div class=\"event-info-body\">\n <ng-container *ngTemplateOutlet=\"eventDescriptionCustomTemplate() || eventDescriptionContainer; context: {event: event}\"></ng-container>\n </div>\n </div>\n\n <div class=\"event-divider-container\">\n <hr>\n </div>\n\n @if (getDateObj(); as dateObj) {\n <div class=\"event-date-container\">\n <div>\n <p>{{dateObj?.month}}</p>\n </div>\n <div>\n <p class=\"day\">{{dateObj?.day}}</p>\n </div>\n <div>\n <p>{{dateObj?.year}}</p>\n </div>\n </div>\n }\n </div>\n</ng-template>\n\n\n<ng-template #eventDescriptionContainer let-event=event>\n <p class=\"event-info-description\">{{event?.eventInfo?.description}}</p>\n</ng-template>\n", styles: ["::ng-deep :root{--ngx-timeline-period-inner-container: orange;--ngx-timeline-icon: orange;--ngx-timeline-line-background: #464646;--ngx-timeline-flex-display-col: 49 49 0;--ngx-timeline-flex-display-col-center: 2 2 0;--ngx-timeline-event-background: white;--ngx-timeline-event-divider-background: #e9e9e9;--ngx-timeline-event-text-color: black}.event-wrapper-container{display:flex;justify-content:center;align-items:center;cursor:pointer;color:var(--ngx-timeline-event-text-color)}.event-wrapper-container.horizontal{display:flex;flex-direction:column;padding:0 3rem}.event-wrapper-container.horizontal .event-container.reverse{flex-direction:row}.event-wrapper-container.horizontal .event{margin:0}.event-wrapper-container.horizontal .arrow.right{border-left:.5rem solid transparent;border-right:.5rem solid transparent;border-top:.5rem solid var(--ngx-timeline-event-background);border-bottom:none}.event-wrapper-container.horizontal .arrow.left{border-left:.5rem solid transparent;border-right:.5rem solid transparent;border-bottom:.5rem solid var(--ngx-timeline-event-background);border-top:none}.arrow{width:0;height:0;border-top:.5rem solid transparent;border-bottom:.5rem solid transparent;border-radius:6px;z-index:10}.arrow.right{filter:drop-shadow(2px 0px 0px rgba(36,74,110,.1333333333));border-left:.5rem solid var(--ngx-timeline-event-background)}.arrow.left{filter:drop-shadow(-1px 0px 0px rgba(36,74,110,.1333333333));border-right:.5rem solid var(--ngx-timeline-event-background)}.event{background:var(--ngx-timeline-event-background);border-radius:.8rem;padding:1rem;width:100%;margin:1rem 0}.event.enableAnimation:hover{padding:2rem;transition:all .5s ease-in-out}.event.enableAnimation:not(:hover){padding:1rem;transition:all .5s ease-in-out}.event:not(.hour){background:var(--ngx-timeline-event-background) 0% 0% no-repeat padding-box;box-shadow:0 3px 6px #244a6e52}.event.hour{padding:.5rem;background:none;display:flex;justify-content:center;align-items:center}.event.hour.right{justify-content:flex-start}.event.hour.left{justify-content:flex-end}.event .hour-inner-container{margin:0}.event-container{display:flex}.event-container.reverse{flex-direction:row-reverse}.event-container .event-info-container{display:flex;flex-direction:column;align-items:flex-start;padding:.1rem;flex:88 88 0}.event-container .event-info-container .event-info-header{display:flex;align-items:center;width:100%}.event-container .event-info-container .event-info-header .icon-container{margin-right:.3rem}.event-container .event-info-container .event-info-header .title-container{font-weight:700;font-size:15px}.event-container .event-info-container .event-info-body{padding:.5rem 0;display:flex;flex-direction:column;justify-content:flex-start;overflow-wrap:anywhere}.event-container .event-info-container .event-info-body .event-info-description{margin-bottom:.5rem;font-size:13px}.event-container .event-info-container .event-info-body .expiration-container,.event-container .event-info-container .event-info-body .category-container{display:flex;font-size:13px;justify-content:flex-start;align-items:center}.event-container .event-info-container .event-info-body .expiration-container p,.event-container .event-info-container .event-info-body .category-container p{font-size:13px;margin:0}.event-container .event-info-container .event-info-body .expiration-container .expiration-label,.event-container .event-info-container .event-info-body .expiration-container .category-label,.event-container .event-info-container .event-info-body .category-container .expiration-label,.event-container .event-info-container .event-info-body .category-container .category-label{margin-right:.5rem}.event-container .event-info-container .event-info-body .expiration-container .expiration-value,.event-container .event-info-container .event-info-body .expiration-container .category-value,.event-container .event-info-container .event-info-body .category-container .expiration-value,.event-container .event-info-container .event-info-body .category-container .category-value{font-weight:700}.event-container .event-info-container .event-info-footer{font-size:15px;cursor:pointer;padding-top:1rem}.event-container .event-info-container .event-info-footer .footer-inner-container{display:flex;justify-content:flex-start;align-items:flex-end}.event-container .event-divider-container{display:flex;justify-content:center;align-items:center;padding:.1rem;flex:5 5 0}.event-container .event-divider-container hr{height:100%;width:1px;background:var(--ngx-timeline-event-divider-background)}.event-container .event-date-container{display:flex;justify-content:center;align-items:center;flex-direction:column;padding:.1rem;flex:15 15 0}.event-container .event-date-container p{margin:0;text-align:center}.event-container .event-date-container p.day{font-size:32px;font-weight:700;padding:.5rem 0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxTimelineEventComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-timeline-event', imports: [ NgTemplateOutlet, TitleCasePipe, ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"event-wrapper-container\" (click)=\"clickEmitter.emit(event())\" [class.horizontal]=\"orientation() === ngxTimelineOrientation.HORIZONTAL\">\n @if (colSidePosition()===ngxTimelineItemPosition.ON_RIGHT) {\n <div class=\"arrow left\"></div>\n }\n <div class=\"event\" [class.enableAnimation]=\"enableAnimation()\">\n <ng-container *ngTemplateOutlet=\"innerEventCustomTemplate() || innerEventContainer; context: {event: event()}\"></ng-container>\n </div>\n @if (colSidePosition() === ngxTimelineItemPosition.ON_LEFT) {\n <div class=\"arrow right\"></div>\n }\n</div>\n\n<ng-template #innerEventContainer let-event=event>\n <div class=\"event-container\" [class.reverse]=\"colSidePosition() === ngxTimelineItemPosition.ON_LEFT\">\n <div class=\"event-info-container\">\n <div class=\"event-info-header\">\n <div class=\"title-container\">{{event?.eventInfo?.title | titlecase}}</div>\n </div>\n <div class=\"event-info-body\">\n <ng-container *ngTemplateOutlet=\"eventDescriptionCustomTemplate() || eventDescriptionContainer; context: {event: event}\"></ng-container>\n </div>\n </div>\n\n <div class=\"event-divider-container\">\n <hr>\n </div>\n\n @if (getDateObj(); as dateObj) {\n <div class=\"event-date-container\">\n <div>\n <p>{{dateObj?.month}}</p>\n </div>\n <div>\n <p class=\"day\">{{dateObj?.day}}</p>\n </div>\n <div>\n <p>{{dateObj?.year}}</p>\n </div>\n </div>\n }\n </div>\n</ng-template>\n\n\n<ng-template #eventDescriptionContainer let-event=event>\n <p class=\"event-info-description\">{{event?.eventInfo?.description}}</p>\n</ng-template>\n", styles: ["::ng-deep :root{--ngx-timeline-period-inner-container: orange;--ngx-timeline-icon: orange;--ngx-timeline-line-background: #464646;--ngx-timeline-flex-display-col: 49 49 0;--ngx-timeline-flex-display-col-center: 2 2 0;--ngx-timeline-event-background: white;--ngx-timeline-event-divider-background: #e9e9e9;--ngx-timeline-event-text-color: black}.event-wrapper-container{display:flex;justify-content:center;align-items:center;cursor:pointer;color:var(--ngx-timeline-event-text-color)}.event-wrapper-container.horizontal{display:flex;flex-direction:column;padding:0 3rem}.event-wrapper-container.horizontal .event-container.reverse{flex-direction:row}.event-wrapper-container.horizontal .event{margin:0}.event-wrapper-container.horizontal .arrow.right{border-left:.5rem solid transparent;border-right:.5rem solid transparent;border-top:.5rem solid var(--ngx-timeline-event-background);border-bottom:none}.event-wrapper-container.horizontal .arrow.left{border-left:.5rem solid transparent;border-right:.5rem solid transparent;border-bottom:.5rem solid var(--ngx-timeline-event-background);border-top:none}.arrow{width:0;height:0;border-top:.5rem solid transparent;border-bottom:.5rem solid transparent;border-radius:6px;z-index:10}.arrow.right{filter:drop-shadow(2px 0px 0px rgba(36,74,110,.1333333333));border-left:.5rem solid var(--ngx-timeline-event-background)}.arrow.left{filter:drop-shadow(-1px 0px 0px rgba(36,74,110,.1333333333));border-right:.5rem solid var(--ngx-timeline-event-background)}.event{background:var(--ngx-timeline-event-background);border-radius:.8rem;padding:1rem;width:100%;margin:1rem 0}.event.enableAnimation:hover{padding:2rem;transition:all .5s ease-in-out}.event.enableAnimation:not(:hover){padding:1rem;transition:all .5s ease-in-out}.event:not(.hour){background:var(--ngx-timeline-event-background) 0% 0% no-repeat padding-box;box-shadow:0 3px 6px #244a6e52}.event.hour{padding:.5rem;background:none;display:flex;justify-content:center;align-items:center}.event.hour.right{justify-content:flex-start}.event.hour.left{justify-content:flex-end}.event .hour-inner-container{margin:0}.event-container{display:flex}.event-container.reverse{flex-direction:row-reverse}.event-container .event-info-container{display:flex;flex-direction:column;align-items:flex-start;padding:.1rem;flex:88 88 0}.event-container .event-info-container .event-info-header{display:flex;align-items:center;width:100%}.event-container .event-info-container .event-info-header .icon-container{margin-right:.3rem}.event-container .event-info-container .event-info-header .title-container{font-weight:700;font-size:15px}.event-container .event-info-container .event-info-body{padding:.5rem 0;display:flex;flex-direction:column;justify-content:flex-start;overflow-wrap:anywhere}.event-container .event-info-container .event-info-body .event-info-description{margin-bottom:.5rem;font-size:13px}.event-container .event-info-container .event-info-body .expiration-container,.event-container .event-info-container .event-info-body .category-container{display:flex;font-size:13px;justify-content:flex-start;align-items:center}.event-container .event-info-container .event-info-body .expiration-container p,.event-container .event-info-container .event-info-body .category-container p{font-size:13px;margin:0}.event-container .event-info-container .event-info-body .expiration-container .expiration-label,.event-container .event-info-container .event-info-body .expiration-container .category-label,.event-container .event-info-container .event-info-body .category-container .expiration-label,.event-container .event-info-container .event-info-body .category-container .category-label{margin-right:.5rem}.event-container .event-info-container .event-info-body .expiration-container .expiration-value,.event-container .event-info-container .event-info-body .expiration-container .category-value,.event-container .event-info-container .event-info-body .category-container .expiration-value,.event-container .event-info-container .event-info-body .category-container .category-value{font-weight:700}.event-container .event-info-container .event-info-footer{font-size:15px;cursor:pointer;padding-top:1rem}.event-container .event-info-container .event-info-footer .footer-inner-container{display:flex;justify-content:flex-start;align-items:flex-end}.event-container .event-divider-container{display:flex;justify-content:center;align-items:center;padding:.1rem;flex:5 5 0}.event-container .event-divider-container hr{height:100%;width:1px;background:var(--ngx-timeline-event-divider-background)}.event-container .event-date-container{display:flex;justify-content:center;align-items:center;flex-direction:column;padding:.1rem;flex:15 15 0}.event-container .event-date-container p{margin:0;text-align:center}.event-container .event-date-container p.day{font-size:32px;font-weight:700;padding:.5rem 0}\n"] }] }], propDecorators: { event: [{ type: i0.Input, args: [{ isSignal: true, alias: "event", required: true }] }], colSidePosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "colSidePosition", required: false }] }], langCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "langCode", required: false }] }], innerEventCustomTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "innerEventCustomTemplate", required: false }] }], eventDescriptionCustomTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "eventDescriptionCustomTemplate", required: false }] }], enableAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableAnimation", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], clickEmitter: [{ type: i0.Output, args: ["clickEmitter"] }] } }); class NgxTimelineComponent { /** * List of events to be displayed. */ events = input.required({ ...(ngDevMode ? { debugName: "events" } : {}) }); /** * Language code used to show the date formatted. */ langCode = input(defaultSupportedLanguageCode, { ...(ngDevMode ? { debugName: "langCode" } : {}) }); /** * Boolean used to enable or disable the animations. */ enableAnimation = input(true, { ...(ngDevMode ? { debugName: "enableAnimation" } : {}) }); /** * Boolean used to reverse sort order (default older first). */ reverseOrder = input(false, { ...(ngDevMode ? { debugName: "reverseOrder" } : {}) }); /** * Orientation of the timeline. */ orientation = input(NgxTimelineOrientation.VERTICAL, { ...(ngDevMode ? { debugName: "orientation" } : {}) }); /** * Logic to be applied in order to group events. */ groupEvent = input(NgxTimelineEventGroup.MONTH_YEAR, { ...(ngDevMode ? { debugName: "groupEvent" } : {}) }); /** * Logic to be applied in order to put events on LEFT or RIGHT. */ changeSide = input(NgxTimelineEventChangeSide.ON_DIFFERENT_DAY_IN_GROUP, { ...(ngDevMode ? { debugName: "changeSide" } : {}) }); /** * Custom Template displayed before a group of events. */ periodCustomTemplate = input(undefined, { ...(ngDevMode ? { debugName: "periodCustomTemplate" } : {}) }); /** * Custom Template displayed to show a single event. */ eventCustomTemplate = input(undefined, { ...(ngDevMode ? { debugName: "eventCustomTemplate" } : {}) }); /** * Custom Template displayed to show a separator icon. */ centerIconCustomTemplate = input(undefined, { ...(ngDevMode ? { debugName: "centerIconCustomTemplate" } : {}) }); /** * Custom Template displayed to show the side date. */ dateInstantCustomTemplate = input(undefined, { ...(ngDevMode ? { debugName: "dateInstantCustomTemplate" } : {}) }); /** * Custom Template displayed to show the inner event. */ innerEventCustomTemplate = input(undefined, { ...(ngDevMode ? { debugName: "innerEventCustomTemplate" } : {}) }); /** * Inner custom template used to display the event description. */ eventDescriptionCustomTemplate = input(undefined, { ...(ngDevMode ? { debugName: "eventDescriptionCustomTemplate" } : {}) }); /** * Enable virtual scrolling, for rendering performance. Useful when rendering thousands of items. */ virtualScroll = input(false, { ...(ngDevMode ? { debugName: "virtualScroll" } : {}) }); /** * The size of the items in the list (in pixels). */ virtualScrollItemSize = input(100, { ...(ngDevMode ? { debugName: "virtualScrollItemSize" } : {}) }); /** * The number of pixels worth of buffer to render for when rendering new items. Defaults to 200px. */ virtualScrollMaxBufferPx = input(200, { ...(ngDevMode ? { debugName: "virtualScrollMaxBufferPx" } : {}) }); /** * The minimum amount of buffer rendered beyond the viewport (in pixels). * If the amount of buffer dips below this number, more items will be rendered. Defaults to 100px. */ virtualScrollMinBufferPx = input(100, { ...(ngDevMode ? { debugName: "virtualScrollMinBufferPx" } : {}) }); /** * Output click event emitter. */ clickEmitter = output(); groups = {}; periods = []; items = []; ngxTimelineItemPosition = NgxTimelineItemPosition; ngxTimelineOrientation = NgxTimelineOrientation; ngxDateFormat = NgxDateFormat; differs = inject(IterableDiffers); iterableDiffer = this.differs.find([]).create(); separator = '/'; ngOnChanges() { this.groupEvents(this.events()); } ngDoCheck() { const changes = this.iterableDiffer.diff(this.events()); if (changes) { this.groupEvents(this.events()); } } getPeriodKeyDateFormat() { return periodKeyDateFormat[this.groupEvent()]; } clear() { this.groups = {}; this.periods = []; this.items = []; } groupEvents(events) { if (events) { this.clear(); this.sortEvents(events); this.setGroupsAndPeriods(events); this.setItems(); } } sortEvents(events) { events.sort((a, b) => { const aTime = a.timestamp.getTime(); const bTime = b.timestamp.getTime(); return this.reverseOrder() ? bTime - aTime : aTime - bTime; }); } setGroupsAndPeriods(events) { this.periods = []; events.forEach((event) => { // conversion from string to actual Date event.timestamp = new Date(event.timestamp); const periodKey = this.getPeriodKeyFromEvent(event); if (!this.groups[periodKey]) { this.groups[periodKey] = []; this.periods.push({ periodInfo: this.getPeriodInfoFromPeriodKey(periodKey, event) }); } this.groups[periodKey].push(event); }); } setItems() { let isLastItemOnLeft = false; this.periods.forEach((p) => { // insert first the period this.items.push(p); // in each period putting items on left let onLeft = true; if (this.changeSide() === NgxTimelineEventChangeSide.ALL) { onLeft = !isLastItemOnLeft; } const periodInfo = p.periodInfo; if (periodInfo) { // insert then all the events in this period isLastItemOnLeft = this.addPeriodEvents(periodInfo, onLeft); // onLeft = this.addEventItemsAndGetIfOnLeft(periodInfo, onLeft); } }); } addPeriodEvents(periodInfo, onLeft) { const periodKey = periodInfo?.periodKey; if (periodKey == undefined) { return onLeft; } this.groups[periodKey].forEach((event, index) => { const prevEvent = this.groups[periodKey][index - 1]; if (event.itemPosition) { onLeft = event.itemPosition && event.itemPosition === NgxTimelineItemPosition.ON_LEFT; } else if (index > 0 && this.compareEvents(prevEvent, event)) { onLeft = !onLeft; } this.pushEventOnItems(event, onLeft); }); return onLeft; } pushEventOnItems(event, onLeft) { this.items.push({ eventInfo: { ...event }, position: onLeft ? this.ngxTimelineItemPosition.ON_LEFT : this.ngxTimelineItemPosition.ON_RIGHT, }); } /** * Compare the events inside the same group */ compareEvents(prevEvent, event) { return this.shouldChangeEventsInPeriod() || this.compareEventsField(prevEvent, event, ...(fieldsToCheckEventChangeSideInGroup[this.changeSide()] ?? [])); } compareEventsField(prevEvent, event, ...fields) { return fields.reduce((res, field) => res = res || prevEvent.timestamp[field]() !== event.timestamp[field](), false); } getPeriodInfoFromPeriodKey(periodKey, firstGroupEvent) { const split = periodKey.split(this.separator); return this.getPeriodInfo(split, periodKey, firstGroupEvent); } getPeriodInfo(split, periodKey, firstGroupEvent) { return { year: Number(split[0]), month: Number(split[1]), day: Number(split[2]), periodKey, firstDate: firstGroupEvent.timestamp, }; } shouldChangeEventsInPeriod() { return [NgxTimelineEventChangeSide.ALL_IN_GROUP, NgxTimelineEventChangeSide.ALL].includes(this.changeSide()); } getPeriodKeyFromEvent(event) { return fieldsToAddEventGroup[this.groupEvent()].map(field => event.timestamp[field]()).join(this.separator); } getOrientationForVirtualScroll() { return this.orientation().toLowerCase(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxTimelineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: NgxTimelineComponent, isStandalone: true, selector: "ngx-timeline", inputs: { events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: true, transformFunction: null }, langCode: { classPropertyName: "langCode", publicName: "langCode", isSignal: true, isRequired: false, transformFunction: null }, enableAnimation: { classPropertyName: "enableAnimation", publicName: "enableAnimation", isSignal: true, isRequired: false, transformFunction: null }, reverseOrder: { classPropertyName: "reverseOrder", publicName: "reverseOrder", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, groupEvent: { classPropertyName: "groupEvent", publicName: "groupEvent", isSignal: true, isRequired: false, transformFunction: null }, changeSide: { classPropertyName: "changeSide", publicName: "changeSide", isSignal: true, isRequired: false, transformFunction: null }, periodCustomTemplate: { classPropertyName: "periodCustomTemplate", publicName: "periodCustomTemplate", isSignal: true, isRequired: false, transformFunction: null }, eventCustomTemplate: { classPropertyName: "eventCustomTemplate", publicName: "eventCustomTemplate", isSignal: true, isRequired: false, transformFunction: null }, centerIconCustomTemplate: { classPropertyName: "centerIconCustomTemplate", publicName: "centerIconCustomTemplate", isSignal: true, isRequired: false, transformFunction: null }, dateInstantCustomTemplate: { classPropertyName: "dateInstantCustomTemplate", publicName: "dateInstantCustomTemplate", isSignal: true, isRequired: false, transformFunction: null }, innerEventCustomTemplate: { classPropertyName: "innerEventCustomTemplate", publicName: "innerEventCustomTemplate", isSignal: true, isRequired: false, transformFunction: null }, eventDescriptionCustomTemplate: { classPropertyName: "eventDescriptionCustomTemplate", publicName: "eventDescriptionCustomTemplate", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollMaxBufferPx: { classPropertyName: "virtualScrollMaxBufferPx", publicName: "virtualScrollMaxBufferPx", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollMinBufferPx: { classPropertyName: "virtualScrollMinBufferPx", publicName: "virtualScrollMinBufferPx", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickEmitter: "clickEmitter" }, usesOnChanges: true, ngImport: i0, template: "<div [ngClass]=\"virtualScroll() ? 'virtual-scroll-container' : 'main-container'\">\r\n @if (virtualScroll()) {\r\n <cdk-virtual-scroll-viewport\r\n class=\"items-container\"\r\n [class.horizontal]=\"orientation() === ngxTimelineOrientation.HORIZONTAL\"\r\n [orientation]=\"getOrientationForVirtualScroll()\"\r\n [itemSize]=\"virtualScrollItemSize()\"\r\n [maxBufferPx]=\"virtualScrollMaxBufferPx()\"\r\n [minBufferPx]=\"virtualScrollMinBufferPx()\"\r\n >\r\n <div *cdkVirtualFor=\"let item of items\">\r\n <ng-template\r\n *ngTemplateOutlet=\"rowTemplate; context: { item: item }\"\r\n ></ng-template>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n } @else {\r\n <div class=\"items-container\" [class.horizontal]=\"orientation() === ngxTimelineOrientation.HORIZONTAL\">\r\n @for (item of items; track item; let index = $index) {\r\n <ng-template\r\n *ngTemplateOutlet=\"rowTemplate; context: { item: item, index: index }\"\r\n ></ng-template>\r\n }\r\n </div>\r\n }\r\n</div>\r\n\r\n<ng-template #rowTemplate let-item=\"item\" let-index=\"index\">\r\n <div class=\"row\">\r\n <!-- DESKTOP -->\r\n <div class=\"col col-left desktop\" [ngClass]=\"item.periodInfo ? 'col-period' : 'col-event'\">\r\n @if (item.eventInfo && item.position === ngxTimelineItemPosition.ON_LEFT) {\r\n <div class=\"event-outer-container\">\r\n <ng-container *ngTemplateOutlet=\"eventCustomTemplate() || eventTemplate; context: {event: item, colSidePosition: ngxTimelineItemPosition.ON_LEFT}\"></ng-container>\r\n </div>\r\n }\r\n @if (item.eventInfo && item.position === ngxTimelineItemPosition.ON_RIGHT) {\r\n <div class=\"hour left\">\r\n <ng-container *ngTemplateOutlet=\"dateInstantCustomTemplate() || dateInstantTemplate; context: {item: item.eventInfo}\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"col col-center desktop\" [ngClass]=\"item.periodInfo ? 'col-period' : 'col-event'\">\r\n @if (item.periodInfo) {\r\n <div class=\"center-inner\">\r\n <ng-container *ngTemplateOutlet=\"periodContainerTemplate; context: {period: item.periodInfo, index: index, event: item}\"></ng-container>\r\n </div>\r\n }\r\n @if (!item.periodInfo) {\r\n <div class=\"center-inner no-period-key\">\r\n <ng-container *ngTemplateOutlet=\"centerLinesIconTemplate; context: {event: item, index: index}\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"col col-right desktop\" [ngClass]=\"item.periodInfo ? 'col-period' : 'col-event'\">\r\n @if (item.eventInfo && item.position === ngxTimelineItemPosition.ON_RIGHT) {\r\n <div class=\"event-outer-container\">\r\n <ng-container *ngTemplateOutlet=\"eventCustomTemplate() || eventTemplate; context: {event: item, colSidePosition: ngxTimelineItemPosition.ON_RIGHT}\"></ng-container>\r\n </div>\r\n }\r\n @if (item.eventInfo && item.position === ngxTimelineItemPosition.ON_LEFT) {\r\n <div class=\"hour right\">\r\n <ng-container *ngTemplateOutlet=\"dateInstantCustomTemplate() || dateInstantTemplate; context: {item: item.eventInfo}\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n <!-- MOBILE -->\r\n <div class=\"col col-left mobile\" [ngClass]=\"item.periodInfo ? 'col-period' : 'col-event'\">\r\n @if (item.eventInfo) {\r\n <div class=\"hour left\">\r\n <div class=\"hour-inner-container\">\r\n <ng-container *ngTemplateOutlet=\"dateInstantCustomTemplate() || dateInstantTemplate; context: {item: item.eventInfo}\"></ng-container>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"col col-center mobile\" [ngClass]=\"item.periodInfo ? 'col-period' : 'col-event'\">\r\n @if (item.periodInfo) {\r\n <div class=\"center-inner\">\r\n <ng-container *ngTemplateOutlet=\"periodContainerTemplate; context: {period: item.periodInfo, index: index, event: item}\"></ng-container>\r\n </div>\r\n }\r\n @if (!item.periodInfo) {\r\n <div class=\"center-inner no-period-key\">\r\n <ng-container *ngTemplateOutlet=\"centerLinesIconTemplate; context: {event: item, index: index}\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"col col-right mobile\" [ngClass]=\"item.periodInfo ? 'col-period' : 'col-event'\">\r\n @if (item.eventInfo) {\r\n <div class=\"event-outer-container\">\r\n <ng-container *ngTemplateOutlet=\"eventCustomTemplate() || eventTemplate; context: {event: item, colSidePosition: ngxTimelineItemPosition.ON_RIGHT}\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #centerLinesIconTemplate let-index=index let-event=event>\r\n <div class=\"line\"></div>\r\n <ng-container *ngTemplateOutlet=\"centerIconCustomTemplate() || centerIconTemplate; context: {index:index, event:event}\"></ng-container>\r\n <div [class.transparent]=\"index === items.length - 1\" [class.last-line]=\"index === items.length - 1\" class=\"line\"></div>\r\n</ng-template>\r\n\r\n<ng-template #centerIconTemplate let-index=index let-event=event>\r\n <div class=\"center-icon-container\">\r\n <div class=\"icon\"></div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dateInstantTemplate let-item=item>\r\n <span>\r\n {{item?.timestamp | ngxdate : ngxDateFormat.HOURS_MINUTES : langCode()}}\r\n </span>\r\n</ng-template>\r\n\r\n<ng-template #periodContainerTemplate let-period=period let-index=index let-event=event>\r\n <div class=\"period-container\">\r\n <ng-container *ngTemplateOutlet=\"periodCustomTemplate() || periodTemplate; context: {period: period, index:index, event:event}\"></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #periodTemplate let-period=period>\r\n <div class=\"period-inner-container\">\r\n <span>{{period?.firstDate | ngxdate : getPeriodKeyDateFormat() : langCode()}}</span>\r\n </div>\r\n</ng-template>\r\n\r\n\r\n<ng-template #eventTemplate let-event=event let-colSidePosition=colSidePosition>\r\n <ngx-timeline-event\r\n [event]=\"event\"\r\n [langCode]=\"langCode()\"\r\n [orientation]=\"orientation()\"\r\n [enableAnimation]=\"enableAnimation()\"\r\n [innerEventCustomTemplate]=\"innerEventCustomTemplate()\"\r\n [eventDescriptionCustomTemplate]=\"eventDescriptionCustomTemplate()\"\r\n [colSidePosition]=\"colSidePosition\"\r\n (clickEmitter)=\"clickEmitter.emit($event)\">\r\n </ngx-timeline-event>\r\n</ng-template>\r\n\r\n", styles: ["::ng-deep :root{--ngx-timeline-period-inner-container: orange;--ngx-timeline-icon: orange;--ngx-timeline-line-background: #464646;--ngx-timeline-flex-display-col: 49 49 0;--ngx-timeline-flex-display-col-center: 2 2 0;--ngx-timeline-event-background: white;--ngx-timeline-event-divider-background: #e9e9e9;--ngx-timeline-event-text-color: black}.main-container,.virtual-scroll-container{display:flex;justify-content:center;width:100%}.virtual-scroll-container{height:100%}.virtual-scroll-container>.horizontal ::ng-deep .cdk-virtual-scroll-content-wrapper{width:max-content;display:flex;flex-direction:row}.virtual-scroll-container>.horizontal{min-height:0}.items-container{padding:1rem 0;min-width:max(20rem,100%)}.items-container.horizontal{display:flex;flex-direction:row;min-height:max(20rem,100%)}.items-container.horizontal .row{min-width:fit-content;flex-direction:column}.items-container.horizontal .row>[class*=col-]{display:flex;flex-direction:column;align-items:center}.items-container.horizontal .col-center{min-height:2rem}.items-container.horizontal .col-left{min-height:300px;align-items:center;justify-content:flex-end}.items-container.horizontal .col-right{min-height:300px;align-items:center;justify-content:flex-start}.items-container.horizontal .center-inner{display:flex;flex-direction:row}.items-container.horizontal .center-inner .line{max-width:50%;width:50%;height:.1rem;min-height:.1rem;max-height:.1rem}.items-container.horizontal .center-icon-container{padding:0 .5rem}.row{display:flex;flex-wrap:wrap}.row>[class*=col-]{display:flex;flex-direction:column;justify-content:center}.col-left{align-items:flex-end;padding:0;flex:var(--ngx-timeline-flex-display-col)}.col-right{align-items:flex-start;padding:0;flex:var(--ngx-timeline-flex-display-col)}.col-center:not(.col-period){min-height:10rem}.col-center{padding:0;flex:var(--ngx-timeline-flex-display-col-center)}.center-inner{width:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%}.center-inner .line{flex:50 50 0;background:var(--ngx-timeline-line-background);width:.1rem}.center-inner .line.transparent{background:transparent}.period-container .period-inner-container{color:#fff;border-radius:2px;background:var(--ngx-timeline-period-inner-container);width:max-content;padding:.2rem .5rem;z-index:10}.center-icon-container{padding:.8rem 0;display:flex;justify-content:center;align-items:center;position:relative;height:10px;width:10px}.center-icon-container .icon{height:1rem;width:1rem;border-radius:50%;background:var(--ngx-timeline-icon);margin:0;position:absolute}.event-outer-container{margin:0 .5rem;width:97%}.hour{padding:.5rem;background:none;display:flex;justify-content:center;align-items:center}.hour.right{justify-content:flex-start}.hour.left{justify-content:flex-end}.hour .hour-inner-container{margin:0}.desktop{display:flex!important}.mobile{display:none!important}@media(max-width:900px){.desktop{display:none!important}.mobile{display:flex!important}.items-container{min-width:max(20rem,95%)}.items-container.horizontal .event-outer-container{margin:0 .5rem}.items-container.horizontal .col-left{min-height:6rem}.items-container.horizontal .col-center{min-height:2rem}.event-outer-container{margin:.5rem .3rem}.col-left{align-items:flex-start}.col-left .hour{font-size:clamp(10px,2.5vw,12px);padding:0;margin-right:.3rem}.col-left.col-period{flex:14 14 0}.col-left.col-event{flex:17 17 0;padding:0;align-items:flex-end}.col-right{align-items:flex-start}.col-right.col-period{flex:77 77 0}.col-right.col-event{flex:77 77 0;padding:0}.col-center{justify-content:center;margin:0}.col-center.col-period,.col-center.col-event{flex:5 5 0}.center-inner{align-items:center}.period-container{height:fit-content;display:flex;justify-content:center;align-items:center;position:relative}.center-icon-container{align-items:center;justify-content:center}.center-icon-container .icon{height:1rem;width:1rem;position:absolute}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgxTimelineEventComponent, selector: "ngx-timeline-event", inputs: ["event", "colSidePosition", "langCode", "innerEventCustomTemplate", "eventDescriptionCustomTemplate", "enableAnimation", "orientation"], outputs: ["clickEmitter"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "pipe", type: NgxDatePipe, name: "ngxdate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxTimelineComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-timeline', imports: [ NgClass, NgTemplateOutlet, NgxDatePipe, NgxTimelineEventComponent, ScrollingModule, ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"virtualScroll() ? 'virtual-scroll-container' : 'main-container'\">\r\n @if (virtualScroll()) {\r\n <cdk-virtual-scroll-viewport\r\n class=\"items-container\"\r\n [class.horizontal]=\"orientation() === ngxTimelineOrientation.HORIZONTAL\"\r\n [orientation]=\"getOrientationForVirtualScroll()\"\r\n [itemSize]=\"virtualScrollItemSize()\"\r\n [maxBufferPx]=\"virtualScrollMaxBufferPx()\"\r\n [minBufferPx]=\"virtualScrollMinBufferPx()\"\r\n >\r\n <div *cdkVirtualFor=\"let item of items\">\r\n <ng-template\r\n *ngTemplateOutlet=\"rowTemplate; context: { item: item }\"\r\n ></ng-template>\r\n