/** * @fileoverview MJ Timeline Component - A flexible, responsive timeline for Angular. * * This component displays chronological data in a timeline format with support for: * - Multiple data sources (MemberJunction entities or plain objects) * - Virtual scrolling for large datasets * - Collapsible time segments * - Rich event system with BeforeX/AfterX pattern * - Full keyboard navigation and accessibility * - Responsive design for all screen sizes * * @module @memberjunction/ng-timeline */ import { EventEmitter, OnInit, OnDestroy, AfterViewInit, ElementRef, TemplateRef, ChangeDetectorRef, NgZone } from '@angular/core'; import { TimelineOrientation, TimelineLayout, TimelineSortOrder, TimeSegmentGrouping, TimelineCardConfig, VirtualScrollConfig, VirtualScrollState, MJTimelineEvent, TimelineSegment, TimelineAction, TimelineDisplayField } from '../types'; import { TimelineGroup } from '../timeline-group'; import { BeforeEventClickArgs, AfterEventClickArgs, BeforeEventExpandArgs, AfterEventExpandArgs, BeforeEventCollapseArgs, AfterEventCollapseArgs, BeforeEventHoverArgs, AfterEventHoverArgs, BeforeActionClickArgs, AfterActionClickArgs, BeforeSegmentExpandArgs, AfterSegmentExpandArgs, BeforeSegmentCollapseArgs, AfterSegmentCollapseArgs, BeforeLoadArgs, AfterLoadArgs } from '../events'; import * as i0 from "@angular/core"; /** * MJ Timeline Component - Displays chronological data in a rich, interactive timeline. * * The timeline component supports multiple data groups, virtual scrolling for large * datasets, collapsible time segments, and a comprehensive event system that allows * container components to intercept and modify behavior. * * @example Basic usage * ```html * * ``` * * @example Full configuration * ```html * * * *
No events found
*
* *
* ``` */ export declare class TimelineComponent implements OnInit, OnDestroy, AfterViewInit { private cdr; private elementRef; private ngZone; /** * Array of timeline groups to display. * Each group defines a data source and display configuration. */ get groups(): TimelineGroup[]; set groups(value: TimelineGroup[]); private _groups; /** True once ngAfterViewInit has run — the view is ready to render refreshed events. */ private _viewReady; /** * Check if timeline groups have meaningfully changed */ private didGroupsChange; /** * Controls whether data loading is allowed. * Set to false to defer loading until ready. * @default true */ get allowLoad(): boolean; set allowLoad(value: boolean); private _allowLoad; /** * Timeline orientation. * - `vertical`: Events displayed top-to-bottom * - `horizontal`: Events displayed left-to-right * @default 'vertical' */ get orientation(): TimelineOrientation; set orientation(value: TimelineOrientation); private _orientation; /** * Layout mode for vertical timeline. * - `single`: All cards on one side * - `alternating`: Cards alternate sides * @default 'single' */ get layout(): TimelineLayout; set layout(value: TimelineLayout); private _layout; /** * Sort order for events. * - `desc`: Newest first * - `asc`: Oldest first * @default 'desc' */ get sortOrder(): TimelineSortOrder; set sortOrder(value: TimelineSortOrder); private _sortOrder; /** * How to group events into time segments. * @default 'month' */ get segmentGrouping(): TimeSegmentGrouping; set segmentGrouping(value: TimeSegmentGrouping); private _segmentGrouping; /** * Default card configuration applied to all groups. * Individual groups can override these settings. */ defaultCardConfig: TimelineCardConfig; /** * Virtual scrolling configuration. */ virtualScroll: VirtualScrollConfig; /** * Whether time segments can be collapsed. * @default true */ segmentsCollapsible: boolean; /** * Whether segments start expanded. * @default true */ segmentsDefaultExpanded: boolean; /** * Message shown when no events exist. * @default 'No events to display' */ emptyMessage: string; /** * Icon shown with empty message. * @default 'fa-regular fa-calendar-xmark' */ emptyIcon: string; /** * Message shown while loading. * @default 'Loading timeline...' */ loadingMessage: string; /** * ARIA label for the timeline container. * @default 'Timeline' */ ariaLabel: string; /** * Enable keyboard navigation. * @default true */ enableKeyboardNavigation: boolean; /** * ID of the currently selected event. * When set, the corresponding event will be highlighted with the focused style. */ get selectedEventId(): string | null; set selectedEventId(value: string | null); private _selectedEventId; /** Emitted before an event card is clicked. Set `cancel = true` to prevent. */ beforeEventClick: EventEmitter>; /** Emitted before an event card expands. Set `cancel = true` to prevent. */ beforeEventExpand: EventEmitter>; /** Emitted before an event card collapses. Set `cancel = true` to prevent. */ beforeEventCollapse: EventEmitter>; /** Emitted before hover state changes. Set `cancel = true` to prevent. */ beforeEventHover: EventEmitter>; /** Emitted before an action button is clicked. Set `cancel = true` to prevent. */ beforeActionClick: EventEmitter>; /** Emitted before a time segment expands. Set `cancel = true` to prevent. */ beforeSegmentExpand: EventEmitter; /** Emitted before a time segment collapses. Set `cancel = true` to prevent. */ beforeSegmentCollapse: EventEmitter; /** Emitted before data loading begins. Set `cancel = true` to prevent. */ beforeLoad: EventEmitter; /** Emitted after an event card is clicked. */ afterEventClick: EventEmitter>; /** Emitted after an event card expands. */ afterEventExpand: EventEmitter>; /** Emitted after an event card collapses. */ afterEventCollapse: EventEmitter>; /** Emitted after hover state changes. */ afterEventHover: EventEmitter>; /** Emitted after an action button is clicked. */ afterActionClick: EventEmitter>; /** Emitted after a time segment expands. */ afterSegmentExpand: EventEmitter; /** Emitted after a time segment collapses. */ afterSegmentCollapse: EventEmitter; /** Emitted after data loading completes. */ afterLoad: EventEmitter; /** Custom template for entire card. Context: { event, group } */ cardTemplate?: TemplateRef<{ event: MJTimelineEvent; group: TimelineGroup; }>; /** Custom template for card header. Context: { event } */ headerTemplate?: TemplateRef<{ event: MJTimelineEvent; }>; /** Custom template for card body. Context: { event } */ bodyTemplate?: TemplateRef<{ event: MJTimelineEvent; }>; /** Custom template for card actions. Context: { event, actions } */ actionsTemplate?: TemplateRef<{ event: MJTimelineEvent; actions: TimelineAction[]; }>; /** Custom template for segment header. Context: { segment } */ segmentHeaderTemplate?: TemplateRef<{ segment: TimelineSegment; }>; /** Custom template for empty state. */ emptyTemplate?: TemplateRef; /** Custom template for loading state. */ loadingTemplate?: TemplateRef; scrollContainer?: ElementRef; /** Current time segments with events. */ segments: TimelineSegment[]; /** All flattened events (for non-segmented display). */ allEvents: MJTimelineEvent[]; /** Virtual scroll state. */ scrollState: VirtualScrollState; /** Whether initial load is complete. */ isInitialized: boolean; /** Whether currently loading data. */ isLoading: boolean; /** Index of currently focused event (for keyboard navigation). */ focusedEventIndex: number; private _initialized; private _hasLoaded; private _destroy$; private _scroll$; private _intersectionObserver?; constructor(cdr: ChangeDetectorRef, elementRef: ElementRef, ngZone: NgZone); ngOnInit(): void; ngAfterViewInit(): void; ngOnDestroy(): void; /** * Refreshes all data from the configured groups. * Clears existing data and reloads from sources. */ refresh(force?: boolean): Promise; /** * Loads more events (for virtual scrolling). */ loadMore(): Promise; /** * Expands all event cards. */ expandAllEvents(): void; /** * Collapses all event cards. */ collapseAllEvents(): void; /** * Expands all time segments. */ expandAllSegments(): void; /** * Collapses all time segments. */ collapseAllSegments(): void; /** * Expands a specific event by ID. */ expandEvent(eventId: string): void; /** * Collapses a specific event by ID. */ collapseEvent(eventId: string): void; /** * Scrolls to a specific event. */ scrollToEvent(eventId: string, behavior?: ScrollBehavior): void; /** * Scrolls to a specific date. */ scrollToDate(date: Date, behavior?: ScrollBehavior): void; /** * Gets an event by ID. */ getEvent(eventId: string): MJTimelineEvent | undefined; /** * Gets all events (flattened). */ getAllEvents(): MJTimelineEvent[]; /** * Handles click on an event card. */ onEventClick(event: MJTimelineEvent, index: number, domEvent: Event): void; /** * Handles expand/collapse toggle on an event. */ onToggleExpand(event: MJTimelineEvent, index: number, domEvent: Event): void; /** * Handles mouse enter on an event card. */ onEventMouseEnter(event: MJTimelineEvent, index: number, domEvent: Event): void; /** * Handles mouse leave on an event card. */ onEventMouseLeave(event: MJTimelineEvent, index: number, domEvent: Event): void; /** * Handles action button click. */ onActionClick(event: MJTimelineEvent, action: TimelineAction, index: number, domEvent: Event): void; /** * Handles segment header click. */ onSegmentClick(segment: TimelineSegment): void; /** * Handles scroll events for virtual scrolling. */ onScroll(event: Event): void; /** * Handles keyboard navigation. */ onKeyDown(event: KeyboardEvent): void; /** * Gets the effective card config for an event. */ getEffectiveCardConfig(event: MJTimelineEvent): TimelineCardConfig; /** * Gets the color for a group/event. */ getColor(event: MJTimelineEvent): string; /** * Gets the icon for a group/event. */ getIcon(event: MJTimelineEvent): string; /** * Gets the actions for an event. */ getActions(event: MJTimelineEvent): TimelineAction[]; /** * Formats a date for display. */ formatDate(date: Date, format?: string): string; /** * Gets the value of a display field from an event. */ getFieldValue(event: MJTimelineEvent, field: TimelineDisplayField): string; /** * Track by function for ngFor. */ trackByEventId(_index: number, event: MJTimelineEvent): string; /** * Track by function for segments. */ trackBySegmentLabel(_index: number, segment: TimelineSegment): string; /** * Gets the global index of an event in the allEvents array. */ getGlobalIndex(event: MJTimelineEvent): number; /** * Checks if an event is currently selected/focused. * An event is selected if either: * - Its ID matches the selectedEventId input * - Its global index matches the focusedEventIndex (keyboard navigation) */ isEventSelected(event: MJTimelineEvent, globalIndex: number): boolean; /** * Loads data from all groups. */ private loadAllGroups; /** * Loads data from a single group. */ private loadGroup; /** * Loads data from MemberJunction entity. */ private loadFromEntity; /** * Loads the next batch for virtual scrolling. */ private loadNextBatch; /** * Creates a timeline event from a source record. */ private createTimelineEvent; /** * Sorts events by date according to sortOrder. */ private sortEvents; /** * Builds time segments from events. */ private buildSegments; /** * Gets segment information for a date. */ private getSegmentInfo; /** * Toggles event expanded state. */ private toggleEventExpanded; /** * Sets event expanded state. */ private setEventExpanded; /** * Expands an event with events. */ private expandEventInternal; /** * Collapses an event with events. */ private collapseEventInternal; /** * Expands a segment. */ private expandSegment; /** * Collapses a segment. */ private collapseSegment; /** * Sets segment expanded state without events. */ private setSegmentExpanded; private focusNextEvent; private focusPreviousEvent; private focusFirstEvent; private focusLastEvent; private activateFocusedEvent; private collapseFocusedEvent; private scrollToFocusedEvent; private setupIntersectionObserver; private onScrollCheck; /** * Maps event config to card config properties. */ private mapEventConfigToCardConfig; /** * Simple date formatter (replaces Angular DatePipe for standalone use). * Uses placeholder tokens to avoid replacement conflicts. */ private formatDateInternal; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵcmp: i0.ɵɵComponentDeclaration, "mj-timeline", never, { "groups": { "alias": "groups"; "required": false; }; "allowLoad": { "alias": "allowLoad"; "required": false; }; "orientation": { "alias": "orientation"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; "sortOrder": { "alias": "sortOrder"; "required": false; }; "segmentGrouping": { "alias": "segmentGrouping"; "required": false; }; "defaultCardConfig": { "alias": "defaultCardConfig"; "required": false; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; }; "segmentsCollapsible": { "alias": "segmentsCollapsible"; "required": false; }; "segmentsDefaultExpanded": { "alias": "segmentsDefaultExpanded"; "required": false; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; }; "emptyIcon": { "alias": "emptyIcon"; "required": false; }; "loadingMessage": { "alias": "loadingMessage"; "required": false; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; }; "enableKeyboardNavigation": { "alias": "enableKeyboardNavigation"; "required": false; }; "selectedEventId": { "alias": "selectedEventId"; "required": false; }; }, { "beforeEventClick": "beforeEventClick"; "beforeEventExpand": "beforeEventExpand"; "beforeEventCollapse": "beforeEventCollapse"; "beforeEventHover": "beforeEventHover"; "beforeActionClick": "beforeActionClick"; "beforeSegmentExpand": "beforeSegmentExpand"; "beforeSegmentCollapse": "beforeSegmentCollapse"; "beforeLoad": "beforeLoad"; "afterEventClick": "afterEventClick"; "afterEventExpand": "afterEventExpand"; "afterEventCollapse": "afterEventCollapse"; "afterEventHover": "afterEventHover"; "afterActionClick": "afterActionClick"; "afterSegmentExpand": "afterSegmentExpand"; "afterSegmentCollapse": "afterSegmentCollapse"; "afterLoad": "afterLoad"; }, ["cardTemplate", "headerTemplate", "bodyTemplate", "actionsTemplate", "segmentHeaderTemplate", "emptyTemplate", "loadingTemplate"], never, false, never>; } //# sourceMappingURL=timeline.component.d.ts.map