@onemrvapublic/design-system 22.0.0-develop.5 → 22.0.0-develop.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -4
- package/assets/i18n/de.json +12 -0
- package/assets/i18n/en.json +12 -0
- package/assets/i18n/fr.json +12 -0
- package/assets/i18n/nl.json +12 -0
- package/fesm2022/onemrvapublic-design-system-layout.mjs +2 -31
- package/fesm2022/onemrvapublic-design-system-layout.mjs.map +1 -1
- package/fesm2022/onemrvapublic-design-system-mat-carousel.mjs +17 -41
- package/fesm2022/onemrvapublic-design-system-mat-carousel.mjs.map +1 -1
- package/fesm2022/onemrvapublic-design-system-mat-file-upload.mjs +2 -47
- package/fesm2022/onemrvapublic-design-system-mat-file-upload.mjs.map +1 -1
- package/fesm2022/onemrvapublic-design-system-mat-stepper.mjs +5 -32
- package/fesm2022/onemrvapublic-design-system-mat-stepper.mjs.map +1 -1
- package/fesm2022/onemrvapublic-design-system-page-error.mjs +2 -3
- package/fesm2022/onemrvapublic-design-system-page-error.mjs.map +1 -1
- package/fesm2022/onemrvapublic-design-system-shared.mjs +1 -1
- package/fesm2022/onemrvapublic-design-system-shared.mjs.map +1 -1
- package/fesm2022/onemrvapublic-design-system-timeline.mjs +563 -0
- package/fesm2022/onemrvapublic-design-system-timeline.mjs.map +1 -0
- package/fesm2022/onemrvapublic-design-system.mjs +1 -1
- package/fesm2022/onemrvapublic-design-system.mjs.map +1 -1
- package/mat-carousel/src/onemrva-mat-carousel.component.scss +18 -0
- package/package.json +5 -1
- package/timeline/src/onemrva-timeline.component.scss +371 -0
- package/types/onemrvapublic-design-system-mat-carousel.d.ts +0 -3
- package/types/onemrvapublic-design-system-page-error.d.ts +0 -1
- package/types/onemrvapublic-design-system-timeline.d.ts +195 -0
- package/types/onemrvapublic-design-system.d.ts +1 -1
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, model, output, computed, signal, inject, LOCALE_ID, effect, ViewEncapsulation, Component, NgModule } from '@angular/core';
|
|
3
|
+
import { TranslatePipe } from '@ngx-translate/core';
|
|
4
|
+
import { MatIcon } from '@angular/material/icon';
|
|
5
|
+
import { MatIconButton } from '@angular/material/button';
|
|
6
|
+
import * as i1 from '@angular/material/button-toggle';
|
|
7
|
+
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
8
|
+
import * as i2 from '@angular/material/form-field';
|
|
9
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
10
|
+
import * as i3 from '@angular/material/select';
|
|
11
|
+
import { MatSelectModule } from '@angular/material/select';
|
|
12
|
+
import { MatDivider } from '@angular/material/divider';
|
|
13
|
+
import * as i4 from '@angular/cdk/overlay';
|
|
14
|
+
import { OverlayModule } from '@angular/cdk/overlay';
|
|
15
|
+
|
|
16
|
+
/** All palette tokens in display order. */
|
|
17
|
+
const TIMELINE_COLORS = [
|
|
18
|
+
'data-1',
|
|
19
|
+
'data-2',
|
|
20
|
+
'data-3',
|
|
21
|
+
'data-4',
|
|
22
|
+
'data-5',
|
|
23
|
+
'data-6',
|
|
24
|
+
'data-7',
|
|
25
|
+
];
|
|
26
|
+
/** Maps each palette token to its hex value. */
|
|
27
|
+
const TIMELINE_PALETTE = {
|
|
28
|
+
'data-1': '#625d9c',
|
|
29
|
+
'data-2': '#7f56a2',
|
|
30
|
+
'data-3': '#9f499e',
|
|
31
|
+
'data-4': '#be358f',
|
|
32
|
+
'data-5': '#d71675',
|
|
33
|
+
'data-6': '#e70054',
|
|
34
|
+
'data-7': '#eb142a',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** Maximum filter options the timeline renders; extras are ignored. */
|
|
38
|
+
const MAX_TIMELINE_FILTERS = 3;
|
|
39
|
+
|
|
40
|
+
const MS_PER_DAY = 1000 * 60 * 60 * 24;
|
|
41
|
+
function limitFilters(filters) {
|
|
42
|
+
return filters.slice(0, MAX_TIMELINE_FILTERS);
|
|
43
|
+
}
|
|
44
|
+
function daysBetween(a, b) {
|
|
45
|
+
return Math.max(1, Math.round((b.getTime() - a.getTime()) / MS_PER_DAY));
|
|
46
|
+
}
|
|
47
|
+
function formatDate(date) {
|
|
48
|
+
const pad = (value) => value.toString().padStart(2, '0');
|
|
49
|
+
return `${pad(date.getDate())}/${pad(date.getMonth() + 1)}/${date.getFullYear()}`;
|
|
50
|
+
}
|
|
51
|
+
function formatPeriodRange(period) {
|
|
52
|
+
return `${formatDate(period.beginDate)} - ${formatDate(period.endDate)}`;
|
|
53
|
+
}
|
|
54
|
+
function monthsWithSize(year) {
|
|
55
|
+
const daysInYear = (new Date(year, 11, 31).getTime() - new Date(year, 0, 1).getTime()) /
|
|
56
|
+
MS_PER_DAY +
|
|
57
|
+
1;
|
|
58
|
+
return Array.from({ length: 12 }, (_, month) => ({
|
|
59
|
+
month: month + 1,
|
|
60
|
+
widthPercent: (new Date(year, month + 1, 0).getDate() / daysInYear) * 100,
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
function fullTimelineRange(periods) {
|
|
64
|
+
if (!periods.length)
|
|
65
|
+
return null;
|
|
66
|
+
const minBegin = Math.min(...periods.map(p => p.beginDate.getTime()));
|
|
67
|
+
const maxEnd = Math.max(...periods.map(p => p.endDate.getTime()));
|
|
68
|
+
return {
|
|
69
|
+
baseBeginYear: new Date(minBegin).getFullYear(),
|
|
70
|
+
baseEndYear: new Date(maxEnd).getFullYear(),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function splitIntoRows(periods) {
|
|
74
|
+
const rows = [];
|
|
75
|
+
const sorted = [...periods].sort((a, b) => a.beginDate.getTime() - b.beginDate.getTime());
|
|
76
|
+
for (const period of sorted) {
|
|
77
|
+
const row = rows.find(r => r[r.length - 1].endDate.getTime() <= period.beginDate.getTime());
|
|
78
|
+
if (row) {
|
|
79
|
+
row.push(period);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
rows.push([period]);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return rows;
|
|
86
|
+
}
|
|
87
|
+
function buildRow(periods, range, colorOf) {
|
|
88
|
+
if (!periods.length)
|
|
89
|
+
return [];
|
|
90
|
+
const result = [];
|
|
91
|
+
const { begin, end } = range;
|
|
92
|
+
if (periods[0].beginDate > begin) {
|
|
93
|
+
result.push(gapBar(begin, periods[0].beginDate));
|
|
94
|
+
}
|
|
95
|
+
let previous = null;
|
|
96
|
+
for (const period of periods) {
|
|
97
|
+
if (previous) {
|
|
98
|
+
result.push(gapBar(previous.endDate, period.beginDate));
|
|
99
|
+
}
|
|
100
|
+
result.push(periodBar(period, begin, end, colorOf(period)));
|
|
101
|
+
previous = period;
|
|
102
|
+
}
|
|
103
|
+
if (previous && previous.endDate < end) {
|
|
104
|
+
result.push(gapBar(previous.endDate, end));
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
function gapBar(from, to) {
|
|
109
|
+
return bar(undefined, daysBetween(from, to), undefined, `gap-${from.getTime()}-${to.getTime()}`);
|
|
110
|
+
}
|
|
111
|
+
function periodBar(period, begin, end, color) {
|
|
112
|
+
const start = Math.max(begin.getTime(), period.beginDate.getTime());
|
|
113
|
+
const stop = Math.min(end.getTime(), period.endDate.getTime());
|
|
114
|
+
return bar(period, daysBetween(new Date(start), new Date(stop)), color, period.id);
|
|
115
|
+
}
|
|
116
|
+
function bar(period, diff, color, trackById) {
|
|
117
|
+
const classes = ['item'];
|
|
118
|
+
if (period)
|
|
119
|
+
classes.push('period', 'cursor');
|
|
120
|
+
if (period?.disabled)
|
|
121
|
+
classes.push('disabled');
|
|
122
|
+
return {
|
|
123
|
+
class: classes.join(' '),
|
|
124
|
+
style: `flex: ${diff} 1 0${color ? `; background-color: ${color}` : ''}`,
|
|
125
|
+
period,
|
|
126
|
+
trackById,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let nextTooltipId = 0;
|
|
131
|
+
/**
|
|
132
|
+
* Displays dated periods on a horizontal, year-based timeline. Overlapping
|
|
133
|
+
* periods stack into rows and take their colour from the matching legend item.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```html
|
|
137
|
+
* <onemrva-timeline
|
|
138
|
+
* title="Career timeline"
|
|
139
|
+
* [periods]="periods"
|
|
140
|
+
* [legend]="legend"
|
|
141
|
+
* [filters]="filters"
|
|
142
|
+
* [(activeFilter)]="activeFilter"
|
|
143
|
+
* [(selectedPeriod)]="selected"
|
|
144
|
+
* emptyMessage="No periods to display"
|
|
145
|
+
* />
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
class OnemrvaTimelineComponent {
|
|
149
|
+
constructor() {
|
|
150
|
+
this.fallbackColor = '#e5e5e5';
|
|
151
|
+
this.rowHeightPx = 56;
|
|
152
|
+
this.plotPaddingPx = 16;
|
|
153
|
+
this.axesHeightPx = 56;
|
|
154
|
+
/** Optional heading shown above the visible year range. */
|
|
155
|
+
this.title = input('', /* @ts-ignore */
|
|
156
|
+
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
157
|
+
/** Periods to plot on the timeline. */
|
|
158
|
+
this.periods = input([], /* @ts-ignore */
|
|
159
|
+
...(ngDevMode ? [{ debugName: "periods" }] : /* istanbul ignore next */ []));
|
|
160
|
+
/** Legend entries that map a period `type` to its label and color. */
|
|
161
|
+
this.legend = input(/* @ts-ignore */
|
|
162
|
+
...(ngDevMode ? [undefined, { debugName: "legend" }] : /* istanbul ignore next */ []));
|
|
163
|
+
/** Size, in years, of the visible window; two-way bindable via the period dropdown. */
|
|
164
|
+
this.fixedYearCount = model(5, /* @ts-ignore */
|
|
165
|
+
...(ngDevMode ? [{ debugName: "fixedYearCount" }] : /* istanbul ignore next */ []));
|
|
166
|
+
/** Year-window sizes offered by the period dropdown. */
|
|
167
|
+
this.yearOptions = input([1, 5, 10], /* @ts-ignore */
|
|
168
|
+
...(ngDevMode ? [{ debugName: "yearOptions" }] : /* istanbul ignore next */ []));
|
|
169
|
+
/** When true, the period dropdown offers a "Month" option. */
|
|
170
|
+
this.showMonthPicker = input(false, /* @ts-ignore */
|
|
171
|
+
...(ngDevMode ? [{ debugName: "showMonthPicker" }] : /* istanbul ignore next */ []));
|
|
172
|
+
/** Whether month numbers are shown under each year (only when the window spans at most 5 years). */
|
|
173
|
+
this.showMonths = input(true, /* @ts-ignore */
|
|
174
|
+
...(ngDevMode ? [{ debugName: "showMonths" }] : /* istanbul ignore next */ []));
|
|
175
|
+
/** Whether period labels are rendered inside the bars. */
|
|
176
|
+
this.showLabels = input(true, /* @ts-ignore */
|
|
177
|
+
...(ngDevMode ? [{ debugName: "showLabels" }] : /* istanbul ignore next */ []));
|
|
178
|
+
/** Whether the hover popup with period details is shown. */
|
|
179
|
+
this.showTooltip = input(true, /* @ts-ignore */
|
|
180
|
+
...(ngDevMode ? [{ debugName: "showTooltip" }] : /* istanbul ignore next */ []));
|
|
181
|
+
/** Optional max height (any CSS length) for the timeline body; rows scroll within it while the year and month axes stay pinned. Ignored when `fullSize` is true. */
|
|
182
|
+
this.maxHeight = input('', /* @ts-ignore */
|
|
183
|
+
...(ngDevMode ? [{ debugName: "maxHeight" }] : /* istanbul ignore next */ []));
|
|
184
|
+
/** When true, every row is shown at once and the body never scrolls; `maxHeight` is ignored. */
|
|
185
|
+
this.fullSize = input(false, /* @ts-ignore */
|
|
186
|
+
...(ngDevMode ? [{ debugName: "fullSize" }] : /* istanbul ignore next */ []));
|
|
187
|
+
/** Single-select filter toggles shown in the header; at most three are rendered. */
|
|
188
|
+
this.filters = input([], /* @ts-ignore */
|
|
189
|
+
...(ngDevMode ? [{ debugName: "filters" }] : /* istanbul ignore next */ []));
|
|
190
|
+
/** Message shown when no periods are provided. Nothing renders when it is empty. */
|
|
191
|
+
this.emptyMessage = input('', /* @ts-ignore */
|
|
192
|
+
...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
|
|
193
|
+
/** Currently selected period. Two-way bindable via `[(selectedPeriod)]`. */
|
|
194
|
+
this.selectedPeriod = model(/* @ts-ignore */
|
|
195
|
+
...(ngDevMode ? [undefined, { debugName: "selectedPeriod" }] : /* istanbul ignore next */ []));
|
|
196
|
+
/** Value of the currently active filter, or `undefined` when none. Two-way bindable. */
|
|
197
|
+
this.activeFilter = model(undefined, /* @ts-ignore */
|
|
198
|
+
...(ngDevMode ? [{ debugName: "activeFilter" }] : /* istanbul ignore next */ []));
|
|
199
|
+
/** Emits the active filter value whenever the selection changes. */
|
|
200
|
+
this.filterChange = output();
|
|
201
|
+
/**
|
|
202
|
+
* Emits the unit shown on the lower axis whenever the period view changes:
|
|
203
|
+
* `'months'` in the year view, or `'days'` when a single month is focused.
|
|
204
|
+
*/
|
|
205
|
+
this.axisUnitChange = output();
|
|
206
|
+
this.monthsByYear = computed(() => {
|
|
207
|
+
const map = new Map();
|
|
208
|
+
for (const year of this.years()) {
|
|
209
|
+
map.set(year, monthsWithSize(year));
|
|
210
|
+
}
|
|
211
|
+
return map;
|
|
212
|
+
}, /* @ts-ignore */
|
|
213
|
+
...(ngDevMode ? [{ debugName: "monthsByYear" }] : /* istanbul ignore next */ []));
|
|
214
|
+
this.tooltipInfo = signal({ visible: false }, /* @ts-ignore */
|
|
215
|
+
...(ngDevMode ? [{ debugName: "tooltipInfo" }] : /* istanbul ignore next */ []));
|
|
216
|
+
this.tooltipId = `onemrva-timeline-tooltip-${nextTooltipId++}`;
|
|
217
|
+
this.tooltipPositions = [
|
|
218
|
+
{
|
|
219
|
+
originX: 'center',
|
|
220
|
+
originY: 'bottom',
|
|
221
|
+
overlayX: 'center',
|
|
222
|
+
overlayY: 'top',
|
|
223
|
+
offsetY: 15,
|
|
224
|
+
},
|
|
225
|
+
];
|
|
226
|
+
this.changeRange = signal(0, /* @ts-ignore */
|
|
227
|
+
...(ngDevMode ? [{ debugName: "changeRange" }] : /* istanbul ignore next */ []));
|
|
228
|
+
this.activeType = signal(undefined, /* @ts-ignore */
|
|
229
|
+
...(ngDevMode ? [{ debugName: "activeType" }] : /* istanbul ignore next */ []));
|
|
230
|
+
this.monthMode = signal(false, /* @ts-ignore */
|
|
231
|
+
...(ngDevMode ? [{ debugName: "monthMode" }] : /* istanbul ignore next */ []));
|
|
232
|
+
this.locale = inject(LOCALE_ID);
|
|
233
|
+
this.shortMonthFormat = new Intl.DateTimeFormat(this.locale, {
|
|
234
|
+
month: 'short',
|
|
235
|
+
});
|
|
236
|
+
this.longMonthFormat = new Intl.DateTimeFormat(this.locale, {
|
|
237
|
+
month: 'long',
|
|
238
|
+
});
|
|
239
|
+
this.focusedDate = signal({
|
|
240
|
+
year: 0,
|
|
241
|
+
month: 0,
|
|
242
|
+
}, /* @ts-ignore */
|
|
243
|
+
...(ngDevMode ? [{ debugName: "focusedDate" }] : /* istanbul ignore next */ []));
|
|
244
|
+
this.scrollMaxHeight = computed(() => {
|
|
245
|
+
if (this.fullSize())
|
|
246
|
+
return null;
|
|
247
|
+
const raw = this.maxHeight().trim();
|
|
248
|
+
const match = /^(\d+)px$/.exec(raw);
|
|
249
|
+
if (!match)
|
|
250
|
+
return raw || null;
|
|
251
|
+
const middle = Number(match[1]) - this.axesHeightPx;
|
|
252
|
+
if (middle < this.rowHeightPx)
|
|
253
|
+
return raw;
|
|
254
|
+
const rows = Math.floor(middle / this.rowHeightPx);
|
|
255
|
+
return `${rows * this.rowHeightPx + this.axesHeightPx}px`;
|
|
256
|
+
}, /* @ts-ignore */
|
|
257
|
+
...(ngDevMode ? [{ debugName: "scrollMaxHeight" }] : /* istanbul ignore next */ []));
|
|
258
|
+
this.plotHeightPx = computed(() => this.displayedRows().length * this.rowHeightPx + this.plotPaddingPx, /* @ts-ignore */
|
|
259
|
+
...(ngDevMode ? [{ debugName: "plotHeightPx" }] : /* istanbul ignore next */ []));
|
|
260
|
+
this.fullRange = computed(() => fullTimelineRange(this.periods()), /* @ts-ignore */
|
|
261
|
+
...(ngDevMode ? [{ debugName: "fullRange" }] : /* istanbul ignore next */ []));
|
|
262
|
+
this.totalYears = computed(() => {
|
|
263
|
+
const range = this.fullRange();
|
|
264
|
+
return range ? range.baseEndYear - range.baseBeginYear + 1 : 0;
|
|
265
|
+
}, /* @ts-ignore */
|
|
266
|
+
...(ngDevMode ? [{ debugName: "totalYears" }] : /* istanbul ignore next */ []));
|
|
267
|
+
this.maxOffset = computed(() => Math.max(0, this.totalYears() - this.fixedYearCount()), /* @ts-ignore */
|
|
268
|
+
...(ngDevMode ? [{ debugName: "maxOffset" }] : /* istanbul ignore next */ []));
|
|
269
|
+
this.offset = computed(() => Math.min(Math.max(this.changeRange(), 0), this.maxOffset()), /* @ts-ignore */
|
|
270
|
+
...(ngDevMode ? [{ debugName: "offset" }] : /* istanbul ignore next */ []));
|
|
271
|
+
this.displayRange = computed(() => {
|
|
272
|
+
const range = this.fullRange();
|
|
273
|
+
if (!range)
|
|
274
|
+
return null;
|
|
275
|
+
if (this.monthMode()) {
|
|
276
|
+
const year = this.focusedDate().year;
|
|
277
|
+
return { beginYear: year, endYear: year };
|
|
278
|
+
}
|
|
279
|
+
if (this.fixedYearCount() >= this.totalYears()) {
|
|
280
|
+
return { beginYear: range.baseBeginYear, endYear: range.baseEndYear };
|
|
281
|
+
}
|
|
282
|
+
const beginYear = range.baseBeginYear + this.offset();
|
|
283
|
+
return { beginYear, endYear: beginYear + this.fixedYearCount() - 1 };
|
|
284
|
+
}, /* @ts-ignore */
|
|
285
|
+
...(ngDevMode ? [{ debugName: "displayRange" }] : /* istanbul ignore next */ []));
|
|
286
|
+
this.canPrevious = computed(() => this.fixedYearCount() < this.totalYears() && this.offset() > 0, /* @ts-ignore */
|
|
287
|
+
...(ngDevMode ? [{ debugName: "canPrevious" }] : /* istanbul ignore next */ []));
|
|
288
|
+
this.canNext = computed(() => this.fixedYearCount() < this.totalYears() &&
|
|
289
|
+
this.offset() < this.maxOffset(), /* @ts-ignore */
|
|
290
|
+
...(ngDevMode ? [{ debugName: "canNext" }] : /* istanbul ignore next */ []));
|
|
291
|
+
this.monthList = computed(() => {
|
|
292
|
+
const range = this.fullRange();
|
|
293
|
+
if (!range)
|
|
294
|
+
return [];
|
|
295
|
+
const list = [];
|
|
296
|
+
for (let year = range.baseBeginYear; year <= range.baseEndYear; year++) {
|
|
297
|
+
for (let month = 1; month <= 12; month++) {
|
|
298
|
+
list.push({
|
|
299
|
+
value: `${year}-${String(month).padStart(2, '0')}`,
|
|
300
|
+
label: `${this.shortMonthFormat.format(new Date(year, month - 1, 1))} ${year}`,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return list;
|
|
305
|
+
}, /* @ts-ignore */
|
|
306
|
+
...(ngDevMode ? [{ debugName: "monthList" }] : /* istanbul ignore next */ []));
|
|
307
|
+
this.monthLabel = computed(() => {
|
|
308
|
+
const focused = this.focusedDate();
|
|
309
|
+
return `${this.longMonthFormat.format(new Date(focused.year, focused.month, 1))} ${focused.year}`;
|
|
310
|
+
}, /* @ts-ignore */
|
|
311
|
+
...(ngDevMode ? [{ debugName: "monthLabel" }] : /* istanbul ignore next */ []));
|
|
312
|
+
this.focusedMonthValue = computed(() => {
|
|
313
|
+
const focused = this.focusedDate();
|
|
314
|
+
return `${focused.year}-${String(focused.month + 1).padStart(2, '0')}`;
|
|
315
|
+
}, /* @ts-ignore */
|
|
316
|
+
...(ngDevMode ? [{ debugName: "focusedMonthValue" }] : /* istanbul ignore next */ []));
|
|
317
|
+
this.canPreviousMonth = computed(() => {
|
|
318
|
+
const range = this.fullRange();
|
|
319
|
+
const focused = this.focusedDate();
|
|
320
|
+
if (!range)
|
|
321
|
+
return false;
|
|
322
|
+
return focused.year > range.baseBeginYear || focused.month > 0;
|
|
323
|
+
}, /* @ts-ignore */
|
|
324
|
+
...(ngDevMode ? [{ debugName: "canPreviousMonth" }] : /* istanbul ignore next */ []));
|
|
325
|
+
this.canNextMonth = computed(() => {
|
|
326
|
+
const range = this.fullRange();
|
|
327
|
+
const focused = this.focusedDate();
|
|
328
|
+
if (!range)
|
|
329
|
+
return false;
|
|
330
|
+
return focused.year < range.baseEndYear || focused.month < 11;
|
|
331
|
+
}, /* @ts-ignore */
|
|
332
|
+
...(ngDevMode ? [{ debugName: "canNextMonth" }] : /* istanbul ignore next */ []));
|
|
333
|
+
this.years = computed(() => {
|
|
334
|
+
const range = this.displayRange();
|
|
335
|
+
if (!range)
|
|
336
|
+
return [];
|
|
337
|
+
return Array.from({ length: range.endYear - range.beginYear + 1 }, (_, i) => range.beginYear + i);
|
|
338
|
+
}, /* @ts-ignore */
|
|
339
|
+
...(ngDevMode ? [{ debugName: "years" }] : /* istanbul ignore next */ []));
|
|
340
|
+
this.displayWindow = computed(() => {
|
|
341
|
+
const range = this.displayRange();
|
|
342
|
+
if (!range)
|
|
343
|
+
return null;
|
|
344
|
+
if (this.monthMode()) {
|
|
345
|
+
const { year, month } = this.focusedDate();
|
|
346
|
+
return {
|
|
347
|
+
begin: new Date(year, month, 1),
|
|
348
|
+
end: new Date(year, month + 1, 0),
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
return {
|
|
352
|
+
begin: new Date(range.beginYear, 0, 1),
|
|
353
|
+
end: new Date(range.endYear, 11, 31),
|
|
354
|
+
};
|
|
355
|
+
}, /* @ts-ignore */
|
|
356
|
+
...(ngDevMode ? [{ debugName: "displayWindow" }] : /* istanbul ignore next */ []));
|
|
357
|
+
this.visiblePeriods = computed(() => {
|
|
358
|
+
const bounds = this.displayWindow();
|
|
359
|
+
if (!bounds)
|
|
360
|
+
return [];
|
|
361
|
+
return this.periods()
|
|
362
|
+
.filter(p => p.endDate >= bounds.begin && p.beginDate <= bounds.end)
|
|
363
|
+
.sort((a, b) => a.beginDate.getTime() - b.beginDate.getTime());
|
|
364
|
+
}, /* @ts-ignore */
|
|
365
|
+
...(ngDevMode ? [{ debugName: "visiblePeriods" }] : /* istanbul ignore next */ []));
|
|
366
|
+
this.displayedRows = computed(() => {
|
|
367
|
+
const bounds = this.displayWindow();
|
|
368
|
+
const periods = this.visiblePeriods();
|
|
369
|
+
if (!bounds || !periods.length)
|
|
370
|
+
return [];
|
|
371
|
+
return splitIntoRows(periods).map(row => buildRow(row, bounds, period => this.colorOf(period)));
|
|
372
|
+
}, /* @ts-ignore */
|
|
373
|
+
...(ngDevMode ? [{ debugName: "displayedRows" }] : /* istanbul ignore next */ []));
|
|
374
|
+
this.focusedMonthDays = computed(() => {
|
|
375
|
+
const { year, month } = this.focusedDate();
|
|
376
|
+
const days = new Date(year, month + 1, 0).getDate();
|
|
377
|
+
return Array.from({ length: days }, (_, i) => i + 1);
|
|
378
|
+
}, /* @ts-ignore */
|
|
379
|
+
...(ngDevMode ? [{ debugName: "focusedMonthDays" }] : /* istanbul ignore next */ []));
|
|
380
|
+
this.dayWidthPercent = computed(() => {
|
|
381
|
+
const count = this.focusedMonthDays().length;
|
|
382
|
+
return count ? 100 / count : 0;
|
|
383
|
+
}, /* @ts-ignore */
|
|
384
|
+
...(ngDevMode ? [{ debugName: "dayWidthPercent" }] : /* istanbul ignore next */ []));
|
|
385
|
+
this.sortedLegend = computed(() => {
|
|
386
|
+
const seen = new Set();
|
|
387
|
+
return (this.legend() ?? [])
|
|
388
|
+
.filter(item => {
|
|
389
|
+
if (seen.has(item.type))
|
|
390
|
+
return false;
|
|
391
|
+
seen.add(item.type);
|
|
392
|
+
return true;
|
|
393
|
+
})
|
|
394
|
+
.sort((a, b) => a.label.localeCompare(b.label));
|
|
395
|
+
}, /* @ts-ignore */
|
|
396
|
+
...(ngDevMode ? [{ debugName: "sortedLegend" }] : /* istanbul ignore next */ []));
|
|
397
|
+
this.visibleFilters = computed(() => limitFilters(this.filters()), /* @ts-ignore */
|
|
398
|
+
...(ngDevMode ? [{ debugName: "visibleFilters" }] : /* istanbul ignore next */ []));
|
|
399
|
+
effect(() => {
|
|
400
|
+
this.periods();
|
|
401
|
+
this.fixedYearCount();
|
|
402
|
+
this.changeRange.set(0);
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
getLegend(type) {
|
|
406
|
+
if (!type)
|
|
407
|
+
return undefined;
|
|
408
|
+
return this.legend()?.find(l => l.type === type);
|
|
409
|
+
}
|
|
410
|
+
colorHex(color) {
|
|
411
|
+
return color ? TIMELINE_PALETTE[color] : this.fallbackColor;
|
|
412
|
+
}
|
|
413
|
+
colorOf(period) {
|
|
414
|
+
return this.colorHex(this.getLegend(period.type)?.color);
|
|
415
|
+
}
|
|
416
|
+
periodRange(period) {
|
|
417
|
+
return period ? formatPeriodRange(period) : '';
|
|
418
|
+
}
|
|
419
|
+
nextYear() {
|
|
420
|
+
this.changeRange.set(Math.min(this.maxOffset(), this.offset() + 1));
|
|
421
|
+
}
|
|
422
|
+
previousYear() {
|
|
423
|
+
this.changeRange.set(Math.max(0, this.offset() - 1));
|
|
424
|
+
}
|
|
425
|
+
onPeriodChange(value) {
|
|
426
|
+
if (value === 'month') {
|
|
427
|
+
const range = this.fullRange();
|
|
428
|
+
const periods = this.periods();
|
|
429
|
+
const earliest = periods.length
|
|
430
|
+
? periods.reduce((a, b) => (a.beginDate <= b.beginDate ? a : b))
|
|
431
|
+
: null;
|
|
432
|
+
this.focusedDate.set({
|
|
433
|
+
year: earliest?.beginDate.getFullYear() ?? range?.baseBeginYear ?? 0,
|
|
434
|
+
month: earliest?.beginDate.getMonth() ?? 0,
|
|
435
|
+
});
|
|
436
|
+
this.monthMode.set(true);
|
|
437
|
+
this.axisUnitChange.emit('days');
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
this.monthMode.set(false);
|
|
441
|
+
this.changeRange.set(0);
|
|
442
|
+
this.fixedYearCount.set(Number(value));
|
|
443
|
+
this.axisUnitChange.emit('months');
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
goToMonth(value) {
|
|
447
|
+
if (!value)
|
|
448
|
+
return;
|
|
449
|
+
const year = Number(value.slice(0, 4));
|
|
450
|
+
const month = Number(value.slice(5, 7)) - 1;
|
|
451
|
+
if (Number.isNaN(year) || Number.isNaN(month))
|
|
452
|
+
return;
|
|
453
|
+
this.focusedDate.set({ year, month });
|
|
454
|
+
}
|
|
455
|
+
previousMonth() {
|
|
456
|
+
const { year, month } = this.focusedDate();
|
|
457
|
+
if (!this.canPreviousMonth())
|
|
458
|
+
return;
|
|
459
|
+
this.focusedDate.set(month > 0 ? { year, month: month - 1 } : { year: year - 1, month: 11 });
|
|
460
|
+
}
|
|
461
|
+
nextMonth() {
|
|
462
|
+
const { year, month } = this.focusedDate();
|
|
463
|
+
if (!this.canNextMonth())
|
|
464
|
+
return;
|
|
465
|
+
this.focusedDate.set(month < 11 ? { year, month: month + 1 } : { year: year + 1, month: 0 });
|
|
466
|
+
}
|
|
467
|
+
onFilterChange(value) {
|
|
468
|
+
this.activeFilter.set(value);
|
|
469
|
+
this.filterChange.emit(value);
|
|
470
|
+
}
|
|
471
|
+
selectPeriod(period) {
|
|
472
|
+
if (!period || period.disabled)
|
|
473
|
+
return;
|
|
474
|
+
this.activeType.set(undefined);
|
|
475
|
+
this.selectedPeriod.set(period);
|
|
476
|
+
}
|
|
477
|
+
onLegendSelect(item) {
|
|
478
|
+
const match = this.periods().find(p => p.type === item.type && !p.disabled);
|
|
479
|
+
if (!match)
|
|
480
|
+
return;
|
|
481
|
+
if (this.monthMode()) {
|
|
482
|
+
this.focusedDate.set({
|
|
483
|
+
year: match.beginDate.getFullYear(),
|
|
484
|
+
month: match.beginDate.getMonth(),
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
const range = this.fullRange();
|
|
489
|
+
if (range) {
|
|
490
|
+
const target = match.beginDate.getFullYear() - range.baseBeginYear;
|
|
491
|
+
this.changeRange.set(Math.min(Math.max(target, 0), this.maxOffset()));
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
this.activeType.set(item.type);
|
|
495
|
+
this.selectedPeriod.set(match);
|
|
496
|
+
}
|
|
497
|
+
isActive(period) {
|
|
498
|
+
if (!period || period.disabled)
|
|
499
|
+
return false;
|
|
500
|
+
const type = this.activeType();
|
|
501
|
+
if (type && period.type === type)
|
|
502
|
+
return true;
|
|
503
|
+
return period.id === this.selectedPeriod()?.id;
|
|
504
|
+
}
|
|
505
|
+
showPeriodTooltip(period, origin) {
|
|
506
|
+
if (!period)
|
|
507
|
+
return;
|
|
508
|
+
this.tooltipInfo.set({ visible: true, period, origin });
|
|
509
|
+
}
|
|
510
|
+
hidePeriodTooltip() {
|
|
511
|
+
this.tooltipInfo.set({ visible: false });
|
|
512
|
+
}
|
|
513
|
+
isTooltipOpenFor(period) {
|
|
514
|
+
const info = this.tooltipInfo();
|
|
515
|
+
return info.visible && !!period && info.period?.id === period.id;
|
|
516
|
+
}
|
|
517
|
+
ariaLabel(period) {
|
|
518
|
+
if (!period)
|
|
519
|
+
return null;
|
|
520
|
+
const name = period.label ?? period.type ?? '';
|
|
521
|
+
return [name, this.periodRange(period)].filter(Boolean).join(', ') || null;
|
|
522
|
+
}
|
|
523
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: OnemrvaTimelineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
524
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: OnemrvaTimelineComponent, isStandalone: true, selector: "onemrva-timeline", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, periods: { classPropertyName: "periods", publicName: "periods", isSignal: true, isRequired: false, transformFunction: null }, legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: false, transformFunction: null }, fixedYearCount: { classPropertyName: "fixedYearCount", publicName: "fixedYearCount", isSignal: true, isRequired: false, transformFunction: null }, yearOptions: { classPropertyName: "yearOptions", publicName: "yearOptions", isSignal: true, isRequired: false, transformFunction: null }, showMonthPicker: { classPropertyName: "showMonthPicker", publicName: "showMonthPicker", isSignal: true, isRequired: false, transformFunction: null }, showMonths: { classPropertyName: "showMonths", publicName: "showMonths", isSignal: true, isRequired: false, transformFunction: null }, showLabels: { classPropertyName: "showLabels", publicName: "showLabels", isSignal: true, isRequired: false, transformFunction: null }, showTooltip: { classPropertyName: "showTooltip", publicName: "showTooltip", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, fullSize: { classPropertyName: "fullSize", publicName: "fullSize", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, selectedPeriod: { classPropertyName: "selectedPeriod", publicName: "selectedPeriod", isSignal: true, isRequired: false, transformFunction: null }, activeFilter: { classPropertyName: "activeFilter", publicName: "activeFilter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fixedYearCount: "fixedYearCountChange", selectedPeriod: "selectedPeriodChange", activeFilter: "activeFilterChange", filterChange: "filterChange", axisUnitChange: "axisUnitChange" }, host: { properties: { "attr.title": "null" } }, ngImport: i0, template: "<div class=\"container\">\n @if (periods().length !== 0) {\n <div class=\"navigation\">\n <div class=\"nav-info\">\n @if (title()) {\n <p class=\"timeline-title\">{{ title() }}</p>\n }\n <span class=\"timeline-range\">\n @if (monthMode()) {\n {{ monthLabel() }}\n } @else {\n {{ displayRange()?.beginYear }} - {{ displayRange()?.endYear }}\n }\n </span>\n </div>\n\n <div class=\"nav-controls\">\n <div class=\"nav-pager\">\n <button\n mat-icon-button\n data-cy=\"timeline-prev\"\n [attr.aria-label]=\"\n (monthMode() ? 'timeline.previousMonth' : 'timeline.previousYear')\n | translate\n \"\n [disabled]=\"monthMode() ? !canPreviousMonth() : !canPrevious()\"\n (click)=\"monthMode() ? previousMonth() : previousYear()\"\n >\n <mat-icon>arrow_back_ios</mat-icon>\n </button>\n <button\n mat-icon-button\n data-cy=\"timeline-next\"\n [attr.aria-label]=\"\n (monthMode() ? 'timeline.nextMonth' : 'timeline.nextYear')\n | translate\n \"\n [disabled]=\"monthMode() ? !canNextMonth() : !canNext()\"\n (click)=\"monthMode() ? nextMonth() : nextYear()\"\n >\n <mat-icon>arrow_forward_ios</mat-icon>\n </button>\n </div>\n\n <mat-form-field\n class=\"timeline-field timeline-period\"\n appearance=\"outline\"\n subscriptSizing=\"dynamic\"\n >\n <mat-label>{{ 'timeline.period' | translate }}</mat-label>\n <mat-select\n [attr.aria-label]=\"'timeline.period' | translate\"\n [value]=\"monthMode() ? 'month' : fixedYearCount()\"\n (selectionChange)=\"onPeriodChange($event.value)\"\n >\n @if (showMonthPicker()) {\n <mat-option value=\"month\" data-cy=\"timeline-period-month\">\n {{ 'timeline.month' | translate }}\n </mat-option>\n }\n @for (option of yearOptions(); track option) {\n <mat-option\n [value]=\"option\"\n [attr.data-cy]=\"'timeline-period-' + option\"\n >\n {{ option }}\n {{\n (option === 1 ? 'timeline.year' : 'timeline.years')\n | translate\n }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @if (showMonthPicker() && monthMode()) {\n <mat-form-field\n class=\"timeline-field timeline-month-jump\"\n appearance=\"outline\"\n subscriptSizing=\"dynamic\"\n >\n <mat-label>{{ 'timeline.goToMonth' | translate }}</mat-label>\n <mat-select\n data-cy=\"timeline-month-jump\"\n [attr.aria-label]=\"'timeline.goToMonth' | translate\"\n [value]=\"focusedMonthValue()\"\n (selectionChange)=\"goToMonth($event.value)\"\n >\n @for (month of monthList(); track month.value) {\n <mat-option [value]=\"month.value\">{{ month.label }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n\n @if (visibleFilters().length) {\n <mat-divider vertical class=\"nav-divider\" />\n <mat-button-toggle-group\n class=\"timeline-filters\"\n [value]=\"activeFilter()\"\n (change)=\"onFilterChange($any($event).value)\"\n >\n @for (filter of visibleFilters(); track filter.value) {\n <mat-button-toggle\n class=\"filter-toggle\"\n [value]=\"filter.value\"\n [attr.aria-label]=\"filter.label\"\n >\n {{ filter.label }}\n </mat-button-toggle>\n }\n </mat-button-toggle-group>\n }\n </div>\n </div>\n\n <div\n class=\"timeline-scroll\"\n [class.full-size]=\"fullSize()\"\n [style.max-height]=\"scrollMaxHeight()\"\n >\n <div class=\"timelineContainer\">\n <div class=\"timeline-years\">\n @for (year of years(); track 'axis-' + year) {\n <div class=\"axis-col\">{{ monthMode() ? monthLabel() : year }}</div>\n }\n </div>\n\n <div class=\"timeline-plot\" [style.height.px]=\"plotHeightPx()\">\n <div class=\"timeline-grid\">\n @for (year of years(); track 'grid-' + year) {\n <div class=\"grid-col\"></div>\n }\n </div>\n\n <div class=\"timeline\">\n @for (row of displayedRows(); track $index) {\n <div class=\"timeline-row\">\n @for (item of row; track item.trackById) {\n <div\n [class]=\"item.class\"\n [class.selected]=\"isActive(item.period)\"\n [style]=\"item.style\"\n [attr.role]=\"\n item.period && !item.period.disabled ? 'button' : null\n \"\n [attr.tabindex]=\"\n item.period && !item.period.disabled ? 0 : null\n \"\n [attr.aria-label]=\"ariaLabel(item?.period)\"\n [attr.aria-describedby]=\"\n isTooltipOpenFor(item?.period) ? tooltipId : null\n \"\n (mouseenter)=\"showPeriodTooltip(item?.period, origin)\"\n (mouseleave)=\"hidePeriodTooltip()\"\n (focus)=\"showPeriodTooltip(item?.period, origin)\"\n (blur)=\"hidePeriodTooltip()\"\n (click)=\"selectPeriod(item?.period)\"\n (keydown.enter)=\"selectPeriod(item?.period)\"\n (keydown.space)=\"selectPeriod(item?.period)\"\n (keydown.escape)=\"hidePeriodTooltip()\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n >\n @if (showLabels() && item.period?.label) {\n <span class=\"period-label\">{{ item.period.label }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (showMonths() && years().length <= 5) {\n <div class=\"timeline-months\">\n @if (monthMode()) {\n <div class=\"months-col\">\n @for (day of focusedMonthDays(); track day) {\n <span class=\"month\" [style.width.%]=\"dayWidthPercent()\">{{\n day\n }}</span>\n }\n </div>\n } @else {\n @for (year of years(); track 'months-' + year) {\n <div class=\"months-col\">\n @for (\n month of monthsByYear().get(year) ?? [];\n track month.month\n ) {\n <span class=\"month\" [style.width.%]=\"month.widthPercent\">{{\n month.month\n }}</span>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n </div>\n\n <div class=\"timeline-legend\">\n @for (legendItem of sortedLegend(); track legendItem) {\n <button\n type=\"button\"\n class=\"legend-item\"\n [attr.aria-label]=\"\n 'timeline.goTo' | translate: { label: legendItem.label }\n \"\n (click)=\"onLegendSelect(legendItem)\"\n >\n <span\n class=\"legend-color\"\n [style.background-color]=\"colorHex(legendItem.color)\"\n ></span>\n <span class=\"legend-label\">{{ legendItem.label }}</span>\n </button>\n }\n </div>\n\n @if (showTooltip() && tooltipInfo().visible && tooltipInfo().origin) {\n @let period = tooltipInfo().period;\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"tooltipInfo().origin!\"\n [cdkConnectedOverlayOpen]=\"true\"\n [cdkConnectedOverlayPositions]=\"tooltipPositions\"\n >\n <div\n class=\"tooltip\"\n role=\"tooltip\"\n [id]=\"tooltipId\"\n [style.border-color]=\"colorHex(getLegend(period?.type)?.color)\"\n >\n <div class=\"tooltip-title\">{{ periodRange(period) }}</div>\n @if (period?.label) {\n <div class=\"tooltip-label\">{{ period?.label }}</div>\n }\n @if (period?.description) {\n <div\n class=\"tooltip-description\"\n [innerHTML]=\"period?.description\"\n ></div>\n }\n </div>\n </ng-template>\n }\n } @else if (emptyMessage()) {\n <div class=\"parentDiv\">\n <p>{{ emptyMessage() }}</p>\n </div>\n }\n</div>\n", styles: [".container{display:flex;flex-direction:column;width:100%}.navigation{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:16px;margin-bottom:12px}.nav-info{display:flex;flex-direction:column}.timeline-title{margin:0;font-size:18px;font-weight:600;color:#242424}.timeline-range{font-size:14px;color:#242424}.nav-controls{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px}.nav-pager{display:flex;align-items:center;color:#242424}.nav-divider{align-self:center;height:28px}.timeline-field{width:150px;padding:0;--mat-form-field-container-height: 40px;--mat-form-field-container-vertical-padding: 8px}.timeline-month-jump{width:168px}.timeline-field ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.timeline-field ::ng-deep .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{--mat-form-field-container-height: 40px}.timeline-scroll{overflow:auto;overscroll-behavior:contain;scroll-snap-type:y mandatory;scroll-padding-top:26px;scrollbar-width:thin;scrollbar-color:#cfcde0 transparent}.timeline-scroll::-webkit-scrollbar{width:8px;height:8px}.timeline-scroll::-webkit-scrollbar-track{background:transparent}.timeline-scroll::-webkit-scrollbar-thumb{background:#cfcde0;border-radius:4px}.timeline-scroll::-webkit-scrollbar-thumb:hover{background:#bdbad4}.timeline-scroll.full-size{max-height:none;overflow-y:hidden;scroll-snap-type:none}.timelineContainer{position:relative;display:inline-flex;flex-direction:column;min-width:100%}.timeline-years{position:sticky;top:0;z-index:500;display:flex;flex-direction:row;background-color:#fff;box-shadow:0 3px 4px -2px #0000001f}.timeline-years .axis-col{flex:1 0 56px;height:25px;line-height:25px;border-right:solid 1px #d7d5ed;border-bottom:solid 1px #d7d5ed;text-align:center;color:#242424}.timeline-years .axis-col:first-child{border-left:solid 1px #d7d5ed}.timeline-plot{position:relative;overflow:hidden}.timeline-grid{position:absolute;inset:0;display:flex;flex-direction:row}.timeline-grid .grid-col{flex:1 0 56px;border-right:solid 1px #d7d5ed}.timeline-grid .grid-col:first-child{border-left:solid 1px #d7d5ed}.timeline{position:absolute;top:8px;left:4px;right:4px;display:flex;flex-direction:column}.timeline-months{position:sticky;bottom:0;z-index:500;display:flex;flex-direction:row;background-color:#fff;border-top:solid 1px #d7d5ed;box-shadow:0 -3px 4px -2px #0000001f}.timeline-months .months-col{flex:1 0 56px;height:29px;border-right:solid 1px #d7d5ed;font-size:0;white-space:nowrap}.timeline-months .months-col:first-child{border-left:solid 1px #d7d5ed}.timeline-months .month{display:inline-block;box-sizing:border-box;height:29px;line-height:29px;font-size:12px;color:#9a98a8;text-align:center}.timeline-row{display:flex;height:40px;margin-bottom:16px;scroll-snap-align:start;will-change:transform}.item{height:40px;min-width:0}.period{display:flex;align-items:center;height:40px;min-width:0;padding:0 8px;border-radius:4px;color:#fff;font-size:14px;overflow:hidden;z-index:200;transition:box-shadow .15s ease,opacity .15s ease}.period-label{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.period:hover{box-shadow:0 3px 3px #00000052}.period.selected{box-shadow:0 0 0 2px #242424;z-index:250}.period:focus-visible{outline:none;box-shadow:inset 0 0 0 2px #fff,inset 0 0 0 4px #242424;z-index:250}.period.disabled{opacity:.4;cursor:default;pointer-events:none}.cursor{cursor:pointer}.timeline-legend{display:flex;flex-wrap:wrap;gap:12px;margin-top:20px;justify-content:flex-end}.timeline-legend .legend-item{display:flex;align-items:center;gap:6px;margin:0;padding:2px 4px;background:none;border:none;border-radius:4px;font:inherit;color:inherit;cursor:pointer}.timeline-legend .legend-item:hover .legend-label{text-decoration:underline}.timeline-legend .legend-item:focus-visible{outline:2px solid #625d9c;outline-offset:1px}.timeline-legend .legend-color{width:16px;height:16px;border-radius:3px}.timeline-legend .legend-label{font-size:14px;color:#242424}.tooltip{position:absolute;transform:translate(-50%);background-color:#fff;border:1px solid #d7d5ed;border-radius:4px;padding:10px 15px;box-shadow:0 4px 8px #0000001a;color:#242424;z-index:999;width:300px;max-width:90vw}.tooltip-title{font-weight:600}.tooltip-label{margin-top:2px}.tooltip-description{margin-top:2px;color:#78767d}@media(max-width:600px){.navigation{flex-direction:column;align-items:stretch;gap:12px;margin-bottom:16px}.nav-controls{justify-content:flex-start;gap:12px}.nav-divider{display:none}.timeline-filters ::ng-deep .mat-button-toggle-label-content{padding:0 10px;font-size:.875rem}.timeline-title{font-size:16px}.timeline-legend{margin-top:16px;justify-content:flex-start;gap:8px 16px}}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i4.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i4.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
525
|
+
}
|
|
526
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: OnemrvaTimelineComponent, decorators: [{
|
|
527
|
+
type: Component,
|
|
528
|
+
args: [{ selector: 'onemrva-timeline', standalone: true, imports: [
|
|
529
|
+
MatIcon,
|
|
530
|
+
MatIconButton,
|
|
531
|
+
MatButtonToggleModule,
|
|
532
|
+
MatFormFieldModule,
|
|
533
|
+
MatSelectModule,
|
|
534
|
+
MatDivider,
|
|
535
|
+
OverlayModule,
|
|
536
|
+
TranslatePipe,
|
|
537
|
+
], encapsulation: ViewEncapsulation.Emulated, host: { '[attr.title]': 'null' }, template: "<div class=\"container\">\n @if (periods().length !== 0) {\n <div class=\"navigation\">\n <div class=\"nav-info\">\n @if (title()) {\n <p class=\"timeline-title\">{{ title() }}</p>\n }\n <span class=\"timeline-range\">\n @if (monthMode()) {\n {{ monthLabel() }}\n } @else {\n {{ displayRange()?.beginYear }} - {{ displayRange()?.endYear }}\n }\n </span>\n </div>\n\n <div class=\"nav-controls\">\n <div class=\"nav-pager\">\n <button\n mat-icon-button\n data-cy=\"timeline-prev\"\n [attr.aria-label]=\"\n (monthMode() ? 'timeline.previousMonth' : 'timeline.previousYear')\n | translate\n \"\n [disabled]=\"monthMode() ? !canPreviousMonth() : !canPrevious()\"\n (click)=\"monthMode() ? previousMonth() : previousYear()\"\n >\n <mat-icon>arrow_back_ios</mat-icon>\n </button>\n <button\n mat-icon-button\n data-cy=\"timeline-next\"\n [attr.aria-label]=\"\n (monthMode() ? 'timeline.nextMonth' : 'timeline.nextYear')\n | translate\n \"\n [disabled]=\"monthMode() ? !canNextMonth() : !canNext()\"\n (click)=\"monthMode() ? nextMonth() : nextYear()\"\n >\n <mat-icon>arrow_forward_ios</mat-icon>\n </button>\n </div>\n\n <mat-form-field\n class=\"timeline-field timeline-period\"\n appearance=\"outline\"\n subscriptSizing=\"dynamic\"\n >\n <mat-label>{{ 'timeline.period' | translate }}</mat-label>\n <mat-select\n [attr.aria-label]=\"'timeline.period' | translate\"\n [value]=\"monthMode() ? 'month' : fixedYearCount()\"\n (selectionChange)=\"onPeriodChange($event.value)\"\n >\n @if (showMonthPicker()) {\n <mat-option value=\"month\" data-cy=\"timeline-period-month\">\n {{ 'timeline.month' | translate }}\n </mat-option>\n }\n @for (option of yearOptions(); track option) {\n <mat-option\n [value]=\"option\"\n [attr.data-cy]=\"'timeline-period-' + option\"\n >\n {{ option }}\n {{\n (option === 1 ? 'timeline.year' : 'timeline.years')\n | translate\n }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @if (showMonthPicker() && monthMode()) {\n <mat-form-field\n class=\"timeline-field timeline-month-jump\"\n appearance=\"outline\"\n subscriptSizing=\"dynamic\"\n >\n <mat-label>{{ 'timeline.goToMonth' | translate }}</mat-label>\n <mat-select\n data-cy=\"timeline-month-jump\"\n [attr.aria-label]=\"'timeline.goToMonth' | translate\"\n [value]=\"focusedMonthValue()\"\n (selectionChange)=\"goToMonth($event.value)\"\n >\n @for (month of monthList(); track month.value) {\n <mat-option [value]=\"month.value\">{{ month.label }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n\n @if (visibleFilters().length) {\n <mat-divider vertical class=\"nav-divider\" />\n <mat-button-toggle-group\n class=\"timeline-filters\"\n [value]=\"activeFilter()\"\n (change)=\"onFilterChange($any($event).value)\"\n >\n @for (filter of visibleFilters(); track filter.value) {\n <mat-button-toggle\n class=\"filter-toggle\"\n [value]=\"filter.value\"\n [attr.aria-label]=\"filter.label\"\n >\n {{ filter.label }}\n </mat-button-toggle>\n }\n </mat-button-toggle-group>\n }\n </div>\n </div>\n\n <div\n class=\"timeline-scroll\"\n [class.full-size]=\"fullSize()\"\n [style.max-height]=\"scrollMaxHeight()\"\n >\n <div class=\"timelineContainer\">\n <div class=\"timeline-years\">\n @for (year of years(); track 'axis-' + year) {\n <div class=\"axis-col\">{{ monthMode() ? monthLabel() : year }}</div>\n }\n </div>\n\n <div class=\"timeline-plot\" [style.height.px]=\"plotHeightPx()\">\n <div class=\"timeline-grid\">\n @for (year of years(); track 'grid-' + year) {\n <div class=\"grid-col\"></div>\n }\n </div>\n\n <div class=\"timeline\">\n @for (row of displayedRows(); track $index) {\n <div class=\"timeline-row\">\n @for (item of row; track item.trackById) {\n <div\n [class]=\"item.class\"\n [class.selected]=\"isActive(item.period)\"\n [style]=\"item.style\"\n [attr.role]=\"\n item.period && !item.period.disabled ? 'button' : null\n \"\n [attr.tabindex]=\"\n item.period && !item.period.disabled ? 0 : null\n \"\n [attr.aria-label]=\"ariaLabel(item?.period)\"\n [attr.aria-describedby]=\"\n isTooltipOpenFor(item?.period) ? tooltipId : null\n \"\n (mouseenter)=\"showPeriodTooltip(item?.period, origin)\"\n (mouseleave)=\"hidePeriodTooltip()\"\n (focus)=\"showPeriodTooltip(item?.period, origin)\"\n (blur)=\"hidePeriodTooltip()\"\n (click)=\"selectPeriod(item?.period)\"\n (keydown.enter)=\"selectPeriod(item?.period)\"\n (keydown.space)=\"selectPeriod(item?.period)\"\n (keydown.escape)=\"hidePeriodTooltip()\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n >\n @if (showLabels() && item.period?.label) {\n <span class=\"period-label\">{{ item.period.label }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n @if (showMonths() && years().length <= 5) {\n <div class=\"timeline-months\">\n @if (monthMode()) {\n <div class=\"months-col\">\n @for (day of focusedMonthDays(); track day) {\n <span class=\"month\" [style.width.%]=\"dayWidthPercent()\">{{\n day\n }}</span>\n }\n </div>\n } @else {\n @for (year of years(); track 'months-' + year) {\n <div class=\"months-col\">\n @for (\n month of monthsByYear().get(year) ?? [];\n track month.month\n ) {\n <span class=\"month\" [style.width.%]=\"month.widthPercent\">{{\n month.month\n }}</span>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n </div>\n\n <div class=\"timeline-legend\">\n @for (legendItem of sortedLegend(); track legendItem) {\n <button\n type=\"button\"\n class=\"legend-item\"\n [attr.aria-label]=\"\n 'timeline.goTo' | translate: { label: legendItem.label }\n \"\n (click)=\"onLegendSelect(legendItem)\"\n >\n <span\n class=\"legend-color\"\n [style.background-color]=\"colorHex(legendItem.color)\"\n ></span>\n <span class=\"legend-label\">{{ legendItem.label }}</span>\n </button>\n }\n </div>\n\n @if (showTooltip() && tooltipInfo().visible && tooltipInfo().origin) {\n @let period = tooltipInfo().period;\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"tooltipInfo().origin!\"\n [cdkConnectedOverlayOpen]=\"true\"\n [cdkConnectedOverlayPositions]=\"tooltipPositions\"\n >\n <div\n class=\"tooltip\"\n role=\"tooltip\"\n [id]=\"tooltipId\"\n [style.border-color]=\"colorHex(getLegend(period?.type)?.color)\"\n >\n <div class=\"tooltip-title\">{{ periodRange(period) }}</div>\n @if (period?.label) {\n <div class=\"tooltip-label\">{{ period?.label }}</div>\n }\n @if (period?.description) {\n <div\n class=\"tooltip-description\"\n [innerHTML]=\"period?.description\"\n ></div>\n }\n </div>\n </ng-template>\n }\n } @else if (emptyMessage()) {\n <div class=\"parentDiv\">\n <p>{{ emptyMessage() }}</p>\n </div>\n }\n</div>\n", styles: [".container{display:flex;flex-direction:column;width:100%}.navigation{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:16px;margin-bottom:12px}.nav-info{display:flex;flex-direction:column}.timeline-title{margin:0;font-size:18px;font-weight:600;color:#242424}.timeline-range{font-size:14px;color:#242424}.nav-controls{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px}.nav-pager{display:flex;align-items:center;color:#242424}.nav-divider{align-self:center;height:28px}.timeline-field{width:150px;padding:0;--mat-form-field-container-height: 40px;--mat-form-field-container-vertical-padding: 8px}.timeline-month-jump{width:168px}.timeline-field ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.timeline-field ::ng-deep .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{--mat-form-field-container-height: 40px}.timeline-scroll{overflow:auto;overscroll-behavior:contain;scroll-snap-type:y mandatory;scroll-padding-top:26px;scrollbar-width:thin;scrollbar-color:#cfcde0 transparent}.timeline-scroll::-webkit-scrollbar{width:8px;height:8px}.timeline-scroll::-webkit-scrollbar-track{background:transparent}.timeline-scroll::-webkit-scrollbar-thumb{background:#cfcde0;border-radius:4px}.timeline-scroll::-webkit-scrollbar-thumb:hover{background:#bdbad4}.timeline-scroll.full-size{max-height:none;overflow-y:hidden;scroll-snap-type:none}.timelineContainer{position:relative;display:inline-flex;flex-direction:column;min-width:100%}.timeline-years{position:sticky;top:0;z-index:500;display:flex;flex-direction:row;background-color:#fff;box-shadow:0 3px 4px -2px #0000001f}.timeline-years .axis-col{flex:1 0 56px;height:25px;line-height:25px;border-right:solid 1px #d7d5ed;border-bottom:solid 1px #d7d5ed;text-align:center;color:#242424}.timeline-years .axis-col:first-child{border-left:solid 1px #d7d5ed}.timeline-plot{position:relative;overflow:hidden}.timeline-grid{position:absolute;inset:0;display:flex;flex-direction:row}.timeline-grid .grid-col{flex:1 0 56px;border-right:solid 1px #d7d5ed}.timeline-grid .grid-col:first-child{border-left:solid 1px #d7d5ed}.timeline{position:absolute;top:8px;left:4px;right:4px;display:flex;flex-direction:column}.timeline-months{position:sticky;bottom:0;z-index:500;display:flex;flex-direction:row;background-color:#fff;border-top:solid 1px #d7d5ed;box-shadow:0 -3px 4px -2px #0000001f}.timeline-months .months-col{flex:1 0 56px;height:29px;border-right:solid 1px #d7d5ed;font-size:0;white-space:nowrap}.timeline-months .months-col:first-child{border-left:solid 1px #d7d5ed}.timeline-months .month{display:inline-block;box-sizing:border-box;height:29px;line-height:29px;font-size:12px;color:#9a98a8;text-align:center}.timeline-row{display:flex;height:40px;margin-bottom:16px;scroll-snap-align:start;will-change:transform}.item{height:40px;min-width:0}.period{display:flex;align-items:center;height:40px;min-width:0;padding:0 8px;border-radius:4px;color:#fff;font-size:14px;overflow:hidden;z-index:200;transition:box-shadow .15s ease,opacity .15s ease}.period-label{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.period:hover{box-shadow:0 3px 3px #00000052}.period.selected{box-shadow:0 0 0 2px #242424;z-index:250}.period:focus-visible{outline:none;box-shadow:inset 0 0 0 2px #fff,inset 0 0 0 4px #242424;z-index:250}.period.disabled{opacity:.4;cursor:default;pointer-events:none}.cursor{cursor:pointer}.timeline-legend{display:flex;flex-wrap:wrap;gap:12px;margin-top:20px;justify-content:flex-end}.timeline-legend .legend-item{display:flex;align-items:center;gap:6px;margin:0;padding:2px 4px;background:none;border:none;border-radius:4px;font:inherit;color:inherit;cursor:pointer}.timeline-legend .legend-item:hover .legend-label{text-decoration:underline}.timeline-legend .legend-item:focus-visible{outline:2px solid #625d9c;outline-offset:1px}.timeline-legend .legend-color{width:16px;height:16px;border-radius:3px}.timeline-legend .legend-label{font-size:14px;color:#242424}.tooltip{position:absolute;transform:translate(-50%);background-color:#fff;border:1px solid #d7d5ed;border-radius:4px;padding:10px 15px;box-shadow:0 4px 8px #0000001a;color:#242424;z-index:999;width:300px;max-width:90vw}.tooltip-title{font-weight:600}.tooltip-label{margin-top:2px}.tooltip-description{margin-top:2px;color:#78767d}@media(max-width:600px){.navigation{flex-direction:column;align-items:stretch;gap:12px;margin-bottom:16px}.nav-controls{justify-content:flex-start;gap:12px}.nav-divider{display:none}.timeline-filters ::ng-deep .mat-button-toggle-label-content{padding:0 10px;font-size:.875rem}.timeline-title{font-size:16px}.timeline-legend{margin-top:16px;justify-content:flex-start;gap:8px 16px}}\n"] }]
|
|
538
|
+
}], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], periods: [{ type: i0.Input, args: [{ isSignal: true, alias: "periods", required: false }] }], legend: [{ type: i0.Input, args: [{ isSignal: true, alias: "legend", required: false }] }], fixedYearCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "fixedYearCount", required: false }] }, { type: i0.Output, args: ["fixedYearCountChange"] }], yearOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "yearOptions", required: false }] }], showMonthPicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "showMonthPicker", required: false }] }], showMonths: [{ type: i0.Input, args: [{ isSignal: true, alias: "showMonths", required: false }] }], showLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabels", required: false }] }], showTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTooltip", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], fullSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullSize", required: false }] }], filters: [{ type: i0.Input, args: [{ isSignal: true, alias: "filters", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], selectedPeriod: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedPeriod", required: false }] }, { type: i0.Output, args: ["selectedPeriodChange"] }], activeFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeFilter", required: false }] }, { type: i0.Output, args: ["activeFilterChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], axisUnitChange: [{ type: i0.Output, args: ["axisUnitChange"] }] } });
|
|
539
|
+
|
|
540
|
+
class OnemrvaTimelineModule {
|
|
541
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: OnemrvaTimelineModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
542
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.1", ngImport: i0, type: OnemrvaTimelineModule, imports: [OnemrvaTimelineComponent], exports: [OnemrvaTimelineComponent] }); }
|
|
543
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: OnemrvaTimelineModule, imports: [OnemrvaTimelineComponent] }); }
|
|
544
|
+
}
|
|
545
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: OnemrvaTimelineModule, decorators: [{
|
|
546
|
+
type: NgModule,
|
|
547
|
+
args: [{
|
|
548
|
+
declarations: [],
|
|
549
|
+
imports: [OnemrvaTimelineComponent],
|
|
550
|
+
exports: [OnemrvaTimelineComponent],
|
|
551
|
+
}]
|
|
552
|
+
}] });
|
|
553
|
+
|
|
554
|
+
/*
|
|
555
|
+
* Public API Surface of timeline
|
|
556
|
+
*/
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Generated bundle index. Do not edit.
|
|
560
|
+
*/
|
|
561
|
+
|
|
562
|
+
export { MAX_TIMELINE_FILTERS, OnemrvaTimelineComponent, OnemrvaTimelineModule, TIMELINE_COLORS, TIMELINE_PALETTE };
|
|
563
|
+
//# sourceMappingURL=onemrvapublic-design-system-timeline.mjs.map
|