@eui/ecl 22.0.0-alpha.40 → 22.0.0-alpha.41

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.
Files changed (171) hide show
  1. package/docs/changelog.html +74 -0
  2. package/docs/components/EclAccordionSummaryComponent.html +1 -1
  3. package/docs/components/EclAddToCalendarComponent.html +1 -1
  4. package/docs/components/EclAnimatedNumbersComponent.html +1 -1
  5. package/docs/components/EclAnimatedNumbersItemComponent.html +1 -1
  6. package/docs/components/EclAppComponent.html +1 -1
  7. package/docs/components/EclBannerComponent.html +1 -1
  8. package/docs/components/EclBlockquoteComponent.html +1 -1
  9. package/docs/components/EclBreadcrumbComponent.html +1 -1
  10. package/docs/components/EclBreadcrumbSegmentComponent.html +1 -1
  11. package/docs/components/EclButtonComponent.html +1 -1
  12. package/docs/components/EclCardBodyComponent.html +1 -1
  13. package/docs/components/EclCardComponent.html +1 -1
  14. package/docs/components/EclCarouselComponent.html +1 -1
  15. package/docs/components/EclCarouselItemComponent.html +1 -1
  16. package/docs/components/EclCategoryFilterComponent.html +1 -1
  17. package/docs/components/EclCategoryFilterItemComponent.html +1 -1
  18. package/docs/components/EclCategoryFilterListComponent.html +1 -1
  19. package/docs/components/EclCheckboxHelpComponent.html +1 -1
  20. package/docs/components/EclCheckboxLabelComponent.html +1 -1
  21. package/docs/components/EclContentBlockComponent.html +1 -1
  22. package/docs/components/EclContentItemComponent.html +1 -1
  23. package/docs/components/EclDateBlockComponent.html +1 -1
  24. package/docs/components/EclDescriptionListDefinitionComponent.html +1 -1
  25. package/docs/components/EclExpandableComponent.html +1 -1
  26. package/docs/components/EclFactFiguresComponent.html +1 -1
  27. package/docs/components/EclFactFiguresItemComponent.html +1 -1
  28. package/docs/components/EclFactFiguresViewAllComponent.html +1 -1
  29. package/docs/components/EclFeaturedComponent.html +1 -1
  30. package/docs/components/EclFeaturedItemComponent.html +1 -1
  31. package/docs/components/EclFeaturedItemDescriptionComponent.html +1 -1
  32. package/docs/components/EclFileComponent.html +1 -1
  33. package/docs/components/EclFileItemComponent.html +1 -1
  34. package/docs/components/EclFileItemsComponent.html +1 -1
  35. package/docs/components/EclFileListsComponent.html +1 -1
  36. package/docs/components/EclFormGroupComponent.html +1 -1
  37. package/docs/components/EclFormLabelComponent.html +1 -1
  38. package/docs/components/EclGalleryComponent.html +1 -1
  39. package/docs/components/EclGalleryFooterComponent.html +1 -1
  40. package/docs/components/EclGalleryItemComponent.html +1 -1
  41. package/docs/components/EclHighlightBoxComponent.html +1 -1
  42. package/docs/components/EclHighlightedSearchComponent.html +1 -1
  43. package/docs/components/EclIconComponent.html +1 -1
  44. package/docs/components/EclIndicatorComponent.html +1 -1
  45. package/docs/components/EclInpageNavigationComponent.html +1 -1
  46. package/docs/components/EclInpageNavigationItemComponent.html +1 -1
  47. package/docs/components/EclLayoutWrapperComponent.html +1 -1
  48. package/docs/components/EclListIllustrationComponent.html +1 -1
  49. package/docs/components/EclListIllustrationItemComponent.html +1 -1
  50. package/docs/components/EclLoadingIndicatorComponent.html +1 -1
  51. package/docs/components/EclMediaContainerComponent.html +1 -1
  52. package/docs/components/EclMegaMenuComponent.html +1 -1
  53. package/docs/components/EclMegaMenuFeaturedComponent.html +1 -1
  54. package/docs/components/EclMegaMenuInfoComponent.html +1 -1
  55. package/docs/components/EclMegaMenuItemComponent.html +1 -1
  56. package/docs/components/EclMegaMenuSubitemComponent.html +1 -1
  57. package/docs/components/EclMenuComponent.html +1 -1
  58. package/docs/components/EclMenuItemComponent.html +1 -1
  59. package/docs/components/EclMenuMegaComponent.html +1 -1
  60. package/docs/components/EclMenuMegaItemComponent.html +1 -1
  61. package/docs/components/EclModalBodyComponent.html +1 -1
  62. package/docs/components/EclModalComponent.html +1 -1
  63. package/docs/components/EclModalFooterComponent.html +1 -1
  64. package/docs/components/EclModalHeaderComponent.html +1 -1
  65. package/docs/components/EclMultiselectComponent.html +1 -1
  66. package/docs/components/EclMultiselectDropdownComponent.html +1 -1
  67. package/docs/components/EclMultiselectInputComponent.html +1 -1
  68. package/docs/components/EclMultiselectOptgroupComponent.html +1 -1
  69. package/docs/components/EclMultiselectOptionComponent.html +1 -1
  70. package/docs/components/EclNavigationListComponent.html +1 -1
  71. package/docs/components/EclNavigationListItemComponent.html +1 -1
  72. package/docs/components/EclNewsTickerComponent.html +1 -1
  73. package/docs/components/EclNewsTickerItemComponent.html +1 -1
  74. package/docs/components/EclNotificationComponent.html +1 -1
  75. package/docs/components/EclPageHeaderComponent.html +1 -1
  76. package/docs/components/EclPageHeaderDescriptionContainerComponent.html +1 -1
  77. package/docs/components/EclPageHeaderExpandableComponent.html +1 -1
  78. package/docs/components/EclPageHeaderSectionComponent.html +1 -1
  79. package/docs/components/EclPageHeaderSectionInfoComponent.html +1 -1
  80. package/docs/components/EclPageSummaryComponent.html +1 -1
  81. package/docs/components/EclPaginationComponent.html +1 -1
  82. package/docs/components/EclPaginationItemComponent.html +1 -1
  83. package/docs/components/EclPopoverComponent.html +1 -1
  84. package/docs/components/EclQuizCardComponent.html +1 -1
  85. package/docs/components/EclQuizComponent.html +1 -1
  86. package/docs/components/EclRadioHelpComponent.html +1 -1
  87. package/docs/components/EclRadioLabelComponent.html +1 -1
  88. package/docs/components/EclRangeBubbleComponent.html +1 -1
  89. package/docs/components/EclRangeValueComponent.html +1 -1
  90. package/docs/components/EclRatingFieldComponent.html +1 -1
  91. package/docs/components/EclSearchFormComponent.html +1 -1
  92. package/docs/components/EclSelectContainerComponent.html +1 -1
  93. package/docs/components/EclSiteFooterComponent.html +1 -1
  94. package/docs/components/EclSiteFooterCoownerComponent.html +1 -1
  95. package/docs/components/EclSiteFooterCoreComponent.html +1 -1
  96. package/docs/components/EclSiteFooterFeedbackComponent.html +1 -1
  97. package/docs/components/EclSiteFooterFixedContentEUComponent.html +1 -1
  98. package/docs/components/EclSiteFooterRowCommonComponent.html +1 -1
  99. package/docs/components/EclSiteHeaderActionComponent.html +1 -1
  100. package/docs/components/EclSiteHeaderBannerTopComponent.html +1 -1
  101. package/docs/components/EclSiteHeaderComponent.html +1 -1
  102. package/docs/components/EclSiteHeaderCustomActionComponent.html +1 -1
  103. package/docs/components/EclSiteHeaderEnvironmentComponent.html +1 -1
  104. package/docs/components/EclSiteHeaderLanguageComponent.html +1 -1
  105. package/docs/components/EclSiteHeaderLanguagePopoverComponent.html +1 -1
  106. package/docs/components/EclSiteHeaderLoginComponent.html +1 -1
  107. package/docs/components/EclSiteHeaderNotificationComponent.html +1 -1
  108. package/docs/components/EclSiteHeaderSearchComponent.html +1 -1
  109. package/docs/components/EclSloganTickerComponent.html +1 -1
  110. package/docs/components/EclSocialMediaFollowComponent.html +1 -1
  111. package/docs/components/EclSocialMediaFollowItemComponent.html +1 -1
  112. package/docs/components/EclSplashPageComponent.html +1 -1
  113. package/docs/components/EclSplashPageLanguageCategoryComponent.html +1 -1
  114. package/docs/components/EclSplashPageLanguageContainerComponent.html +1 -1
  115. package/docs/components/EclSplashPageLanguageLinkComponent.html +1 -1
  116. package/docs/components/EclSpotlightComponent.html +1 -1
  117. package/docs/components/EclSpotlightLinkComponent.html +1 -1
  118. package/docs/components/EclStickyContainerComponent.html +1 -1
  119. package/docs/components/EclStoryCardComponent.html +1 -1
  120. package/docs/components/EclStoryCardGridDetailsComponent.html +1 -1
  121. package/docs/components/EclStoryCardItemComponent.html +1 -1
  122. package/docs/components/EclTabComponent.html +1 -1
  123. package/docs/components/EclTabLabelComponent.html +1 -1
  124. package/docs/components/EclTableSortButtonComponent.html +1 -1
  125. package/docs/components/EclTabsComponent.html +1 -1
  126. package/docs/components/EclTagComponent.html +47 -107
  127. package/docs/components/EclTextMediaComponent.html +45 -30
  128. package/docs/components/EclTimelineComponent.html +2 -221
  129. package/docs/components/EclTimelineItemComponent.html +41 -443
  130. package/docs/components/EclTimelineItemTogglerComponent.html +7 -97
  131. package/docs/directives/ECLBaseDirective.html +0 -4
  132. package/docs/directives/EclTextAreaDirective.html +53 -100
  133. package/docs/directives/EclTextInputDirective.html +47 -144
  134. package/docs/directives/EclTimelineItemLabelDirective.html +0 -46
  135. package/docs/directives/EclTimelineItemTitleDirective.html +0 -46
  136. package/docs/directives/EclTimelineSetDirective.html +0 -104
  137. package/docs/directives/EclTooltipDirective.html +4 -157
  138. package/docs/js/search/search_index.js +2 -2
  139. package/docs/json/EclTimelineComponent.md +1 -1
  140. package/docs/json/EclTimelineItemComponent.md +4 -4
  141. package/docs/json/EclTimelineItemTogglerComponent.md +2 -2
  142. package/docs/json/documentation.json +1673 -2083
  143. package/docs/llms.txt +21 -25
  144. package/docs/properties.html +1 -1
  145. package/fesm2022/eui-ecl-components-ecl-tag.mjs +19 -22
  146. package/fesm2022/eui-ecl-components-ecl-tag.mjs.map +1 -1
  147. package/fesm2022/eui-ecl-components-ecl-text-area.mjs +16 -17
  148. package/fesm2022/eui-ecl-components-ecl-text-area.mjs.map +1 -1
  149. package/fesm2022/eui-ecl-components-ecl-text-input.mjs +14 -17
  150. package/fesm2022/eui-ecl-components-ecl-text-input.mjs.map +1 -1
  151. package/fesm2022/eui-ecl-components-ecl-text-media.mjs +10 -9
  152. package/fesm2022/eui-ecl-components-ecl-text-media.mjs.map +1 -1
  153. package/fesm2022/eui-ecl-components-ecl-timeline.mjs +132 -133
  154. package/fesm2022/eui-ecl-components-ecl-timeline.mjs.map +1 -1
  155. package/fesm2022/eui-ecl-components-ecl-tooltip.mjs +8 -14
  156. package/fesm2022/eui-ecl-components-ecl-tooltip.mjs.map +1 -1
  157. package/fesm2022/eui-ecl-core.mjs +0 -1
  158. package/fesm2022/eui-ecl-core.mjs.map +1 -1
  159. package/package.json +1 -1
  160. package/types/eui-ecl-components-ecl-tag.d.ts +2 -3
  161. package/types/eui-ecl-components-ecl-tag.d.ts.map +1 -1
  162. package/types/eui-ecl-components-ecl-text-area.d.ts +2 -2
  163. package/types/eui-ecl-components-ecl-text-area.d.ts.map +1 -1
  164. package/types/eui-ecl-components-ecl-text-input.d.ts +3 -3
  165. package/types/eui-ecl-components-ecl-text-input.d.ts.map +1 -1
  166. package/types/eui-ecl-components-ecl-text-media.d.ts +1 -1
  167. package/types/eui-ecl-components-ecl-text-media.d.ts.map +1 -1
  168. package/types/eui-ecl-components-ecl-timeline.d.ts +65 -50
  169. package/types/eui-ecl-components-ecl-timeline.d.ts.map +1 -1
  170. package/types/eui-ecl-components-ecl-tooltip.d.ts.map +1 -1
  171. package/types/eui-ecl-core.d.ts.map +1 -1
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { HostBinding, Directive, EventEmitter, HostListener, Output, Component, input, booleanAttribute, model, contentChild, forwardRef, ElementRef, viewChild, inject, Renderer2, ViewEncapsulation, contentChildren } from '@angular/core';
2
+ import { Directive, output, Component, input, booleanAttribute, model, linkedSignal, contentChild, forwardRef, computed, ElementRef, inject, Injector, Renderer2, effect, afterNextRender, ViewEncapsulation, contentChildren } from '@angular/core';
3
3
  import { ECLBaseDirective, EclBaseEvent } from '@eui/ecl/core';
