Initial commit: timeline-elements-ui library
Angular 19 component library for timelines and event tracking: timeline, Gantt chart, event cards, date markers, connectors, and custom event templates. Includes signal-based services, SCSS design tokens with dark mode, and TypeScript type definitions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { Component, ChangeDetectionStrategy, input, output, computed, signal } from '@angular/core';
|
||||
import { TitleCasePipe } from '@angular/common';
|
||||
import { BadgeComponent, IconComponent, ButtonComponent } from '@sda/base-ui';
|
||||
import type { TlChangelogVersion, TlChangeCategory } from '../../types/changelog.types';
|
||||
import type { TlVersionClickEvent, TlChangelogEntryClickEvent } from '../../types/event.types';
|
||||
import { formatDate } from '../../utils/date.utils';
|
||||
|
||||
@Component({
|
||||
selector: 'tl-changelog-version',
|
||||
standalone: true,
|
||||
imports: [BadgeComponent, IconComponent, ButtonComponent, TitleCasePipe],
|
||||
templateUrl: './tl-changelog-version.component.html',
|
||||
styleUrl: './tl-changelog-version.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
host: {
|
||||
'[class.tl-changelog-version--collapsible]': 'collapsible()',
|
||||
'[class.tl-changelog-version--expanded]': 'isExpanded()',
|
||||
},
|
||||
})
|
||||
export class TlChangelogVersionComponent {
|
||||
readonly version = input.required<TlChangelogVersion>();
|
||||
readonly collapsible = input(false);
|
||||
readonly expanded = input(true);
|
||||
readonly showCategoryBadges = input(true);
|
||||
readonly showBreakingBadge = input(true);
|
||||
|
||||
readonly versionClick = output<TlVersionClickEvent>();
|
||||
readonly entryClick = output<TlChangelogEntryClickEvent>();
|
||||
readonly expandToggle = output<boolean>();
|
||||
|
||||
protected readonly isExpanded = signal(true);
|
||||
|
||||
protected readonly formattedDate = computed(() => formatDate(this.version().date));
|
||||
|
||||
protected readonly entriesByCategory = computed(() => {
|
||||
const entries = this.version().entries;
|
||||
const categories: TlChangeCategory[] = ['added', 'changed', 'fixed', 'removed', 'deprecated', 'security'];
|
||||
|
||||
return categories
|
||||
.map(category => ({
|
||||
category,
|
||||
entries: entries.filter(e => e.category === category),
|
||||
}))
|
||||
.filter(group => group.entries.length > 0);
|
||||
});
|
||||
|
||||
protected readonly categoryColor = computed(() => {
|
||||
return (category: TlChangeCategory): string => {
|
||||
return `var(--tl-change-${category})`;
|
||||
};
|
||||
});
|
||||
|
||||
protected readonly categoryIcon = computed(() => {
|
||||
return (category: TlChangeCategory): string => {
|
||||
switch (category) {
|
||||
case 'added': return 'plus';
|
||||
case 'changed': return 'edit';
|
||||
case 'fixed': return 'check';
|
||||
case 'removed': return 'minus';
|
||||
case 'deprecated': return 'alert-triangle';
|
||||
case 'security': return 'shield';
|
||||
default: return 'circle';
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
protected onVersionClick(): void {
|
||||
this.versionClick.emit({ version: this.version() });
|
||||
if (this.collapsible()) {
|
||||
this.toggleExpand();
|
||||
}
|
||||
}
|
||||
|
||||
protected toggleExpand(): void {
|
||||
this.isExpanded.update(v => !v);
|
||||
this.expandToggle.emit(this.isExpanded());
|
||||
}
|
||||
|
||||
protected onEntryClick(entry: any): void {
|
||||
this.entryClick.emit({ entry, version: this.version() });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user