@progress/kendo-angular-layout
Version:
Kendo UI for Angular Layout Package - a collection of components to create professional application layoyts
459 lines (458 loc) • 18 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Component, ContentChildren, EventEmitter, HostBinding, Input, Output, QueryList, ViewChild } from '@angular/core';
import { defaultModelFields } from './models/default-model-fields';
import { processItems } from './util';
import { TimelineHorizontalComponent } from './timeline-horizontal.component';
import { TimelineVerticalComponent } from './timeline-vertical.component';
import { TimelineService } from './timeline.service';
import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n';
import { TimelineCardBodyTemplateDirective } from './templates/timeline-card-body.directive';
import { TimelineCardHeaderTemplateDirective } from './templates/timeline-card-header.directive';
import { Subscription } from 'rxjs';
import { TimelineCardActionsTemplateDirective } from './templates/timeline-card-actions.directive';
import { isPresent } from '@progress/kendo-angular-common';
import { NgIf } from '@angular/common';
import { LocalizedTimelineMessagesDirective } from './localization/localized-messages.directive';
import * as i0 from "@angular/core";
import * as i1 from "./timeline.service";
const DEFAULT_HORIZONTAL_ANIMATION_DURATION = 400;
const DEFAULT_VERTICAL_ANIMATION_DURATION = 300;
const DEFAULT_EVENT_WIDTH = 400;
const DEFAULT_EVENT_HEIGHT = 600;
const DEFAULT_DATE_FORMAT = 'MMMM dd, yyyy';
/**
* Represents the [Kendo UI Timeline component for Angular]({% slug overview_timeline %}).
*/
export class TimelineComponent {
timelineService;
/**
* An array of event instances which will be shown by the Timeline.
*/
set events(events) {
if (!isPresent(events)) {
return;
}
this.originalData = events;
this._events = processItems(this.originalData, this.modelFields);
this._events.sort((a, b) => {
return a.date.getTime() - b.date.getTime();
});
if (this._events.length > 0) {
let flag = this._events[0].date.getFullYear() - 1;
this._events.forEach((event) => {
if (event.date.getFullYear() !== flag) {
flag = event.date.getFullYear();
event.flag = flag;
}
});
}
}
get events() {
return this._events;
}
/**
* The names of the model fields from which the Timeline will read its data.
*/
set modelFields(value) {
this._modelFields = { ...defaultModelFields, ...value };
if (this.originalData) {
this.events = this.originalData;
}
}
get modelFields() {
return this._modelFields;
}
/**
* Specifies the orientation of the axis.
*
* @default 'vertical'
*/
orientation = 'vertical';
/**
* Specifies whether to render events alternatingly on both sides of the axis.
* Applicable when `orientation` is set to `vertical`.
*
* @default false
*/
alterMode = false;
/**
* Specifies whether the event cards can be collapsed.
*
* @default true
*/
collapsibleEvents = true;
/**
* Specifies whether the user can use dedicated shortcuts to interact with the Timeline.
*
* @default true
*/
navigable = true;
/**
* Specifies whether an event's date label will be visible.
*
* @default true
*/
showDateLabels = true;
/**
* Specifies the time for sliding to the next event in `horizontal` mode and the time for collapsing the event in `vertical` mode.
* The default animation duration values are `300ms` for `horizontal` mode and `400ms` for `vertical` mode.
*
* @default true
*/
animation;
/**
* Sets a specific width for the event.
* This setting is supported only in `vertical` mode.
*
* @default 400
*/
get eventWidth() {
return this._eventWidth;
}
set eventWidth(value) {
if (value) {
this._eventWidth = value;
}
else {
this._eventWidth = DEFAULT_EVENT_WIDTH;
}
}
/**
* Sets a specific height for the event.
* This setting is supported only in `horizontal` mode.
*
* @default 600
*/
get eventHeight() {
return this._eventHeight;
}
set eventHeight(value) {
if (value) {
this._eventHeight = value;
}
else {
this._eventHeight = DEFAULT_EVENT_HEIGHT;
}
}
/**
* @hidden
*/
get animationDuration() {
if (typeof this.animation === 'number') {
return this.animation;
}
if ((typeof this.animation === 'boolean' && this.animation) || !isPresent(this.animation)) {
return this.orientation === 'horizontal' ? DEFAULT_HORIZONTAL_ANIMATION_DURATION : DEFAULT_VERTICAL_ANIMATION_DURATION;
}
return 0;
}
/**
* Specifies the date format for displaying the event date.
*
* @default 'MMMM dd, yyyy'
*/
set dateFormat(value) {
if (isPresent(value) && value !== '') {
this._dateFormat = value;
}
else {
this._dateFormat = DEFAULT_DATE_FORMAT;
}
}
get dateFormat() {
return this._dateFormat;
}
hostClass = true;
get verticalClass() {
return this.orientation === 'vertical';
}
get horizontalClass() {
return this.orientation === 'horizontal';
}
get alternatingClass() {
return this.alterMode === true && this.orientation === 'vertical';
}
get collapsibleClass() {
return this.collapsibleEvents === true && this.orientation === 'vertical';
}
/**
* @hidden
*/
timelineHorizontal;
/**
* @hidden
*/
timelineVertical;
/**
* @hidden
*/
cardHeaderTemplate;
/**
* @hidden
*/
cardBodyTemplate;
/**
* @hidden
*/
cardActionsTemplate;
/**
* Fires when a card is toggled.
* This event is supported only in `vertical` mode.
*/
onToggle = new EventEmitter();
/**
* Fires when a card's action is clicked.
*/
onActionClick = new EventEmitter();
/**
* Fires when the left or right arrow is clicked.
* This event is supported only in `horizontal` mode.
*/
onNavigate = new EventEmitter();
/**
* @hidden
*/
headerTemplate;
/**
* @hidden
*/
bodyTemplate;
/**
* @hidden
*/
actionsTemplate;
_events = [];
_modelFields = defaultModelFields;
_eventWidth = DEFAULT_EVENT_WIDTH;
_eventHeight = DEFAULT_EVENT_HEIGHT;
_dateFormat = DEFAULT_DATE_FORMAT;
originalData = [];
subscriptions = new Subscription();
constructor(timelineService) {
this.timelineService = timelineService;
this.timelineService.timeline = this;
}
ngAfterContentInit() {
this.initTemplates();
}
ngOnDestroy() {
this.subscriptions.unsubscribe();
}
/**
* Switches to the previous portion of events.
* This method is supported only in `horizontal` mode.
*/
previous() {
this.timelineHorizontal?.previous();
}
/**
* Switches to the next portion of events.
* This method is supported only in `horizontal` mode.
*/
next() {
this.timelineHorizontal?.next();
}
/**
* Open event details.
* This method is supported only in `horizontal` mode.
*/
open(index) {
this.timelineHorizontal?.open(index);
}
/**
* Expands an event.
* This method is supported only in `vertical` mode.
*/
expand(index) {
this.timelineVertical?.expand(index);
}
/**
* Collapses an event.
* This method is supported only in `vertical` mode.
*/
collapse(index) {
this.timelineVertical?.collapse(index);
}
initTemplates() {
this.headerTemplate = this.cardHeaderTemplate?.first;
this.bodyTemplate = this.cardBodyTemplate?.first;
this.actionsTemplate = this.cardActionsTemplate?.first;
this.subscriptions.add(this.cardHeaderTemplate?.changes.subscribe(() => {
this.headerTemplate = this.cardHeaderTemplate?.first || null;
}));
this.subscriptions.add(this.cardBodyTemplate?.changes.subscribe(() => {
this.bodyTemplate = this.cardBodyTemplate?.first || null;
}));
this.subscriptions.add(this.cardActionsTemplate?.changes.subscribe(() => {
this.actionsTemplate = this.cardActionsTemplate?.first || null;
}));
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimelineComponent, deps: [{ token: i1.TimelineService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TimelineComponent, isStandalone: true, selector: "kendo-timeline", inputs: { events: "events", modelFields: "modelFields", orientation: "orientation", alterMode: "alterMode", collapsibleEvents: "collapsibleEvents", navigable: "navigable", showDateLabels: "showDateLabels", animation: "animation", eventWidth: "eventWidth", eventHeight: "eventHeight", dateFormat: "dateFormat" }, outputs: { onToggle: "onToggle", onActionClick: "onActionClick", onNavigate: "onNavigate" }, host: { properties: { "class.k-timeline": "this.hostClass", "class.k-timeline-vertical": "this.verticalClass", "class.k-timeline-horizontal": "this.horizontalClass", "class.k-timeline-alternating": "this.alternatingClass", "class.k-timeline-collapsible": "this.collapsibleClass" } }, providers: [
TimelineService,
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.timeline'
}
], queries: [{ propertyName: "cardHeaderTemplate", predicate: TimelineCardHeaderTemplateDirective }, { propertyName: "cardBodyTemplate", predicate: TimelineCardBodyTemplateDirective }, { propertyName: "cardActionsTemplate", predicate: TimelineCardActionsTemplateDirective }], viewQueries: [{ propertyName: "timelineHorizontal", first: true, predicate: TimelineHorizontalComponent, descendants: true }, { propertyName: "timelineVertical", first: true, predicate: TimelineVerticalComponent, descendants: true }], exportAs: ["kendoTimeline"], ngImport: i0, template: `
<ng-container kendoTimelineLocalizedMessages
i18n-previous="kendo.timeline.previous|The title of the previous button in horizontal orientation."
previous="previous"
>
</ng-container>
<ng-container kendoTimelineLocalizedMessages
i18n-next="kendo.timeline.next|The title of the next button in horizontal orientation."
next="next"
>
</ng-container>
<kendo-timeline-vertical
*ngIf="orientation === 'vertical'"
[events]="events"
[alterMode]="alterMode"
[collapsibleEvents]="collapsibleEvents"
[navigable]="navigable"
[showDateLabels]="showDateLabels"
[animationDuration]="animationDuration"
[eventWidth]="eventWidth"
[dateFormat]="dateFormat"
[headerTemplate]="headerTemplate"
[bodyTemplate]="bodyTemplate"
[actionsTemplate]="actionsTemplate"
>
</kendo-timeline-vertical>
<kendo-timeline-horizontal
*ngIf="orientation === 'horizontal'"
[events]="events"
[collapsibleEvents]="false"
[navigable]="navigable"
[showDateLabels]="showDateLabels"
[animationDuration]="animationDuration"
[eventHeight]="eventHeight"
[dateFormat]="dateFormat"
[headerTemplate]="headerTemplate"
[bodyTemplate]="bodyTemplate"
[actionsTemplate]="actionsTemplate"
>
</kendo-timeline-horizontal>
`, isInline: true, dependencies: [{ kind: "directive", type: LocalizedTimelineMessagesDirective, selector: "[kendoTimelineLocalizedMessages]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TimelineVerticalComponent, selector: "kendo-timeline-vertical", inputs: ["events", "alterMode", "collapsibleEvents", "navigable", "showDateLabels", "animationDuration", "eventWidth", "dateFormat", "headerTemplate", "bodyTemplate", "actionsTemplate"], exportAs: ["kendoTimelineVertical"] }, { kind: "component", type: TimelineHorizontalComponent, selector: "kendo-timeline-horizontal", inputs: ["events", "alterMode", "collapsibleEvents", "navigable", "showDateLabels", "animationDuration", "eventHeight", "dateFormat", "headerTemplate", "bodyTemplate", "actionsTemplate"], exportAs: ["kendoTimelineHorizontal"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimelineComponent, decorators: [{
type: Component,
args: [{
providers: [
TimelineService,
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.timeline'
}
],
exportAs: 'kendoTimeline',
selector: 'kendo-timeline',
template: `
<ng-container kendoTimelineLocalizedMessages
i18n-previous="kendo.timeline.previous|The title of the previous button in horizontal orientation."
previous="previous"
>
</ng-container>
<ng-container kendoTimelineLocalizedMessages
i18n-next="kendo.timeline.next|The title of the next button in horizontal orientation."
next="next"
>
</ng-container>
<kendo-timeline-vertical
*ngIf="orientation === 'vertical'"
[events]="events"
[alterMode]="alterMode"
[collapsibleEvents]="collapsibleEvents"
[navigable]="navigable"
[showDateLabels]="showDateLabels"
[animationDuration]="animationDuration"
[eventWidth]="eventWidth"
[dateFormat]="dateFormat"
[headerTemplate]="headerTemplate"
[bodyTemplate]="bodyTemplate"
[actionsTemplate]="actionsTemplate"
>
</kendo-timeline-vertical>
<kendo-timeline-horizontal
*ngIf="orientation === 'horizontal'"
[events]="events"
[collapsibleEvents]="false"
[navigable]="navigable"
[showDateLabels]="showDateLabels"
[animationDuration]="animationDuration"
[eventHeight]="eventHeight"
[dateFormat]="dateFormat"
[headerTemplate]="headerTemplate"
[bodyTemplate]="bodyTemplate"
[actionsTemplate]="actionsTemplate"
>
</kendo-timeline-horizontal>
`,
standalone: true,
imports: [LocalizedTimelineMessagesDirective, NgIf, TimelineVerticalComponent, TimelineHorizontalComponent]
}]
}], ctorParameters: function () { return [{ type: i1.TimelineService }]; }, propDecorators: { events: [{
type: Input
}], modelFields: [{
type: Input
}], orientation: [{
type: Input
}], alterMode: [{
type: Input
}], collapsibleEvents: [{
type: Input
}], navigable: [{
type: Input
}], showDateLabels: [{
type: Input
}], animation: [{
type: Input
}], eventWidth: [{
type: Input
}], eventHeight: [{
type: Input
}], dateFormat: [{
type: Input
}], hostClass: [{
type: HostBinding,
args: ['class.k-timeline']
}], verticalClass: [{
type: HostBinding,
args: ['class.k-timeline-vertical']
}], horizontalClass: [{
type: HostBinding,
args: ['class.k-timeline-horizontal']
}], alternatingClass: [{
type: HostBinding,
args: ['class.k-timeline-alternating']
}], collapsibleClass: [{
type: HostBinding,
args: ['class.k-timeline-collapsible']
}], timelineHorizontal: [{
type: ViewChild,
args: [TimelineHorizontalComponent]
}], timelineVertical: [{
type: ViewChild,
args: [TimelineVerticalComponent]
}], cardHeaderTemplate: [{
type: ContentChildren,
args: [TimelineCardHeaderTemplateDirective, { descendants: false }]
}], cardBodyTemplate: [{
type: ContentChildren,
args: [TimelineCardBodyTemplateDirective, { descendants: false }]
}], cardActionsTemplate: [{
type: ContentChildren,
args: [TimelineCardActionsTemplateDirective, { descendants: false }]
}], onToggle: [{
type: Output
}], onActionClick: [{
type: Output
}], onNavigate: [{
type: Output
}] } });