4
4
  import { NgTemplateOutlet } from '@angular/common';
5
5
  import * as i2 from '@eui/ecl/components/ecl-button';
@@ -7,8 +7,6 @@ import { EUI_ECL_BUTTON } from '@eui/ecl/components/ecl-button';
7
7
  import * as i1 from '@eui/ecl/components/ecl-icon';
8
8
  import { EUI_ECL_ICON } from '@eui/ecl/components/ecl-icon';
9
9
  import { EclLinkDirective } from '@eui/ecl/components/ecl-link';
10
- import { Subject } from 'rxjs';
11
- import { takeUntil } from 'rxjs/operators';
12
10
 
13
11
  /**
14
12
  * Directive that applies the `ecl-timeline__label` class to an element.
@@ -23,17 +21,17 @@ class EclTimelineItemLabelDirective extends ECLBaseDirective {
23
21
  return [super.getCssClasses('ecl-timeline__label')].join(' ').trim();
24
22
  }
25
23
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineItemLabelDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
26
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: EclTimelineItemLabelDirective, isStandalone: true, selector: "[eclTimelineItemLabel]", host: { properties: { "class": "this.cssClasses" } }, usesInheritance: true, ngImport: i0 }); }
24
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: EclTimelineItemLabelDirective, isStandalone: true, selector: "[eclTimelineItemLabel]", host: { properties: { "class": "cssClasses" } }, usesInheritance: true, ngImport: i0 }); }
27
25
  }
28
26
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineItemLabelDirective, decorators: [{
29
27
  type: Directive,
30
28
  args: [{
31
29
  selector: '[eclTimelineItemLabel]',
30
+ host: {
31
+ '[class]': 'cssClasses',
32
+ },
32
33
  }]
33
- }], propDecorators: { cssClasses: [{
34
- type: HostBinding,
35
- args: ['class']
36
- }] } });
34
+ }] });
37
35
 
38
36
  /**
39
37
  * Directive that applies the `ecl-timeline__title` class to an element.
@@ -48,17 +46,17 @@ class EclTimelineItemTitleDirective extends ECLBaseDirective {
48
46
  return [super.getCssClasses('ecl-timeline__title')].join(' ').trim();
49
47
  }
50
48
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineItemTitleDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
51
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: EclTimelineItemTitleDirective, isStandalone: true, selector: "[eclTimelineItemTitle]", host: { properties: { "class": "this.cssClasses" } }, usesInheritance: true, ngImport: i0 }); }
49
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: EclTimelineItemTitleDirective, isStandalone: true, selector: "[eclTimelineItemTitle]", host: { properties: { "class": "cssClasses" } }, usesInheritance: true, ngImport: i0 }); }
52
50
  }
53
51
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineItemTitleDirective, decorators: [{
54
52
  type: Directive,
55
53
  args: [{
56
54
  selector: '[eclTimelineItemTitle]',
55
+ host: {
56
+ '[class]': 'cssClasses',
57
+ },
57
58
  }]
58
- }], propDecorators: { cssClasses: [{
59
- type: HostBinding,
60
- args: ['class']
61
- }] } });
59
+ }] });
62
60
 
63
61
  /**
64
62
  * Component representing a toggler inside a timeline item.
@@ -71,8 +69,7 @@ class EclTimelineItemTogglerComponent extends ECLBaseDirective {
71
69
  * Event emitted when the toggler is activated (clicked).
72
70
  * Used to trigger expand/collapse behavior in the parent timeline item.
73
71
  */
