@progress/kendo-angular-layout
Version:
Kendo UI for Angular Layout Package - a collection of components to create professional application layoyts
773 lines (772 loc) • 36 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 { ChangeDetectorRef, Component, ElementRef, Input, NgZone, QueryList, Renderer2, ViewChild, ViewChildren, } from '@angular/core';
import { caretAltLeftIcon, caretAltRightIcon } from '@progress/kendo-svg-icons';
import { Subscription } from 'rxjs';
import { TimelineCardComponent } from './timeline-card.component';
import { Keys, ResizeSensorComponent, guid, isChanged, isDocumentAvailable, isPresent } from '@progress/kendo-angular-common';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { TimelineService } from './timeline.service';
import { LocalizationService } from '@progress/kendo-angular-l10n';
import { TimelineCardBodyTemplateDirective } from './templates/timeline-card-body.directive';
import { TimelineCardHeaderTemplateDirective } from './templates/timeline-card-header.directive';
import { TimelineCardActionsTemplateDirective } from './templates/timeline-card-actions.directive';
import { DatePipe } from '@progress/kendo-angular-intl';
import { NgFor, NgIf, NgStyle } from '@angular/common';
import { ButtonComponent } from '@progress/kendo-angular-buttons';
import * as i0 from "@angular/core";
import * as i1 from "./timeline.service";
import * as i2 from "@progress/kendo-angular-l10n";
const DEFAULT_TAB_WIDTH = 200;
const SPACE_BETWEEN_TABS = 25;
const TRANSITION_EVENTS_COUNT = 3;
/**
* @hidden
*/
export class TimelineHorizontalComponent {
cdr;
_zone;
renderer;
timelineService;
localization;
events = [];
alterMode;
collapsibleEvents;
navigable;
showDateLabels;
animationDuration;
eventHeight;
dateFormat;
headerTemplate;
bodyTemplate;
actionsTemplate;
cardElementRefs;
circleElementRefs;
flagElementRefs;
trackElementRef;
scrollableTrackElementRef;
cardComponents;
get selectedEvent() {
return this._selectedEvent;
}
set selectedEvent(value) {
if (this._selectedEvent === value) {
return;
}
const newSelectedIndex = this.events.findIndex(event => event === value);
if (newSelectedIndex === -1 && value !== null) {
return;
}
this._selectedEvent = value;
this.selectedEventIndex = newSelectedIndex;
this.calloutStyle = this.calloutOffset;
}
trackWrapWidth;
scrollableTrackWidth;
cardWidth;
svgLeftIcon = caretAltLeftIcon;
svgRightIcon = caretAltRightIcon;
calloutStyle;
animationState = 'center';
translateValue = 0;
eventsInInterval = [0, 1, 2];
selectedCardIndex = 0;
selectedEventIndex;
tabFlex;
tabWidth = DEFAULT_TAB_WIDTH;
visibleTabsCount;
firstCircleInView = 0;
visibleEvents = [];
trackItems = [];
previousTitle = 'previous';
nextTitle = 'next';
_selectedEvent;
subscriptions = new Subscription();
constructor(cdr, _zone, renderer, timelineService, localization) {
this.cdr = cdr;
this._zone = _zone;
this.renderer = renderer;
this.timelineService = timelineService;
this.localization = localization;
}
ngOnInit() {
this.l10nChange();
this.subscriptions.add(this.localization.changes.subscribe(this.l10nChange.bind(this)));
if (this.events.length > 0) {
this.selectedEvent = this.events[0];
}
this.events.forEach(event => {
if (event.flag) {
this.trackItems.push({ isFlag: event.flag });
}
this.trackItems.push(event);
});
}
ngAfterViewInit() {
if (!isDocumentAvailable()) {
return;
}
this.subscriptions.add(this.renderer.listen(this.trackElementRef.nativeElement, 'keydown', this.onKeyDown.bind(this)));
this.trackWrapWidth = this.trackElementRef.nativeElement.getBoundingClientRect().width;
this.scrollableTrackWidth = this.scrollableTrackElementRef.nativeElement.getBoundingClientRect().width;
this._zone.runOutsideAngular(() => {
this.onCirclesChange();
this.subscriptions.add(this.circleElementRefs.changes.subscribe(this.onCirclesChange.bind(this)));
this.subscriptions.add(this.cardElementRefs.changes.subscribe(this.onCardsChange.bind(this)));
});
if (this.events.length === 0) {
return;
}
this.onCardsChange();
if (this.cardComponents.get(this.selectedCardIndex)) {
this.cardComponents.get(this.selectedCardIndex).calloutStyle = this.calloutOffset;
this.focusTrackItem(0);
}
}
ngOnChanges(changes) {
if (isChanged('events', changes)) {
if (!this.events || this.events.length === 0) {
this.selectedEvent = null;
this.trackItems = [];
this.visibleEvents = [];
}
else {
this.trackItems = [];
this.events.forEach(event => {
if (event.flag) {
this.trackItems.push({ isFlag: event.flag });
}
this.trackItems.push(event);
});
this.visibleEvents = this.trackItems
.slice(this.firstCircleInView, this.firstCircleInView + this.visibleTabsCount)
.filter(event => !event.isFlag);
this.selectedEvent = this.events[0];
this.cdr.detectChanges();
this.calloutStyle = this.calloutOffset;
this.focusTrackItem(0);
}
}
}
ngOnDestroy() {
this.subscriptions.unsubscribe();
}
onResize() {
if (!isDocumentAvailable()) {
return;
}
if (this.trackWrapWidth === this.trackElementRef.nativeElement.getBoundingClientRect().width) {
return;
}
this.cardWidth = this.cardComponents.get(this.selectedCardIndex).element.nativeElement.offsetWidth;
this.transformCards();
this.trackWrapWidth = this.trackElementRef.nativeElement.getBoundingClientRect().width;
this.scrollableTrackWidth = this.scrollableTrackElementRef.nativeElement.getBoundingClientRect().width;
this.changeTabsCount();
this._zone.run(() => {
this.cardComponents.get(this.selectedCardIndex).calloutStyle = this.calloutOffset;
});
}
onTransitionEnd() {
this.cardElementRefs?.forEach(card => this.renderer.removeStyle(card.nativeElement, 'transition-duration'));
this.cardComponents.get(this.selectedCardIndex).event = this.selectedEvent;
this.calloutStyle = this.calloutOffset;
}
onTrackTransitionEnd() {
this.calloutStyle = this.calloutOffset;
}
onSlideDone() {
this.calloutStyle = this.calloutOffset;
}
previous() {
if (this.firstCircleInView === 0) {
return;
}
this.updateInterval(false);
}
previousClick() {
this.previous();
this.timelineService.onNavigate('previous');
}
next() {
if (!this.visibleTabsCount || this.firstCircleInView + this.visibleTabsCount > this.trackItems.length) {
return;
}
this.updateInterval(true);
}
nextClick() {
this.next();
this.timelineService.onNavigate('next');
}
open(index) {
if (index < 0 || index >= this.events.length) {
return;
}
if (this.visibleEvents.findIndex(event => event === this.events[index]) === -1) {
// determine the start and end of the interval that the event belongs to, regardless of its position in the interval
const trackItemIndex = this.trackItems.findIndex(event => event === this.events[index]);
const start = Math.floor(trackItemIndex / this.visibleTabsCount) * this.visibleTabsCount;
this.navigateToInterval(start, index);
}
this.selectedEvent = this.events[index];
this.selectedCardIndex = this.getOtherSelectedCardIndex(index > this.selectedEventIndex);
this.calloutStyle = this.calloutOffset;
this.focusTrackItem(this.selectedEventIndex);
this.animateCards();
}
navigateToEvent(index) {
const eventIndex = this.events.findIndex(event => event === this.trackItems[index]);
if (this.selectedEventIndex === eventIndex) {
return;
}
this.selectedEvent = this.events[eventIndex];
this.selectedCardIndex = this.getOtherSelectedCardIndex(index > eventIndex);
this.calloutStyle = this.calloutOffset;
this.animateCards();
}
getOtherSelectedCardIndex(forward) {
// change the selected card which changes all cards' transform styles
if (forward) {
return this.selectedCardIndex === 0 ? TRANSITION_EVENTS_COUNT - 1 : this.selectedCardIndex - 1;
}
return this.selectedCardIndex === TRANSITION_EVENTS_COUNT - 1 ? 0 : this.selectedCardIndex + 1;
}
tabStyle() {
if (!this.tabFlex) {
return {};
}
return { 'flex': `1 0 ${this.tabFlex}%` };
}
getTransformation(width, position) {
if (position === this.selectedCardIndex - 1 || position === this.selectedCardIndex + 2) {
return `translate3d(${-width}px, 0, 0)`;
}
if (position === this.selectedCardIndex + 1 || position === this.selectedCardIndex - 2) {
return `translate3d(${width}px, 0, 0)`;
}
return `translate3d(0, 0, 0)`;
}
getState(position) {
if (position === this.selectedCardIndex) {
return 'center';
}
if (position === this.selectedCardIndex - 1 || position === this.selectedCardIndex + 2) {
return 'left';
}
return 'right';
}
get calloutOffset() {
if (!isDocumentAvailable() || (!this.circleElementRefs?.first || !this.trackElementRef || !isPresent(this.selectedEventIndex))) {
return {};
}
const circleCenter = this.circleElementRefs.get(this.selectedEventIndex).nativeElement.getBoundingClientRect().left +
this.circleElementRefs.get(this.selectedEventIndex).nativeElement.offsetWidth / 2;
const trackOffset = this.trackElementRef.nativeElement.getBoundingClientRect().left;
return { left: `${circleCenter - trackOffset}px` };
}
get isFirstRange() {
return this.firstCircleInView === 0;
}
get isLastRange() {
if (!this.circleElementRefs?.first && !this.flagElementRefs?.first) {
return false;
}
return this.trackItems.length === 0 ||
this.firstCircleInView + this.visibleTabsCount >= this.trackItems.length;
}
onCardsChange() {
if (this.cardElementRefs?.get(this.selectedCardIndex)) {
this.cardWidth = this.cardElementRefs.get(this.selectedCardIndex).nativeElement.offsetWidth;
this.transformCards();
}
}
onCirclesChange() {
if (!this.circleElementRefs?.first) {
return;
}
this.circleElementRefs
.map(element => element.nativeElement)
.forEach((element, index) => {
this.subscriptions.add(this.renderer.listen(element, 'click', () => {
this.focusTrackItem(index);
}));
});
const width = this.circleElementRefs.first.nativeElement.getBoundingClientRect().width;
if (width > DEFAULT_TAB_WIDTH) {
this.tabWidth = this.circleElementRefs.first.nativeElement.getBoundingClientRect().width + SPACE_BETWEEN_TABS;
}
this.changeTabsCount();
this.visibleEvents = this.trackItems
.slice(this.firstCircleInView, this.firstCircleInView + this.visibleTabsCount)
.filter(event => !event.isFlag);
}
onKeyDown(event) {
if (!this.navigable) {
return;
}
event.preventDefault();
if (event.keyCode === Keys.Home) {
this.onHomeKey();
}
else if (event.keyCode === Keys.End) {
this.onEndKey();
}
else if (event.keyCode === Keys.ArrowRight) {
this.onArrowRightKey();
}
else if (event.keyCode === Keys.ArrowLeft) {
this.onArrowLeftKey();
}
}
focusTrackItem(index) {
if (!isDocumentAvailable()) {
return;
}
if (!this.circleElementRefs || index < 0 || index >= this.circleElementRefs.length) {
return;
}
const selectedTrackItem = this.circleElementRefs
.find(element => element.nativeElement.hasAttribute('aria-selected'));
if (selectedTrackItem) {
this.removeTrackItemAttributes(selectedTrackItem);
this.removeCardsAttributes();
}
const newTrackItem = this.circleElementRefs.get(index).nativeElement;
this.setTrackItemAttributes(newTrackItem, index);
}
setTrackItemAttributes(element, index) {
if (!isDocumentAvailable()) {
return;
}
const innerCard = this.cardComponents.get(this.selectedCardIndex).element.nativeElement.querySelector('.k-card');
const selectedCircle = this.circleElementRefs.get(index).nativeElement;
this.renderer.addClass(element, 'k-focus');
this.renderer.setAttribute(element, 'aria-selected', 'true');
this.assignAriaLabel(innerCard, selectedCircle);
this.assignAriaDescribedBy(innerCard, selectedCircle);
}
removeTrackItemAttributes(element) {
this.renderer.removeClass(element.nativeElement, 'k-focus');
this.renderer.removeAttribute(element.nativeElement, 'aria-selected');
this.renderer.removeAttribute(element.nativeElement, 'id');
this.renderer.removeAttribute(element.nativeElement, 'aria-describedby');
}
removeCardsAttributes() {
this.cardElementRefs.forEach(card => {
this.renderer.removeAttribute(card.nativeElement.querySelector('.k-card'), 'id');
this.renderer.removeAttribute(card.nativeElement.querySelector('.k-card'), 'aria-label');
});
}
assignAriaLabel(cardElement, dateElement) {
const dateLabelId = `k-${guid()}`;
this.renderer.setAttribute(dateElement, 'id', dateLabelId);
this.renderer.setAttribute(cardElement, 'aria-label', dateLabelId);
}
assignAriaDescribedBy(cardElement, dateElement) {
const cardId = `k-${guid()}`;
this.renderer.setAttribute(cardElement, 'id', cardId);
this.renderer.setAttribute(dateElement, 'aria-describedby', cardId);
}
updateInterval(forward) {
let start = forward ? this.firstCircleInView + this.visibleTabsCount : this.firstCircleInView - this.visibleTabsCount;
if (start < 0 || start >= this.trackItems.length) {
start = 0;
}
this.navigateToInterval(start, 0, forward, !forward);
}
onHomeKey() {
if (this.selectedEvent === this.events[0]) {
return;
}
this.navigateToFirstInterval();
}
onEndKey() {
if (this.selectedEvent === this.events[this.events.length - 1]) {
return;
}
this.navigateToLastInterval();
}
onArrowRightKey() {
this.navigateToOtherEvent(true);
}
onArrowLeftKey() {
this.navigateToOtherEvent(false);
}
navigateToFirstInterval() {
this.navigateToInterval(0);
}
navigateToLastInterval() {
const start = Math.floor((this.trackItems.length - 1) / this.visibleTabsCount) * this.visibleTabsCount;
this.navigateToInterval(start, this.events.length - 1);
}
navigateToOtherEvent(direction) {
const offset = direction ? 1 : -1;
const newIndex = this.selectedEventIndex + offset;
if (newIndex < 0 || newIndex >= this.events.length) {
return;
}
if (this.visibleEvents.findIndex(event => event === this.events[newIndex]) === -1) {
this.updateInterval(direction);
}
else {
this.selectedEvent = this.events[newIndex];
this.selectedCardIndex = this.getOtherSelectedCardIndex(direction);
this.focusTrackItem(this.selectedEventIndex);
this.animateCards();
this.cdr.markForCheck();
}
}
navigateToInterval(start, selectedIndex = 0, selectFirst = false, selectLast = false) {
const end = start + this.visibleTabsCount < this.trackItems.length ? start + this.visibleTabsCount : undefined;
const forward = this.firstCircleInView < start;
this.firstCircleInView = start;
const interval = Math.floor(start / this.visibleTabsCount);
this.translateValue = interval * -100;
this.animationState = forward ? 'right' : 'left';
this.visibleEvents = this.trackItems.slice(this.firstCircleInView, end).filter(event => !event.isFlag);
if (selectFirst) {
this.selectedEvent = this.visibleEvents[0];
}
else if (selectLast) {
this.selectedEvent = this.visibleEvents[this.visibleEvents.length - 1];
}
else {
this.selectedEvent = this.events[selectedIndex];
}
this.selectedCardIndex = this.getOtherSelectedCardIndex(forward);
this.cdr.detectChanges();
this.focusTrackItem(this.selectedEventIndex);
this.animateCards();
this.calloutStyle = this.calloutOffset;
this.cdr.markForCheck();
}
animateCards() {
if (this.animationDuration) {
this.cardComponents.get(this.selectedCardIndex).event = null;
}
this.cardElementRefs.forEach((card, index) => {
this.renderer.setStyle(card.nativeElement, 'transform', this.getTransformation(this.cardWidth, index));
this.renderer.setStyle(card.nativeElement, 'transition-duration', `${this.animationDuration || 0}ms`);
});
}
transformCards() {
this.cardElementRefs.forEach((card, index) => this.renderer.setStyle(card.nativeElement, 'transform', this.getTransformation(this.cardWidth, index)));
}
changeTabsCount() {
this.visibleTabsCount = Math.round(this.scrollableTrackWidth / this.tabWidth);
if (this.tabFlex !== 100 / this.visibleTabsCount) {
this.tabFlex = 100 / this.visibleTabsCount;
this.circleElementRefs.forEach(item => this.renderer.setStyle(item.nativeElement, 'flex', `1 0 ${this.tabFlex}%`));
this.flagElementRefs.forEach(item => this.renderer.setStyle(item.nativeElement, 'flex', `1 0 ${this.tabFlex}%`));
this.cdr.detectChanges();
this.visibleEvents = this.trackItems
.slice(this.firstCircleInView, this.firstCircleInView + this.visibleTabsCount)
.filter(event => !event.isFlag);
if (!this.visibleEvents.find(event => event === this.selectedEvent)) {
const trackItemIndex = this.trackItems.findIndex(event => event === this.selectedEvent);
this.navigateToInterval(trackItemIndex, this.selectedEventIndex);
}
}
}
l10nChange() {
if (this.localization.get('previous')) {
this.previousTitle = this.localization.get('previous');
}
if (this.localization.get('next')) {
this.nextTitle = this.localization.get('next');
}
this.cdr.markForCheck();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimelineHorizontalComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i1.TimelineService }, { token: i2.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TimelineHorizontalComponent, isStandalone: true, selector: "kendo-timeline-horizontal", inputs: { events: "events", alterMode: "alterMode", collapsibleEvents: "collapsibleEvents", navigable: "navigable", showDateLabels: "showDateLabels", animationDuration: "animationDuration", eventHeight: "eventHeight", dateFormat: "dateFormat", headerTemplate: "headerTemplate", bodyTemplate: "bodyTemplate", actionsTemplate: "actionsTemplate" }, providers: [], viewQueries: [{ propertyName: "trackElementRef", first: true, predicate: ["track"], descendants: true }, { propertyName: "scrollableTrackElementRef", first: true, predicate: ["scrollableTrack"], descendants: true }, { propertyName: "cardElementRefs", predicate: ["card"], descendants: true, read: ElementRef }, { propertyName: "circleElementRefs", predicate: ["trackCircle"], descendants: true }, { propertyName: "flagElementRefs", predicate: ["trackFlag"], descendants: true }, { propertyName: "cardComponents", predicate: TimelineCardComponent, descendants: true }], exportAs: ["kendoTimelineHorizontal"], usesOnChanges: true, ngImport: i0, template: `
<div class="k-timeline-track-wrap" #track>
<button
kendoButton
[svgIcon]="svgLeftIcon"
icon="caret-alt-left"
class="k-timeline-arrow k-timeline-arrow-left"
rounded="full"
[title]="previousTitle"
(click)="previousClick()"
[disabled]="isFirstRange"
tabindex="-1"
type="button"
></button>
<button
kendoButton
[svgIcon]="svgRightIcon"
icon="caret-alt-right"
class="k-timeline-arrow k-timeline-arrow-right"
rounded="full"
[title]="nextTitle"
(click)="nextClick()"
[disabled]="isLastRange"
tabindex="-1"
type="button"
></button>
<div class="k-timeline-track">
<ul class="k-timeline-scrollable-wrap"
#scrollableTrack
[attr.role]="'tablist'"
[attr.tabindex]="'0'"
[ ]="{value: animationState, params: {transformValue: this.translateValue}}"
( .done)="onSlideDone()"
(transitionend)="onTrackTransitionEnd()"
>
<ng-container *ngFor="let event of trackItems; let index = index">
<li
#trackFlag
*ngIf="event.isFlag"
class="k-timeline-flag-wrap k-timeline-track-item"
[attr.role]="'none'"
[attr.aria-hidden]="true"
[ngStyle]="tabStyle()"
>
<span class="k-timeline-flag">{{ event.isFlag }}</span>
</li>
<li
*ngIf="!event.isFlag"
#trackCircle
class="k-timeline-track-item"
[attr.role]="'tab'"
(click)="navigateToEvent(index)"
[ngStyle]="tabStyle()"
>
<div class="k-timeline-date-wrap">
<span *ngIf="showDateLabels" class="k-timeline-date">
{{ event.date | kendoDate: dateFormat }}
</span>
</div>
<span class="k-timeline-circle"></span>
</li>
</ng-container>
</ul>
</div>
</div>
<div class="k-timeline-events-list">
<ul
*ngIf="selectedEvent"
class="k-timeline-scrollable-wrap"
[ ]="{value: animationState, params: {animationDuration: this.animationDuration || 0}}"
( .done)="onSlideDone()"
[ngStyle]="{'transform-origin': 'left top'}"
>
<li *ngFor="let event of eventsInInterval; let index = index"
#card
class="k-timeline-event"
(transitionend)="onTransitionEnd()"
>
<kendo-timeline-card
[event]="selectedCardIndex === index ? selectedEvent : null"
[expanded]="true"
[collapsible]="collapsibleEvents"
[calloutStyle]="selectedCardIndex === index ? calloutStyle : {}"
[ngStyle]="{visibility: selectedCardIndex === index ? 'visible' : 'hidden' }"
[tabIndex]="selectedCardIndex === index ? '0' : '-1'"
[navigable]="navigable"
[index]="selectedEventIndex"
[headerTemplate]="headerTemplate"
[bodyTemplate]="bodyTemplate"
[actionsTemplate]="actionsTemplate"
[eventHeight]="eventHeight"
orientation="horizontal"
>
</kendo-timeline-card>
</li>
</ul>
<kendo-resize-sensor (resize)="onResize()" [rateLimit]="10"></kendo-resize-sensor>
</div>
`, isInline: true, dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: TimelineCardComponent, selector: "kendo-timeline-card", inputs: ["event", "expanded", "collapsible", "reversed", "orientation", "navigable", "tabIndex", "animationDuration", "index", "eventWidth", "eventHeight", "headerTemplate", "bodyTemplate", "actionsTemplate", "calloutStyle"], exportAs: ["kendoTimelineCard"] }, { kind: "pipe", type: DatePipe, name: "kendoDate" }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }], animations: [
trigger('trackSlide', [
state('left', style({
transform: `translateX({{transformValue}}%)`,
}), { params: { transformValue: '0' } }),
state('right', style({
transform: `translateX({{transformValue}}%)`,
}), { params: { transformValue: '0' } }),
state('center', style({
transform: `translateX(0)`,
}))
]),
trigger('eventsSlide', [
transition('* => right', [
animate('{{animationDuration}}ms', style({ transform: `translateX(-100%)` }))
], { params: { animationDuration: '400' } }),
transition('* => left', [
animate('{{animationDuration}}ms', style({ transform: `translateX(100%)` }))
], { params: { animationDuration: '400' } })
])
] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TimelineHorizontalComponent, decorators: [{
type: Component,
args: [{
animations: [
trigger('trackSlide', [
state('left', style({
transform: `translateX({{transformValue}}%)`,
}), { params: { transformValue: '0' } }),
state('right', style({
transform: `translateX({{transformValue}}%)`,
}), { params: { transformValue: '0' } }),
state('center', style({
transform: `translateX(0)`,
}))
]),
trigger('eventsSlide', [
transition('* => right', [
animate('{{animationDuration}}ms', style({ transform: `translateX(-100%)` }))
], { params: { animationDuration: '400' } }),
transition('* => left', [
animate('{{animationDuration}}ms', style({ transform: `translateX(100%)` }))
], { params: { animationDuration: '400' } })
])
],
providers: [],
exportAs: 'kendoTimelineHorizontal',
selector: 'kendo-timeline-horizontal',
template: `
<div class="k-timeline-track-wrap" #track>
<button
kendoButton
[svgIcon]="svgLeftIcon"
icon="caret-alt-left"
class="k-timeline-arrow k-timeline-arrow-left"
rounded="full"
[title]="previousTitle"
(click)="previousClick()"
[disabled]="isFirstRange"
tabindex="-1"
type="button"
></button>
<button
kendoButton
[svgIcon]="svgRightIcon"
icon="caret-alt-right"
class="k-timeline-arrow k-timeline-arrow-right"
rounded="full"
[title]="nextTitle"
(click)="nextClick()"
[disabled]="isLastRange"
tabindex="-1"
type="button"
></button>
<div class="k-timeline-track">
<ul class="k-timeline-scrollable-wrap"
#scrollableTrack
[attr.role]="'tablist'"
[attr.tabindex]="'0'"
[ ]="{value: animationState, params: {transformValue: this.translateValue}}"
( .done)="onSlideDone()"
(transitionend)="onTrackTransitionEnd()"
>
<ng-container *ngFor="let event of trackItems; let index = index">
<li
#trackFlag
*ngIf="event.isFlag"
class="k-timeline-flag-wrap k-timeline-track-item"
[attr.role]="'none'"
[attr.aria-hidden]="true"
[ngStyle]="tabStyle()"
>
<span class="k-timeline-flag">{{ event.isFlag }}</span>
</li>
<li
*ngIf="!event.isFlag"
#trackCircle
class="k-timeline-track-item"
[attr.role]="'tab'"
(click)="navigateToEvent(index)"
[ngStyle]="tabStyle()"
>
<div class="k-timeline-date-wrap">
<span *ngIf="showDateLabels" class="k-timeline-date">
{{ event.date | kendoDate: dateFormat }}
</span>
</div>
<span class="k-timeline-circle"></span>
</li>
</ng-container>
</ul>
</div>
</div>
<div class="k-timeline-events-list">
<ul
*ngIf="selectedEvent"
class="k-timeline-scrollable-wrap"
[ ]="{value: animationState, params: {animationDuration: this.animationDuration || 0}}"
( .done)="onSlideDone()"
[ngStyle]="{'transform-origin': 'left top'}"
>
<li *ngFor="let event of eventsInInterval; let index = index"
#card
class="k-timeline-event"
(transitionend)="onTransitionEnd()"
>
<kendo-timeline-card
[event]="selectedCardIndex === index ? selectedEvent : null"
[expanded]="true"
[collapsible]="collapsibleEvents"
[calloutStyle]="selectedCardIndex === index ? calloutStyle : {}"
[ngStyle]="{visibility: selectedCardIndex === index ? 'visible' : 'hidden' }"
[tabIndex]="selectedCardIndex === index ? '0' : '-1'"
[navigable]="navigable"
[index]="selectedEventIndex"
[headerTemplate]="headerTemplate"
[bodyTemplate]="bodyTemplate"
[actionsTemplate]="actionsTemplate"
[eventHeight]="eventHeight"
orientation="horizontal"
>
</kendo-timeline-card>
</li>
</ul>
<kendo-resize-sensor (resize)="onResize()" [rateLimit]="10"></kendo-resize-sensor>
</div>
`,
standalone: true,
imports: [ButtonComponent, NgFor, NgIf, NgStyle, TimelineCardComponent, DatePipe, ResizeSensorComponent]
}]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i1.TimelineService }, { type: i2.LocalizationService }]; }, propDecorators: { events: [{
type: Input
}], alterMode: [{
type: Input
}], collapsibleEvents: [{
type: Input
}], navigable: [{
type: Input
}], showDateLabels: [{
type: Input
}], animationDuration: [{
type: Input
}], eventHeight: [{
type: Input
}], dateFormat: [{
type: Input
}], headerTemplate: [{
type: Input
}], bodyTemplate: [{
type: Input
}], actionsTemplate: [{
type: Input
}], cardElementRefs: [{
type: ViewChildren,
args: ['card', { read: ElementRef }]
}], circleElementRefs: [{
type: ViewChildren,
args: ['trackCircle']
}], flagElementRefs: [{
type: ViewChildren,
args: ['trackFlag']
}], trackElementRef: [{
type: ViewChild,
args: ['track']
}], scrollableTrackElementRef: [{
type: ViewChild,
args: ['scrollableTrack']
}], cardComponents: [{
type: ViewChildren,
args: [TimelineCardComponent]
}] } });