74
- // eslint-disable-next-line
75
- this.toggle = new EventEmitter();
72
+ this.toggle = output();
76
73
  }
77
74
  /**
78
75
  * Handles click events on the toggler element and emits the `toggle` event.
@@ -81,17 +78,14 @@ class EclTimelineItemTogglerComponent extends ECLBaseDirective {
81
78
  this.toggle.emit();
82
79
  }
83
80
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineItemTogglerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
84
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.2", type: EclTimelineItemTogglerComponent, isStandalone: true, selector: "ecl-timeline-item-toggler, li[eclTimelineItemToggler]", outputs: { toggle: "toggle" }, host: { listeners: { "click": "onTogglerClick()" } }, usesInheritance: true, ngImport: i0, template: "<ng-content></ng-content>\n" }); }
81
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.2", type: EclTimelineItemTogglerComponent, isStandalone: true, selector: "li[eclTimelineItemToggler]", outputs: { toggle: "toggle" }, host: { listeners: { "click": "onTogglerClick()" } }, usesInheritance: true, ngImport: i0, template: "<ng-content></ng-content>\n" }); }
85
82
  }
86
83
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineItemTogglerComponent, decorators: [{
87
84
  type: Component,
88
- args: [{ selector: 'ecl-timeline-item-toggler, li[eclTimelineItemToggler]', template: "<ng-content></ng-content>\n" }]
89
- }], propDecorators: { toggle: [{
90
- type: Output
91
- }], onTogglerClick: [{
92
- type: HostListener,
93
- args: ['click']
94
- }] } });
85
+ args: [{ selector: 'li[eclTimelineItemToggler]', host: {
86
+ '(click)': 'onTogglerClick()',
87
+ }, template: "<ng-content></ng-content>\n" }]
88
+ }], propDecorators: { toggle: [{ type: i0.Output, args: ["toggle"] }] } });
95
89
 
96
90
  /**
97
91
  * Event emitted when a timeline item is toggled (expanded or collapsed).
@@ -114,7 +108,7 @@ class EclTimelineItemToggleEvent extends EclBaseEvent {
114
108
 
115
109
  class EclTimelineItemComponent extends ECLBaseDirective {
116
110
  constructor() {
117
- super(...arguments);
111
+ super();
118
112
  /**
119
113
  * Text label shown when the item is collapsed and can be expanded.
120
114
  * Defaults to `'Expand'`.
@@ -134,31 +128,23 @@ class EclTimelineItemComponent extends ECLBaseDirective {
134
128
  */
135
129
  this.isTogglerExpanded = model(false, /* @ts-ignore */
136
130
  ...(ngDevMode ? [{ debugName: "isTogglerExpanded" }] : /* istanbul ignore next */ []));
137
- // @HostBinding('attr.style') customStyle = '';
138
131
  /**
139
- * Reference to a projected custom toggler component.
132
+ * Whether the item is initially collapsed.
133
+ * Applies the `ecl-timeline__item--collapsed` CSS class when true.
140
134
  */
141
- this.timelineItemToggler = contentChild(forwardRef(() => EclTimelineItemTogglerComponent), /* @ts-ignore */
142
- ...(ngDevMode ? [{ debugName: "timelineItemToggler" }] : /* istanbul ignore next */ []));
143
- this.timelineTitle = contentChild(forwardRef(() => EclTimelineItemTitleDirective), /* @ts-ignore */
144
- ...(ngDevMode ? [{ debugName: "timelineTitle" }] : /* istanbul ignore next */ []));
145
- /**
146
- * Reference to a projected ECL link, used for setting focus after toggle.
147
- */
148
- this.eclLink = contentChild(forwardRef(() => EclLinkDirective), /* @ts-ignore */
149
- ...(ngDevMode ? [{ debugName: "eclLink" }] : /* istanbul ignore next */ []));
135
+ this.isCollapsed = input(false, { ...(ngDevMode ? { debugName: "isCollapsed" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
150
136
  /**
151
- * Reference to a projected label for the item. Used to set height, when item has no content and title.
137
+ * Live collapsed state of the item.
138
+ *
139
+ * Seeded from the `isCollapsed` input but writable at runtime, so the parent
140
+ * `EclTimelineComponent` can expand or collapse grouped items in response to
141
+ * a toggler interaction. Resets to the input value if the input changes.
152
142
  */
153
- this.eclTimelineItemLabel = contentChild(forwardRef(() => EclTimelineItemLabelDirective), { ...(ngDevMode ? { debugName: "eclTimelineItemLabel" } : /* istanbul ignore next */ {}), read: ElementRef });
154
- /**
155
- * Whether the item is collapsed.
156
- * Adds the `ecl-timeline__item--collapsed` CSS class when true.
157
- */
158
- this.isCollapsed = input(false, { ...(ngDevMode ? { debugName: "isCollapsed" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
143
+ this.isCollapsedState = linkedSignal(() => this.isCollapsed(), /* @ts-ignore */
144
+ ...(ngDevMode ? [{ debugName: "isCollapsedState" }] : /* istanbul ignore next */ []));
159
145
  /**
160
146
  * Whether the item is a toggler (e.g. expands/collapses related items).
161
- * Adds the `ecl-timeline__item--toggle` CSS class when true.
147
+ * Applies the `ecl-timeline__item--toggle` CSS class when true.
162
148
  */
163
149
  this.isToggler = input(false, { ...(ngDevMode ? { debugName: "isToggler" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
164
150
  /**
@@ -171,42 +157,66 @@ class EclTimelineItemComponent extends ECLBaseDirective {
171
157
  * Event emitted when the toggler is clicked.
172
158
  * Consumers can call `preventDefault()` on the event to cancel toggle behavior.
173
159
  */
174
- // eslint-disable-next-line
175
- this.toggle = new EventEmitter();
176
- this.contentSlotRef = viewChild('contentSlot', /* @ts-ignore */
177
- ...(ngDevMode ? [{ debugName: "contentSlotRef" }] : /* istanbul ignore next */ []));
178
- this.destroy$ = new Subject();
179
- this.hasContent = false;
180
- this.hasHeight = false;
181
- this.renderer = inject(Renderer2);
182
- this.host = inject((ElementRef));
183
- }
184
- /**
185
- * Adds the `ecl-timeline__item` class to the host element.
186
- */
187
- get cssClasses() {
188
- return [
160
+ this.toggle = output();
161
+ /**
162
+ * Reference to a projected ECL link, used for setting focus after toggle.
163
+ * Read by the parent `EclTimelineComponent` to move focus after a toggle.
164
+ */
165
+ this.eclLink = contentChild(forwardRef(() => EclLinkDirective), /* @ts-ignore */
166
+ ...(ngDevMode ? [{ debugName: "eclLink" }] : /* istanbul ignore next */ []));
167
+ /**
168
+ * Host CSS classes for the timeline item.
169
+ *
170
+ * Each modifier is derived by invoking the corresponding signal, so the
171
+ * classes reflect the actual input / runtime values. Binding the signal
172
+ * directly through `@HostBinding('class.x')` would always evaluate the
173
+ * signal function as truthy and apply every modifier unconditionally.
174
+ */
175
+ this.cssClasses = computed(() => [
189
176
  super.getCssClasses('ecl-timeline__item'),
190
177
  this.isHeadline() ? 'ecl-timeline__item--headline' : '',
191
- ].join(' ');
192
- }
193
- ngAfterViewChecked() {
194
- if (!this.hasHeight) {
195
- setTimeout(() => {
196
- const node = this.contentSlotRef()?.nativeElement;
197
- if (node) {
198
- this.hasContent =
199
- (node.textContent?.trim().length ?? 0) > 0 || node.children.length > 0;
200
- }
201
- const eclTimelineItemLabel = this.eclTimelineItemLabel();
202
- if (!this.isToggler() && eclTimelineItemLabel) {
203
- const labelHeight = eclTimelineItemLabel.nativeElement.getBoundingClientRect().height;
204
- this.hasHeight = labelHeight > 0;
205
- this.host.nativeElement.style.setProperty('--ecl-timeline-label-height', `${labelHeight}px`);
206
- this.renderer.setStyle(this.host.nativeElement, 'box-sizing', 'unset');
207
- }
208
- });
209
- }
178
+ this.isCollapsedState() ? 'ecl-timeline__item--collapsed' : '',
179
+ this.isToggler() ? 'ecl-timeline__item--toggle' : '',
180
+ ].join(' '), /* @ts-ignore */
181
+ ...(ngDevMode ? [{ debugName: "cssClasses" }] : /* istanbul ignore next */ []));
182
+ /**
183
+ * Reference to a projected custom toggler component.
184
+ */
185
+ this.timelineItemToggler = contentChild(forwardRef(() => EclTimelineItemTogglerComponent), /* @ts-ignore */
186
+ ...(ngDevMode ? [{ debugName: "timelineItemToggler" }] : /* istanbul ignore next */ []));
187
+ /**
188
+ * Reference to a projected label for the item. Used to set height, when item has no content and title.
189
+ */
190
+ this.eclTimelineItemLabel = contentChild(forwardRef(() => EclTimelineItemLabelDirective), { ...(ngDevMode ? { debugName: "eclTimelineItemLabel" } : /* istanbul ignore next */ {}), read: ElementRef });
191
+ this.injector = inject(Injector);
192
+ this.renderer = inject(Renderer2);
193
+ this.host = inject((ElementRef));
194
+ this.hasMeasuredLabelHeight = false;
195
+ // Measure the label height once the item is actually displayed, and expose
196
+ // it as the `--ecl-timeline-label-height` custom property. A collapsed item
197
+ // is `display: none` and therefore has no measurable height, so the
198
+ // measurement is deferred until the item becomes visible. Reacting to
199
+ // `isCollapsedState` ensures items revealed by a toggler are measured too.
200
+ effect(() => {
201
+ const isMeasurable = !this.isToggler() && !this.isCollapsedState();
202
+ if (!isMeasurable || this.hasMeasuredLabelHeight) {
203
+ return;
204
+ }
205
+ let labelHeight = 0;
206
+ afterNextRender({
207
+ earlyRead: () => {
208
+ const labelElement = this.eclTimelineItemLabel();
209
+ labelHeight = labelElement?.nativeElement.getBoundingClientRect().height ?? 0;
210
+ },
211
+ write: () => {
212
+ if (labelHeight > 0) {
213
+ this.hasMeasuredLabelHeight = true;
214
+ this.host.nativeElement.style.setProperty('--ecl-timeline-label-height', `${labelHeight}px`);
215
+ this.renderer.setStyle(this.host.nativeElement, 'box-sizing', 'unset');
216
+ }
217
+ },
218
+ }, { injector: this.injector });
219
+ });
210
220
  }
211
221
  /**
212
222
  * Lifecycle hook that sets up event subscriptions after content is initialized.
@@ -214,7 +224,7 @@ class EclTimelineItemComponent extends ECLBaseDirective {
214
224
  ngAfterContentInit() {
215
225
  const timelineItemToggler = this.timelineItemToggler();
216
226
  if (timelineItemToggler) {
217
- timelineItemToggler.toggle.pipe(takeUntil(this.destroy$)).subscribe(() => {
227
+ this.togglerSubscription = timelineItemToggler.toggle.subscribe(() => {
218
228
  this.handleToggler();
219
229
  });
220
230
  }
@@ -223,8 +233,7 @@ class EclTimelineItemComponent extends ECLBaseDirective {
223
233
  * Lifecycle hook called on component destruction to clean up subscriptions.
224
234
  */
225
235
  ngOnDestroy() {
226
- this.destroy$.next(true);
227
- this.destroy$.unsubscribe();
236
+ this.togglerSubscription?.unsubscribe();
228
237
  }
229
238
  /**
230
239
  * True if the expand label should be visible.
@@ -247,95 +256,86 @@ class EclTimelineItemComponent extends ECLBaseDirective {
247
256
  }
248
257
  /**
249
258
  * Handles click events from the default toggler element.
250
- *
251
- * @param evt The mouse click event.
252
259
  */
253
- onTogglerClick(evt) {
260
+ onTogglerClick() {
254
261
  this.handleToggler();
255
262
  }
256
263
  handleToggler() {
257
264
  const nextExpandedState = !this.isTogglerExpanded();
258
265
  const event = new EclTimelineItemToggleEvent(nextExpandedState, this.toggleGroup());
259
266
  if (!event.defaultPrevented) {
260
- this.toggle.next(event);
267
+ this.toggle.emit(event);
261
268
  this.isTogglerExpanded.set(nextExpandedState);
262
269
  }
263
270
  }
264
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
265
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: EclTimelineItemComponent, isStandalone: true, selector: "ecl-timeline-item, li[eclTimelineItem]", inputs: { expandLabel: { classPropertyName: "expandLabel", publicName: "expandLabel", isSignal: true, isRequired: false, transformFunction: null }, collapseLabel: { classPropertyName: "collapseLabel", publicName: "collapseLabel", isSignal: true, isRequired: false, transformFunction: null }, isHeadline: { classPropertyName: "isHeadline", publicName: "isHeadline", isSignal: true, isRequired: false, transformFunction: null }, isTogglerExpanded: { classPropertyName: "isTogglerExpanded", publicName: "isTogglerExpanded", isSignal: true, isRequired: false, transformFunction: null }, isCollapsed: { classPropertyName: "isCollapsed", publicName: "isCollapsed", isSignal: true, isRequired: false, transformFunction: null }, isToggler: { classPropertyName: "isToggler", publicName: "isToggler", isSignal: true, isRequired: false, transformFunction: null }, toggleGroup: { classPropertyName: "toggleGroup", publicName: "toggleGroup", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isTogglerExpanded: "isTogglerExpandedChange", toggle: "toggle" }, host: { properties: { "class": "this.cssClasses", "class.ecl-timeline__item--collapsed": "this.isCollapsed", "class.ecl-timeline__item--toggle": "this.isToggler" } }, queries: [{ propertyName: "timelineItemToggler", first: true, predicate: i0.forwardRef(() => EclTimelineItemTogglerComponent), descendants: true, isSignal: true }, { propertyName: "timelineTitle", first: true, predicate: i0.forwardRef(() => EclTimelineItemTitleDirective), descendants: true, isSignal: true }, { propertyName: "eclLink", first: true, predicate: i0.forwardRef(() => EclLinkDirective), descendants: true, isSignal: true }, { propertyName: "eclTimelineItemLabel", first: true, predicate: i0.forwardRef(() => EclTimelineItemLabelDirective), descendants: true, read: ElementRef, isSignal: true }], viewQueries: [{ propertyName: "contentSlotRef", first: true, predicate: ["contentSlot"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (isToggler()) {\n <div class=\"ecl-timeline__content\">\n @if (hasDefaultToggler()) {\n <button eclButton (click)=\"onTogglerClick($event)\" variant=\"secondary\">\n @if (isShowExpandLabel) {\n <span eclButtonLabel> {{ expandLabel() }} </span>\n }\n @if (isShowCollapseLabel) {\n <span eclButtonLabel> {{ collapseLabel() }} </span>\n }\n <ecl-icon icon=\"corner-arrow\" size=\"fluid\" [transform]=\"!isTogglerExpanded() ? 'rotate-180' : ''\"></ecl-icon>\n </button>\n }\n\n\n <ng-content select=\"ecl-timeline-item-toggler\"></ng-content>\n\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n}\n@else {\n <div class=\"ecl-timeline__tooltip\">\n <div class=\"ecl-timeline__tooltip-arrow\"></div>\n <ng-content select=\"[eclTimelineItemLabel]\"></ng-content>\n\n <ng-content select=\"[eclTimelineItemTitle]\"></ng-content>\n\n <div class=\"ecl-timeline__content\" #contentSlot>\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n </div>\n}\n\n<ng-template #content>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["ecl-timeline-item{display:list-item}\n"], dependencies: [{ kind: "component", type: i1.EclIconComponent, selector: "ecl-icon", inputs: ["iconSet", "icon", "size", "color", "transform", "ariaLabelledby", "role", "title", "ariaHidden", "focusable", "isFlipHorizontal"] }, { kind: "component", type: i2.EclButtonComponent, selector: "button[eclButton], button[ecl-button], a[eclButton]", inputs: ["isIconOnly", "variant", "eclStyle", "size", "containerStyleClass"] }, { kind: "directive", type: i2.EclButtonLabelDirective, selector: "[eclButtonLabel]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None }); }
271
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
272
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: EclTimelineItemComponent, isStandalone: true, selector: "li[eclTimelineItem]", inputs: { expandLabel: { classPropertyName: "expandLabel", publicName: "expandLabel", isSignal: true, isRequired: false, transformFunction: null }, collapseLabel: { classPropertyName: "collapseLabel", publicName: "collapseLabel", isSignal: true, isRequired: false, transformFunction: null }, isHeadline: { classPropertyName: "isHeadline", publicName: "isHeadline", isSignal: true, isRequired: false, transformFunction: null }, isTogglerExpanded: { classPropertyName: "isTogglerExpanded", publicName: "isTogglerExpanded", isSignal: true, isRequired: false, transformFunction: null }, isCollapsed: { classPropertyName: "isCollapsed", publicName: "isCollapsed", isSignal: true, isRequired: false, transformFunction: null }, isToggler: { classPropertyName: "isToggler", publicName: "isToggler", isSignal: true, isRequired: false, transformFunction: null }, toggleGroup: { classPropertyName: "toggleGroup", publicName: "toggleGroup", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isTogglerExpanded: "isTogglerExpandedChange", toggle: "toggle" }, host: { properties: { "class": "cssClasses()" } }, queries: [{ propertyName: "eclLink", first: true, predicate: i0.forwardRef(() => EclLinkDirective), descendants: true, isSignal: true }, { propertyName: "timelineItemToggler", first: true, predicate: i0.forwardRef(() => EclTimelineItemTogglerComponent), descendants: true, isSignal: true }, { propertyName: "eclTimelineItemLabel", first: true, predicate: i0.forwardRef(() => EclTimelineItemLabelDirective), descendants: true, read: ElementRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (isToggler()) {\n <div class=\"ecl-timeline__content\">\n @if (hasDefaultToggler()) {\n <button eclButton (click)=\"onTogglerClick()\" variant=\"secondary\">\n @if (isShowExpandLabel) {\n <span eclButtonLabel> {{ expandLabel() }} </span>\n }\n @if (isShowCollapseLabel) {\n <span eclButtonLabel> {{ collapseLabel() }} </span>\n }\n <ecl-icon icon=\"corner-arrow\" size=\"fluid\" [transform]=\"!isTogglerExpanded() ? 'rotate-180' : ''\"></ecl-icon>\n </button>\n }\n\n\n <ng-content select=\"ecl-timeline-item-toggler\"></ng-content>\n\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n}\n@else {\n <div class=\"ecl-timeline__tooltip\">\n <div class=\"ecl-timeline__tooltip-arrow\"></div>\n <ng-content select=\"[eclTimelineItemLabel]\"></ng-content>\n\n <ng-content select=\"[eclTimelineItemTitle]\"></ng-content>\n\n <div class=\"ecl-timeline__content\" #contentSlot>\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n </div>\n}\n\n<ng-template #content>\n <ng-content></ng-content>\n</ng-template>\n", dependencies: [{ kind: "component", type: i1.EclIconComponent, selector: "ecl-icon", inputs: ["iconSet", "icon", "size", "color", "transform", "ariaLabelledby", "role", "title", "ariaHidden", "focusable", "isFlipHorizontal"] }, { kind: "component", type: i2.EclButtonComponent, selector: "button[eclButton], button[ecl-button], a[eclButton]", inputs: ["isIconOnly", "variant", "eclStyle", "size", "containerStyleClass"] }, { kind: "directive", type: i2.EclButtonLabelDirective, selector: "[eclButtonLabel]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None }); }
266
273
  }
267
274
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineItemComponent, decorators: [{
268
275
  type: Component,
269
- args: [{ selector: 'ecl-timeline-item, li[eclTimelineItem]', imports: [...EUI_ECL_ICON, ...EUI_ECL_BUTTON, NgTemplateOutlet], encapsulation: ViewEncapsulation.None, template: "@if (isToggler()) {\n <div class=\"ecl-timeline__content\">\n @if (hasDefaultToggler()) {\n <button eclButton (click)=\"onTogglerClick($event)\" variant=\"secondary\">\n @if (isShowExpandLabel) {\n <span eclButtonLabel> {{ expandLabel() }} </span>\n }\n @if (isShowCollapseLabel) {\n <span eclButtonLabel> {{ collapseLabel() }} </span>\n }\n <ecl-icon icon=\"corner-arrow\" size=\"fluid\" [transform]=\"!isTogglerExpanded() ? 'rotate-180' : ''\"></ecl-icon>\n </button>\n }\n\n\n <ng-content select=\"ecl-timeline-item-toggler\"></ng-content>\n\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n}\n@else {\n <div class=\"ecl-timeline__tooltip\">\n <div class=\"ecl-timeline__tooltip-arrow\"></div>\n <ng-content select=\"[eclTimelineItemLabel]\"></ng-content>\n\n <ng-content select=\"[eclTimelineItemTitle]\"></ng-content>\n\n <div class=\"ecl-timeline__content\" #contentSlot>\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n </div>\n}\n\n<ng-template #content>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["ecl-timeline-item{display:list-item}\n"] }]
270
- }], propDecorators: { expandLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandLabel", required: false }] }], collapseLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseLabel", required: false }] }], isHeadline: [{ type: i0.Input, args: [{ isSignal: true, alias: "isHeadline", required: false }] }], isTogglerExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "isTogglerExpanded", required: false }] }, { type: i0.Output, args: ["isTogglerExpandedChange"] }], cssClasses: [{
271
- type: HostBinding,
272
- args: ['class']
273
- }], timelineItemToggler: [{ type: i0.ContentChild, args: [forwardRef(() => EclTimelineItemTogglerComponent), { isSignal: true }] }], timelineTitle: [{ type: i0.ContentChild, args: [forwardRef(() => EclTimelineItemTitleDirective), { isSignal: true }] }], eclLink: [{ type: i0.ContentChild, args: [forwardRef(() => EclLinkDirective), { isSignal: true }] }], eclTimelineItemLabel: [{ type: i0.ContentChild, args: [forwardRef(() => EclTimelineItemLabelDirective), { ...{ read: ElementRef }, isSignal: true }] }], isCollapsed: [{
274
- type: HostBinding,
275
- args: ['class.ecl-timeline__item--collapsed']
276
- }], isToggler: [{
277
- type: HostBinding,
278
- args: ['class.ecl-timeline__item--toggle']
279
- }], toggleGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "toggleGroup", required: false }] }], toggle: [{
280
- type: Output
281
- }], contentSlotRef: [{ type: i0.ViewChild, args: ['contentSlot', { isSignal: true }] }] } });
276
+ args: [{ selector: 'li[eclTimelineItem]', imports: [...EUI_ECL_ICON, ...EUI_ECL_BUTTON, NgTemplateOutlet], host: {
277
+ '[class]': 'cssClasses()',
278
+ }, encapsulation: ViewEncapsulation.None, template: "@if (isToggler()) {\n <div class=\"ecl-timeline__content\">\n @if (hasDefaultToggler()) {\n <button eclButton (click)=\"onTogglerClick()\" variant=\"secondary\">\n @if (isShowExpandLabel) {\n <span eclButtonLabel> {{ expandLabel() }} </span>\n }\n @if (isShowCollapseLabel) {\n <span eclButtonLabel> {{ collapseLabel() }} </span>\n }\n <ecl-icon icon=\"corner-arrow\" size=\"fluid\" [transform]=\"!isTogglerExpanded() ? 'rotate-180' : ''\"></ecl-icon>\n </button>\n }\n\n\n <ng-content select=\"ecl-timeline-item-toggler\"></ng-content>\n\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n}\n@else {\n <div class=\"ecl-timeline__tooltip\">\n <div class=\"ecl-timeline__tooltip-arrow\"></div>\n <ng-content select=\"[eclTimelineItemLabel]\"></ng-content>\n\n <ng-content select=\"[eclTimelineItemTitle]\"></ng-content>\n\n <div class=\"ecl-timeline__content\" #contentSlot>\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n </div>\n}\n\n<ng-template #content>\n <ng-content></ng-content>\n</ng-template>\n" }]
279
+ }], ctorParameters: () => [], propDecorators: { expandLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandLabel", required: false }] }], collapseLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseLabel", required: false }] }], isHeadline: [{ type: i0.Input, args: [{ isSignal: true, alias: "isHeadline", required: false }] }], isTogglerExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "isTogglerExpanded", required: false }] }, { type: i0.Output, args: ["isTogglerExpandedChange"] }], isCollapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "isCollapsed", required: false }] }], isToggler: [{ type: i0.Input, args: [{ isSignal: true, alias: "isToggler", required: false }] }], toggleGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "toggleGroup", required: false }] }], toggle: [{ type: i0.Output, args: ["toggle"] }], eclLink: [{ type: i0.ContentChild, args: [forwardRef(() => EclLinkDirective), { isSignal: true }] }], timelineItemToggler: [{ type: i0.ContentChild, args: [forwardRef(() => EclTimelineItemTogglerComponent), { isSignal: true }] }], eclTimelineItemLabel: [{ type: i0.ContentChild, args: [forwardRef(() => EclTimelineItemLabelDirective), { ...{ read: ElementRef }, isSignal: true }] }] } });
282
280
 
283
281
  /**
284
282
  * Directive that applies the `ecl-timeline-set` class to an element.
285
283
  */
286
284
  class EclTimelineSetDirective extends ECLBaseDirective {
287
- constructor() {
288
- super(...arguments);
289
- this.hasClass = true;
290
- }
291
285
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineSetDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
292
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: EclTimelineSetDirective, isStandalone: true, selector: "[eclTimelineSet]", host: { properties: { "class.ecl-timeline-set": "this.hasClass" } }, usesInheritance: true, ngImport: i0 }); }
286
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: EclTimelineSetDirective, isStandalone: true, selector: "[eclTimelineSet]", host: { classAttribute: "ecl-timeline-set" }, usesInheritance: true, ngImport: i0 }); }
293
287
  }
294
288
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineSetDirective, decorators: [{
295
289
  type: Directive,
296
290
  args: [{
297
291
  selector: '[eclTimelineSet]',
292
+ host: {
293
+ 'class': 'ecl-timeline-set',
294
+ },
298
295
  }]
299
- }], propDecorators: { hasClass: [{
300
- type: HostBinding,
301
- args: ['class.ecl-timeline-set']
302
- }] } });
296
+ }] });
303
297
 
304
298
  class EclTimelineComponent extends ECLBaseDirective {
305
299
  constructor() {
306
300
  super(...arguments);
307
301
  this.isExpanded = null;
302
+ /**
303
+ * Host CSS classes for the timeline.
304
+ *
305
+ * Adds the `ecl-timeline--has-headline` modifier when the projected content
306
+ * includes a headline item.
307
+ */
308
+ this.cssClasses = computed(() => [
309
+ super.getCssClasses('ecl-timeline'),
310
+ this.hasHeadlineItem() ? 'ecl-timeline--has-headline' : '',
311
+ ].join(' '), /* @ts-ignore */
312
+ ...(ngDevMode ? [{ debugName: "cssClasses" }] : /* istanbul ignore next */ []));
308
313
  /**
309
314
  * List of projected `EclTimelineItemComponent` instances.
310
315
  * Collected using `@ContentChildren`.
311
316
  */
312
317
  this.timelineItems = contentChildren(forwardRef(() => EclTimelineItemComponent), /* @ts-ignore */
313
318
  ...(ngDevMode ? [{ debugName: "timelineItems" }] : /* istanbul ignore next */ []));
314
- this.destroy$ = new Subject();
319
+ /**
320
+ * Whether any projected item is marked as a headline.
321
+ */
322
+ this.hasHeadlineItem = computed(() => this.timelineItems().some((item) => item.isHeadline()), /* @ts-ignore */
323
+ ...(ngDevMode ? [{ debugName: "hasHeadlineItem" }] : /* istanbul ignore next */ []));
324
+ this.togglerSubscriptions = [];
315
325
  this.isFirstExpandedLinkFocused = false;
316
- this.hasHeadlineItem = false;
317
- }
318
- /**
319
- * Applies the `ecl-timeline` CSS class to the host element.
320
- */
321
- get cssClasses() {
322
- return [
323
- super.getCssClasses('ecl-timeline'),
324
- this.hasHeadlineItem ? 'ecl-timeline--has-headline' : '',
325
- ].join(' ');
326
326
  }
327
327
  /**
328
328
  * Lifecycle hook that is called after content (child components)
329
329
  * has been fully initialized.
330
330
  *
331
- * It sets up toggle event subscriptions for `isToggler` items and
332
- * collapses/expands related content items accordingly.
331
+ * Sets up toggle event subscriptions for `isToggler` items and
332
+ * collapses/expands related items in the same toggle group accordingly.
333
333
  */
334
334
  ngAfterContentInit() {
335
335
  this.timelineItems()
336
336
  .filter((item) => item.isToggler())
337
337
  .forEach((it) => {
338
- it.toggle.pipe(takeUntil(this.destroy$)).subscribe((evt) => {
338
+ const subscription = it.toggle.subscribe((evt) => {
339
339
  if (evt.isExpanded) {
340
340
  this.isExpanded = true;
341
341
  }
@@ -348,22 +348,22 @@ class EclTimelineComponent extends ECLBaseDirective {
348
348
  .filter((item) => item.toggleGroup() === evt.toggleGroup)
349
349
  .filter((item) => !item.isToggler())
350
350
  .forEach((item) => {
351
- // item.isCollapsed = !item.isCollapsed;
351
+ // An expanded toggler reveals the grouped items,
352
+ // a collapsed toggler hides them again.
353
+ item.isCollapsedState.set(!evt.isExpanded);
352
354
  this.onFocusFirstExpandedLink(item);
353
355
  });
354
356
  }
355
357
  });
358
+ this.togglerSubscriptions.push(subscription);
356
359
  });
357
- if (this.timelineItems()?.find(item => item.isHeadline()) !== undefined)
358
- this.hasHeadlineItem = true;
359
360
  }
360
361
  /**
361
362
  * Lifecycle hook called when the component is destroyed.
362
363
  * Cleans up subscriptions.
363
364
  */
364
365
  ngOnDestroy() {
365
- this.destroy$.next(true);
366
- this.destroy$.unsubscribe();
366
+ this.togglerSubscriptions.forEach((subscription) => subscription.unsubscribe());
367
367
  }
368
368
  /**
369
369
  * Focuses the first link in the expanded timeline item,
@@ -372,7 +372,7 @@ class EclTimelineComponent extends ECLBaseDirective {
372
372
  * @param item The timeline item to check and potentially focus.
373
373
  */
374
374
  onFocusFirstExpandedLink(item) {
375
- if (!item.isCollapsed()) {
375
+ if (!item.isCollapsedState()) {
376
376
  if (!this.isFirstExpandedLinkFocused && item.eclLink()) {
377
377
  setTimeout(() => item.eclLink().onFocus());
378
378
  this.isFirstExpandedLinkFocused = true;
@@ -383,15 +383,14 @@ class EclTimelineComponent extends ECLBaseDirective {
383
383
  }
384
384
  }
385
385
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
386
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.2", type: EclTimelineComponent, isStandalone: true, selector: "ecl-timeline, ol[eclTimeline]", host: { attributes: { "role": "list" }, properties: { "attr.data-ecl-timeline-expanded": "isExpanded", "class": "cssClasses" } }, queries: [{ propertyName: "timelineItems", predicate: i0.forwardRef(() => EclTimelineItemComponent), isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-content></ng-content>\n", styles: [":host{display:block}\n"] }); }
386
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.2", type: EclTimelineComponent, isStandalone: true, selector: "ol[eclTimeline]", host: { properties: { "attr.data-ecl-timeline-expanded": "isExpanded", "class": "cssClasses()" } }, queries: [{ propertyName: "timelineItems", predicate: i0.forwardRef(() => EclTimelineItemComponent), isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-content></ng-content>\n" }); }
387
387
  }
388
388
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclTimelineComponent, decorators: [{
389
389
  type: Component,
390
- args: [{ selector: 'ecl-timeline, ol[eclTimeline]', host: {
391
- role: 'list',
390
+ args: [{ selector: 'ol[eclTimeline]', host: {
392
391
  '[attr.data-ecl-timeline-expanded]': 'isExpanded',
393
- '[class]': 'cssClasses',
394
- }, template: "<ng-content></ng-content>\n", styles: [":host{display:block}\n"] }]
392
+ '[class]': 'cssClasses()',
393
+ }, template: "<ng-content></ng-content>\n" }]
395
394
  }], propDecorators: { timelineItems: [{ type: i0.ContentChildren, args: [forwardRef(() => EclTimelineItemComponent), { isSignal: true }] }] } });
396
395
 
397
396
  const EUI_ECL_TIMELINE = [