@eui/ecl 23.0.0-alpha.10 → 23.0.0-alpha.11

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 (231) hide show
  1. package/assets/i18n-ecl/bg.json +13 -2
  2. package/assets/i18n-ecl/cs.json +13 -2
  3. package/assets/i18n-ecl/da.json +13 -2
  4. package/assets/i18n-ecl/de.json +13 -2
  5. package/assets/i18n-ecl/el.json +13 -2
  6. package/assets/i18n-ecl/en.json +13 -2
  7. package/assets/i18n-ecl/es.json +13 -2
  8. package/assets/i18n-ecl/et.json +13 -2
  9. package/assets/i18n-ecl/fi.json +13 -2
  10. package/assets/i18n-ecl/fr.json +13 -2
  11. package/assets/i18n-ecl/ga.json +13 -2
  12. package/assets/i18n-ecl/hr.json +13 -2
  13. package/assets/i18n-ecl/hu.json +13 -2
  14. package/assets/i18n-ecl/it.json +13 -2
  15. package/assets/i18n-ecl/lt.json +13 -2
  16. package/assets/i18n-ecl/lv.json +13 -2
  17. package/assets/i18n-ecl/mt.json +13 -2
  18. package/assets/i18n-ecl/nl.json +13 -2
  19. package/assets/i18n-ecl/pl.json +13 -2
  20. package/assets/i18n-ecl/pt.json +13 -2
  21. package/assets/i18n-ecl/ro.json +13 -2
  22. package/assets/i18n-ecl/sk.json +13 -2
  23. package/assets/i18n-ecl/sl.json +13 -2
  24. package/assets/i18n-ecl/sv.json +13 -2
  25. package/components/ecl-highlighted-search/package.json +4 -0
  26. package/components/ecl-story-card/package.json +4 -0
  27. package/docs/changelog.html +10 -0
  28. package/docs/classes/EclBaseEvent.html +3 -0
  29. package/docs/classes/EclHighlightedSearchEvent.html +443 -0
  30. package/docs/components/EclAccordionSummaryComponent.html +2 -79
  31. package/docs/components/EclAddToCalendarComponent.html +2 -2
  32. package/docs/components/EclAnimatedNumbersComponent.html +2 -2
  33. package/docs/components/EclAnimatedNumbersItemComponent.html +2 -2
  34. package/docs/components/EclAppComponent.html +2 -2
  35. package/docs/components/EclBannerComponent.html +2 -2
  36. package/docs/components/EclBlockquoteComponent.html +2 -2
  37. package/docs/components/EclBreadcrumbComponent.html +2 -2
  38. package/docs/components/EclBreadcrumbSegmentComponent.html +2 -2
  39. package/docs/components/EclButtonComponent.html +2 -2
  40. package/docs/components/EclCardBodyComponent.html +2 -2
  41. package/docs/components/EclCardComponent.html +2 -2
  42. package/docs/components/EclCarouselComponent.html +2 -2
  43. package/docs/components/EclCarouselItemComponent.html +2 -2
  44. package/docs/components/EclCategoryFilterComponent.html +2 -2
  45. package/docs/components/EclCategoryFilterItemComponent.html +2 -2
  46. package/docs/components/EclCategoryFilterListComponent.html +2 -2
  47. package/docs/components/EclCheckboxHelpComponent.html +2 -2
  48. package/docs/components/EclCheckboxLabelComponent.html +2 -2
  49. package/docs/components/EclContentBlockComponent.html +2 -2
  50. package/docs/components/EclContentItemComponent.html +2 -2
  51. package/docs/components/EclDateBlockComponent.html +2 -2
  52. package/docs/components/EclDescriptionListDefinitionComponent.html +2 -2
  53. package/docs/components/EclExpandableComponent.html +2 -2
  54. package/docs/components/EclFactFiguresComponent.html +2 -2
  55. package/docs/components/EclFactFiguresItemComponent.html +2 -2
  56. package/docs/components/EclFactFiguresViewAllComponent.html +2 -2
  57. package/docs/components/EclFeaturedComponent.html +2 -2
  58. package/docs/components/EclFeaturedItemComponent.html +2 -2
  59. package/docs/components/EclFeaturedItemDescriptionComponent.html +2 -2
  60. package/docs/components/EclFileComponent.html +234 -110
  61. package/docs/components/EclFileItemComponent.html +13 -250
  62. package/docs/components/EclFileItemsComponent.html +34 -313
  63. package/docs/components/{EclFileTaxonomyComponent.html → EclFileListsComponent.html} +16 -107
  64. package/docs/components/EclFormGroupComponent.html +2 -2
  65. package/docs/components/EclFormLabelComponent.html +2 -2
  66. package/docs/components/EclGalleryComponent.html +2 -2
  67. package/docs/components/EclGalleryFooterComponent.html +2 -2
  68. package/docs/components/EclGalleryItemComponent.html +3 -3
  69. package/docs/components/EclHighlightBoxComponent.html +2 -2
  70. package/docs/components/EclHighlightedSearchComponent.html +1042 -0
  71. package/docs/components/EclIconComponent.html +5 -2
  72. package/docs/components/EclIndicatorComponent-1.html +2 -2
  73. package/docs/components/EclIndicatorComponent.html +2 -2
  74. package/docs/components/EclInpageNavigationComponent.html +2 -2
  75. package/docs/components/EclInpageNavigationItemComponent.html +2 -2
  76. package/docs/components/EclLayoutWrapperComponent.html +6 -109
  77. package/docs/components/EclListIllustrationComponent.html +2 -2
  78. package/docs/components/EclListIllustrationItemComponent.html +2 -2
  79. package/docs/components/EclLoadingIndicatorComponent.html +2 -2
  80. package/docs/components/EclMediaContainerComponent.html +2 -2
  81. package/docs/components/EclMegaMenuComponent.html +2 -2
  82. package/docs/components/EclMegaMenuFeaturedComponent.html +2 -2
  83. package/docs/components/EclMegaMenuInfoComponent.html +2 -2
  84. package/docs/components/EclMegaMenuItemComponent.html +2 -2
  85. package/docs/components/EclMegaMenuSubitemComponent.html +2 -2
  86. package/docs/components/EclMenuComponent.html +2 -2
  87. package/docs/components/EclMenuItemComponent.html +2 -2
  88. package/docs/components/EclMenuMegaComponent.html +2 -2
  89. package/docs/components/EclMenuMegaItemComponent.html +2 -2
  90. package/docs/components/EclModalBodyComponent.html +2 -2
  91. package/docs/components/EclModalComponent.html +2 -2
  92. package/docs/components/EclModalFooterComponent.html +2 -2
  93. package/docs/components/EclModalHeaderComponent.html +2 -2
  94. package/docs/components/EclMultiselectComponent.html +2 -2
  95. package/docs/components/EclMultiselectDropdownComponent.html +13 -98
  96. package/docs/components/EclMultiselectInputComponent.html +2 -2
  97. package/docs/components/EclMultiselectOptgroupComponent.html +2 -2
  98. package/docs/components/EclMultiselectOptionComponent.html +2 -2
  99. package/docs/components/EclNavigationListComponent.html +2 -2
  100. package/docs/components/EclNavigationListItemComponent.html +2 -2
  101. package/docs/components/EclNewsTickerComponent.html +2 -2
  102. package/docs/components/EclNewsTickerItemComponent.html +2 -2
  103. package/docs/components/EclNotificationComponent.html +2 -2
  104. package/docs/components/EclPageHeaderComponent.html +2 -2
  105. package/docs/components/EclPageHeaderDescriptionContainerComponent.html +2 -2
  106. package/docs/components/EclPageHeaderExpandableComponent.html +2 -2
  107. package/docs/components/EclPageHeaderNextComponent.html +2 -2
  108. package/docs/components/EclPageHeaderSectionComponent.html +2 -2
  109. package/docs/components/EclPageHeaderSectionInfoComponent.html +2 -2
  110. package/docs/components/EclPageSummaryComponent.html +2 -2
  111. package/docs/components/EclPaginationComponent.html +2 -2
  112. package/docs/components/EclPaginationItemComponent.html +2 -2
  113. package/docs/components/EclPopoverComponent.html +2 -2
  114. package/docs/components/EclQuizCardComponent.html +2 -2
  115. package/docs/components/EclQuizComponent.html +3 -3
  116. package/docs/components/EclRadioHelpComponent.html +2 -2
  117. package/docs/components/EclRadioLabelComponent.html +2 -2
  118. package/docs/components/EclRangeBubbleComponent.html +2 -2
  119. package/docs/components/EclRangeValueComponent.html +2 -2
  120. package/docs/components/EclRatingFieldComponent.html +2 -2
  121. package/docs/components/EclSearchFormComponent.html +2 -2
  122. package/docs/components/EclSelectContainerComponent.html +2 -2
  123. package/docs/components/EclSiteFooterComponent.html +2 -2
  124. package/docs/components/EclSiteFooterCoownerComponent.html +2 -2
  125. package/docs/components/EclSiteFooterCoreComponent.html +2 -2
  126. package/docs/components/EclSiteFooterFeedbackComponent.html +2 -2
  127. package/docs/components/EclSiteFooterFixedContentEUComponent.html +2 -2
  128. package/docs/components/EclSiteFooterRowCommonComponent.html +2 -2
  129. package/docs/components/EclSiteHeaderActionComponent.html +2 -2
  130. package/docs/components/EclSiteHeaderBannerTopComponent.html +2 -2
  131. package/docs/components/EclSiteHeaderComponent.html +2 -2
  132. package/docs/components/EclSiteHeaderCustomActionComponent.html +2 -2
  133. package/docs/components/EclSiteHeaderEnvironmentComponent.html +2 -2
  134. package/docs/components/EclSiteHeaderLanguageComponent.html +2 -2
  135. package/docs/components/EclSiteHeaderLanguagePopoverComponent.html +2 -2
  136. package/docs/components/EclSiteHeaderLoginComponent.html +2 -2
  137. package/docs/components/EclSiteHeaderNotificationComponent.html +2 -2
  138. package/docs/components/EclSiteHeaderSearchComponent.html +2 -2
  139. package/docs/components/EclSloganTickerComponent.html +2 -2
  140. package/docs/components/EclSocialMediaFollowComponent.html +2 -2
  141. package/docs/components/EclSocialMediaFollowItemComponent.html +2 -2
  142. package/docs/components/EclSplashPageComponent.html +2 -2
  143. package/docs/components/EclSplashPageLanguageCategoryComponent.html +2 -2
  144. package/docs/components/EclSplashPageLanguageContainerComponent.html +2 -2
  145. package/docs/components/EclSplashPageLanguageLinkComponent.html +2 -2
  146. package/docs/components/EclSpotlightComponent.html +2 -2
  147. package/docs/components/EclSpotlightLinkComponent.html +2 -2
  148. package/docs/components/EclStickyContainerComponent.html +2 -2
  149. package/docs/components/EclStoryCardComponent.html +908 -0
  150. package/docs/components/EclStoryCardGridDetailsComponent.html +946 -0
  151. package/docs/components/EclStoryCardItemComponent.html +916 -0
  152. package/docs/components/EclTabComponent.html +2 -2
  153. package/docs/components/EclTabLabelComponent.html +2 -2
  154. package/docs/components/EclTableSortButtonComponent.html +2 -2
  155. package/docs/components/EclTabsComponent.html +2 -2
  156. package/docs/components/EclTagComponent.html +2 -2
  157. package/docs/components/EclTextMediaComponent.html +2 -2
  158. package/docs/components/EclTimelineComponent.html +2 -2
  159. package/docs/components/EclTimelineItemComponent.html +2 -2
  160. package/docs/components/EclTimelineItemTogglerComponent.html +2 -2
  161. package/docs/directives/ECLBaseDirective.html +4 -4
  162. package/docs/directives/EclAccordionDirective.html +33 -36
  163. package/docs/directives/EclFileDownloadDirective.html +0 -116
  164. package/docs/directives/EclFileImageDirective.html +0 -116
  165. package/docs/directives/EclFileMetaDirective.html +488 -0
  166. package/docs/directives/EclFilePictureDirective.html +0 -95
  167. package/docs/directives/EclFilePreviewDirective.html +1 -199
  168. package/docs/directives/EclFileTitleDirective.html +0 -146
  169. package/docs/directives/EclFileTranslationDownloadDirective.html +0 -116
  170. package/docs/directives/EclHighlightedSearchSuggestionsDirective.html +394 -0
  171. package/docs/directives/EclLayoutItemDirective.html +0 -32
  172. package/docs/directives/EclStoryCardLinkDirective.html +491 -0
  173. package/docs/directives/EclStoryCardListDirective.html +491 -0
  174. package/docs/directives/EclStoryCardPictureDirective.html +497 -0
  175. package/docs/interfaces/EclStoryCardSelectionEvent.html +317 -0
  176. package/docs/js/menu-wc.js +34 -1
  177. package/docs/js/search/search_index.js +2 -2
  178. package/docs/json/EclAccordionDirective.md +1 -0
  179. package/docs/json/EclFileComponent.md +43 -7
  180. package/docs/json/EclFileItemComponent.md +6 -6
  181. package/docs/json/EclFileItemsComponent.md +6 -6
  182. package/docs/json/EclFileListsComponent.md +15 -0
  183. package/docs/json/EclFileMetaDirective.md +16 -0
  184. package/docs/json/EclFilePreviewDirective.md +1 -1
  185. package/docs/json/EclFileTitleDirective.md +0 -1
  186. package/docs/json/EclHighlightedSearchComponent.md +46 -0
  187. package/docs/json/EclHighlightedSearchSuggestionsDirective.md +13 -0
  188. package/docs/json/EclLayoutWrapperComponent.md +2 -2
  189. package/docs/json/EclStoryCardComponent.md +43 -0
  190. package/docs/json/EclStoryCardGridDetailsComponent.md +39 -0
  191. package/docs/json/EclStoryCardItemComponent.md +35 -0
  192. package/docs/json/EclStoryCardLinkDirective.md +19 -0
  193. package/docs/json/EclStoryCardListDirective.md +19 -0
  194. package/docs/json/EclStoryCardPictureDirective.md +22 -0
  195. package/docs/json/documentation.json +5287 -2643
  196. package/docs/llms.txt +242 -60
  197. package/docs/miscellaneous/variables.html +112 -1
  198. package/docs/overview.html +4 -4
  199. package/docs/properties.html +1 -1
  200. package/fesm2022/eui-ecl-components-ecl-accordion.mjs +46 -15
  201. package/fesm2022/eui-ecl-components-ecl-accordion.mjs.map +1 -1
  202. package/fesm2022/eui-ecl-components-ecl-file.mjs +284 -275
  203. package/fesm2022/eui-ecl-components-ecl-file.mjs.map +1 -1
  204. package/fesm2022/eui-ecl-components-ecl-gallery.mjs +2 -2
  205. package/fesm2022/eui-ecl-components-ecl-gallery.mjs.map +1 -1
  206. package/fesm2022/eui-ecl-components-ecl-highlighted-search.mjs +193 -0
  207. package/fesm2022/eui-ecl-components-ecl-highlighted-search.mjs.map +1 -0
  208. package/fesm2022/eui-ecl-components-ecl-layout-wrapper.mjs +10 -11
  209. package/fesm2022/eui-ecl-components-ecl-layout-wrapper.mjs.map +1 -1
  210. package/fesm2022/eui-ecl-components-ecl-multiselect.mjs +26 -36
  211. package/fesm2022/eui-ecl-components-ecl-multiselect.mjs.map +1 -1
  212. package/fesm2022/eui-ecl-components-ecl-quiz.mjs +36 -2
  213. package/fesm2022/eui-ecl-components-ecl-quiz.mjs.map +1 -1
  214. package/fesm2022/eui-ecl-components-ecl-story-card.mjs +505 -0
  215. package/fesm2022/eui-ecl-components-ecl-story-card.mjs.map +1 -0
  216. package/package.json +9 -1
  217. package/types/eui-ecl-components-ecl-accordion.d.ts +23 -5
  218. package/types/eui-ecl-components-ecl-accordion.d.ts.map +1 -1
  219. package/types/eui-ecl-components-ecl-file.d.ts +131 -116
  220. package/types/eui-ecl-components-ecl-file.d.ts.map +1 -1
  221. package/types/eui-ecl-components-ecl-highlighted-search.d.ts +104 -0
  222. package/types/eui-ecl-components-ecl-highlighted-search.d.ts.map +1 -0
  223. package/types/eui-ecl-components-ecl-layout-wrapper.d.ts +6 -8
  224. package/types/eui-ecl-components-ecl-layout-wrapper.d.ts.map +1 -1
  225. package/types/eui-ecl-components-ecl-multiselect.d.ts +2 -1
  226. package/types/eui-ecl-components-ecl-multiselect.d.ts.map +1 -1
  227. package/types/eui-ecl-components-ecl-quiz.d.ts +11 -0
  228. package/types/eui-ecl-components-ecl-quiz.d.ts.map +1 -1
  229. package/types/eui-ecl-components-ecl-story-card.d.ts +256 -0
  230. package/types/eui-ecl-components-ecl-story-card.d.ts.map +1 -0
  231. package/docs/json/EclFileTaxonomyComponent.md +0 -15
@@ -0,0 +1,505 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Directive, input, signal, output, contentChild, ElementRef, computed, ChangeDetectionStrategy, Component, booleanAttribute, contentChildren, viewChild, viewChildren, inject, ChangeDetectorRef, afterNextRender, effect, untracked } from '@angular/core';
3
+ import { EclIconComponent } from '@eui/ecl/components/ecl-icon';
4
+ import { ECLBaseDirective, EclRtlService } from '@eui/ecl/core';
5
+ import { TranslatePipe } from '@ngx-translate/core';
6
+ import { EmblaCarouselDirective } from 'embla-carousel-angular';
7
+ import { Subject, takeUntil } from 'rxjs';
8
+ import { outputToObservable } from '@angular/core/rxjs-interop';
9
+
10
+ /**
11
+ * Directive applied to the <ul> element that holds the story card items.
12
+ * Adds the grid container class and tablist role.
13
+ *
14
+ * @example
15
+ * <ul eclStoryCardList>...</ul>
16
+ */
17
+ class EclStoryCardListDirective extends ECLBaseDirective {
18
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardListDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
19
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.5", type: EclStoryCardListDirective, isStandalone: true, selector: "ul[eclStoryCardList]", host: { attributes: { "role": "tablist" }, properties: { "class": "getCssClasses(\"ecl-story-card__grid-container\")" } }, usesInheritance: true, ngImport: i0 }); }
20
+ }
21
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardListDirective, decorators: [{
22
+ type: Directive,
23
+ args: [{
24
+ selector: 'ul[eclStoryCardList]',
25
+ host: {
26
+ role: 'tablist',
27
+ '[class]': 'getCssClasses("ecl-story-card__grid-container")',
28
+ },
29
+ }]
30
+ }] });
31
+ /**
32
+ * Directive applied to <picture> elements inside a story card item.
33
+ * Adds the ECL picture classes.
34
+ *
35
+ * @example
36
+ * <picture eclStoryCardPicture>
37
+ * <source srcset="..." media="(max-width: 50rem)">
38
+ * <img src="..." alt="...">
39
+ * </picture>
40
+ */
41
+ class EclStoryCardPictureDirective extends ECLBaseDirective {
42
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardPictureDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
43
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.5", type: EclStoryCardPictureDirective, isStandalone: true, selector: "picture[eclStoryCardPicture]", host: { properties: { "class": "getCssClasses(\"ecl-picture ecl-story-card__picture\")" } }, usesInheritance: true, ngImport: i0 }); }
44
+ }
45
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardPictureDirective, decorators: [{
46
+ type: Directive,
47
+ args: [{
48
+ selector: 'picture[eclStoryCardPicture]',
49
+ host: {
50
+ '[class]': 'getCssClasses("ecl-picture ecl-story-card__picture")',
51
+ },
52
+ }]
53
+ }] });
54
+ /**
55
+ * Directive applied to <a> elements inside story card grid details.
56
+ * Adds the ECL link classes for the "Read more" link.
57
+ *
58
+ * @example
59
+ * <a eclStoryCardLink href="/example">Read more</a>
60
+ */
61
+ class EclStoryCardLinkDirective extends ECLBaseDirective {
62
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardLinkDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
63
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.5", type: EclStoryCardLinkDirective, isStandalone: true, selector: "[eclStoryCardLink]", host: { properties: { "class": "getCssClasses(\"ecl-link ecl-link--standalone ecl-link--icon ecl-story-card__link\")" } }, usesInheritance: true, ngImport: i0 }); }
64
+ }
65
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardLinkDirective, decorators: [{
66
+ type: Directive,
67
+ args: [{
68
+ selector: '[eclStoryCardLink]',
69
+ host: {
70
+ '[class]': 'getCssClasses("ecl-link ecl-link--standalone ecl-link--icon ecl-story-card__link")',
71
+ },
72
+ }]
73
+ }] });
74
+
75
+ /**
76
+ * Component for a single story card grid item (tab).
77
+ * Applied to <li> elements within the story card list.
78
+ *
79
+ * The user provides:
80
+ * - `gridTitle`: the short label shown in the accordion tab button
81
+ * - A <picture eclStoryCardPicture> as projected content
82
+ *
83
+ * The component internally renders the button with role="tab",
84
+ * the loading bar, and the title wrapper.
85
+ *
86
+ * @example
87
+ * <li eclStoryCardItem gridTitle="why twelve">
88
+ * <picture eclStoryCardPicture>
89
+ * <img src="example.jpg" alt="Example">
90
+ * </picture>
91
+ * </li>
92
+ */
93
+ class EclStoryCardItemComponent extends ECLBaseDirective {
94
+ constructor() {
95
+ super(...arguments);
96
+ /** Short title displayed in the accordion tab button. */
97
+ this.gridTitle = input('', /* @ts-ignore */
98
+ ...(ngDevMode ? [{ debugName: "gridTitle" }] : /* istanbul ignore next */ []));
99
+ /** Whether this item is currently expanded/selected. Set by parent. */
100
+ this.isExpanded = signal(false, /* @ts-ignore */
101
+ ...(ngDevMode ? [{ debugName: "isExpanded" }] : /* istanbul ignore next */ []));
102
+ /** Whether autoplay is active (controls loading bar animation). Set by parent. */
103
+ this.isAutoPlaying = signal(false, /* @ts-ignore */
104
+ ...(ngDevMode ? [{ debugName: "isAutoPlaying" }] : /* istanbul ignore next */ []));
105
+ /** The index of this item within the list. Set by parent. */
106
+ this.index = signal(0, /* @ts-ignore */
107
+ ...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
108
+ /** The generated ID for the tab button. Set by parent. */
109
+ this.tabId = signal('', /* @ts-ignore */
110
+ ...(ngDevMode ? [{ debugName: "tabId" }] : /* istanbul ignore next */ []));
111
+ /** The ID of the controlled tabpanel. Set by parent. */
112
+ this.panelId = signal('', /* @ts-ignore */
113
+ ...(ngDevMode ? [{ debugName: "panelId" }] : /* istanbul ignore next */ []));
114
+ /** Emitted when the item's button is clicked. */
115
+ this.itemClick = output();
116
+ /** Emitted when the loading bar animation ends. */
117
+ this.loadingBarAnimationEnd = output();
118
+ /** Reference to the projected picture element for cloning into carousel. */
119
+ this.pictureRef = contentChild(EclStoryCardPictureDirective, { ...(ngDevMode ? { debugName: "pictureRef" } : /* istanbul ignore next */ {}), read: ElementRef });
120
+ this.cssClasses = computed(() => [
121
+ super.getCssClasses('ecl-story-card__grid-item'),
122
+ this.isExpanded() ? 'ecl-story-card__grid-item--expanded' : '',
123
+ ].join(' ').trim(), /* @ts-ignore */
124
+ ...(ngDevMode ? [{ debugName: "cssClasses" }] : /* istanbul ignore next */ []));
125
+ }
126
+ onButtonClick() {
127
+ this.itemClick.emit(this.index());
128
+ }
129
+ onAnimationEnd() {
130
+ this.loadingBarAnimationEnd.emit();
131
+ }
132
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
133
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: EclStoryCardItemComponent, isStandalone: true, selector: "li[eclStoryCardItem]", inputs: { gridTitle: { classPropertyName: "gridTitle", publicName: "gridTitle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick", loadingBarAnimationEnd: "loadingBarAnimationEnd" }, host: { attributes: { "role": "presentation" }, properties: { "class": "cssClasses()" } }, queries: [{ propertyName: "pictureRef", first: true, predicate: EclStoryCardPictureDirective, descendants: true, read: ElementRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<button class=\"ecl-story-card__grid-card\"\n type=\"button\"\n [attr.id]=\"tabId()\"\n role=\"tab\"\n [attr.aria-selected]=\"isExpanded()\"\n [attr.aria-controls]=\"panelId()\"\n (click)=\"onButtonClick()\">\n <div class=\"ecl-story-card__grid-image\">\n <ng-content select=\"picture[eclStoryCardPicture]\"></ng-content>\n <div class=\"ecl-story-card__grid-loading-bar\">\n <div class=\"ecl-story-card__grid-loading-bar-completion\"\n [class.is-paused]=\"!isExpanded() || !isAutoPlaying()\"\n (animationend)=\"onAnimationEnd()\">\n </div>\n </div>\n </div>\n <div class=\"ecl-story-card__grid-title-wrapper\">\n @if (gridTitle()) {\n <div class=\"ecl-story-card__grid-title\">{{ gridTitle() }}</div>\n }\n </div>\n</button>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
134
+ }
135
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardItemComponent, decorators: [{
136
+ type: Component,
137
+ args: [{ selector: 'li[eclStoryCardItem]', host: {
138
+ role: 'presentation',
139
+ '[class]': 'cssClasses()',
140
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<button class=\"ecl-story-card__grid-card\"\n type=\"button\"\n [attr.id]=\"tabId()\"\n role=\"tab\"\n [attr.aria-selected]=\"isExpanded()\"\n [attr.aria-controls]=\"panelId()\"\n (click)=\"onButtonClick()\">\n <div class=\"ecl-story-card__grid-image\">\n <ng-content select=\"picture[eclStoryCardPicture]\"></ng-content>\n <div class=\"ecl-story-card__grid-loading-bar\">\n <div class=\"ecl-story-card__grid-loading-bar-completion\"\n [class.is-paused]=\"!isExpanded() || !isAutoPlaying()\"\n (animationend)=\"onAnimationEnd()\">\n </div>\n </div>\n </div>\n <div class=\"ecl-story-card__grid-title-wrapper\">\n @if (gridTitle()) {\n <div class=\"ecl-story-card__grid-title\">{{ gridTitle() }}</div>\n }\n </div>\n</button>\n" }]
141
+ }], propDecorators: { gridTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridTitle", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }], loadingBarAnimationEnd: [{ type: i0.Output, args: ["loadingBarAnimationEnd"] }], pictureRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => EclStoryCardPictureDirective), { ...{ read: ElementRef }, isSignal: true }] }] } });
142
+
143
+ /**
144
+ * Component for a story card grid details panel (tabpanel).
145
+ * Contains the expanded content: title, description, and optional link.
146
+ *
147
+ * For the 'testimonial' variant, additional inputs are available:
148
+ * - `author`: name of the author
149
+ * - `role`: role/position of the author
150
+ * - `source`: publication source
151
+ *
152
+ * @example
153
+ * <div eclStoryCardGridDetails
154
+ * eclTitle="The European flag..."
155
+ * description="It appears on official documents..."
156
+ * author="John Doe"
157
+ * role="Commissioner"
158
+ * source="Published on The Guardian">
159
+ * <a eclStoryCardLink eclLink variant="standalone" href="/example">
160
+ * <span eclLinkLabel>Read more</span>
161
+ * <ecl-icon icon="arrow-right" size="xs"></ecl-icon>
162
+ * </a>
163
+ * </div>
164
+ */
165
+ class EclStoryCardGridDetailsComponent extends ECLBaseDirective {
166
+ constructor() {
167
+ super(...arguments);
168
+ /** Title shown in the details panel. */
169
+ this.eclTitle = input('', /* @ts-ignore */
170
+ ...(ngDevMode ? [{ debugName: "eclTitle" }] : /* istanbul ignore next */ []));
171
+ /** Description shown in the details panel. */
172
+ this.description = input('', /* @ts-ignore */
173
+ ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
174
+ /** Author name (testimonial variant). */
175
+ this.author = input('', /* @ts-ignore */
176
+ ...(ngDevMode ? [{ debugName: "author" }] : /* istanbul ignore next */ []));
177
+ /** Author role/position (testimonial variant). */
178
+ this.role = input('', /* @ts-ignore */
179
+ ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
180
+ /** Publication source (testimonial variant). */
181
+ this.source = input('', /* @ts-ignore */
182
+ ...(ngDevMode ? [{ debugName: "source" }] : /* istanbul ignore next */ []));
183
+ /** Whether this panel is currently visible. Set by parent. */
184
+ this.isActive = signal(false, /* @ts-ignore */
185
+ ...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
186
+ /** Whether the parent is in testimonial variant. Set by parent. */
187
+ this.isTestimonial = signal(false, /* @ts-ignore */
188
+ ...(ngDevMode ? [{ debugName: "isTestimonial" }] : /* istanbul ignore next */ []));
189
+ /** Index of this panel. Set by parent. */
190
+ this.index = signal(0, /* @ts-ignore */
191
+ ...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
192
+ /** Generated panel ID. Set by parent. */
193
+ this.panelId = signal('', /* @ts-ignore */
194
+ ...(ngDevMode ? [{ debugName: "panelId" }] : /* istanbul ignore next */ []));
195
+ /** ID of the controlling tab. Set by parent. */
196
+ this.tabId = signal('', /* @ts-ignore */
197
+ ...(ngDevMode ? [{ debugName: "tabId" }] : /* istanbul ignore next */ []));
198
+ /** Reference to the projected link element for cloning into carousel. */
199
+ this.linkRef = contentChild(EclStoryCardLinkDirective, { ...(ngDevMode ? { debugName: "linkRef" } : /* istanbul ignore next */ {}), read: ElementRef });
200
+ }
201
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardGridDetailsComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
202
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: EclStoryCardGridDetailsComponent, isStandalone: true, selector: "[eclStoryCardGridDetails]", inputs: { eclTitle: { classPropertyName: "eclTitle", publicName: "eclTitle", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, author: { classPropertyName: "author", publicName: "author", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "getCssClasses(\"ecl-story-card__grid-details\")", "attr.id": "panelId()", "attr.role": "\"tabpanel\"", "attr.aria-labelledby": "tabId()", "hidden": "!isActive()" } }, queries: [{ propertyName: "linkRef", first: true, predicate: EclStoryCardLinkDirective, descendants: true, read: ElementRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<article class=\"ecl-story-card__grid-details-content\">\n <div class=\"ecl-story-card__content\">\n @if (isTestimonial()) {\n <div class=\"ecl-story-card__content-icon\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"45\" viewBox=\"0 0 22 45\" fill=\"none\">\n <path d=\"M0 0H22V23.3143L0 44.5714V0Z\" fill=\"currentColor\"/>\n </svg>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"45\" viewBox=\"0 0 22 45\" fill=\"none\">\n <path d=\"M0 0H22V23.3143L0 44.5714V0Z\" fill=\"currentColor\"/>\n </svg>\n </div>\n }\n @if (eclTitle()) {\n <div class=\"ecl-story-card__card-title\">{{ eclTitle() }}</div>\n }\n @if (author() || role() || source()) {\n <div class=\"ecl-story-card__testimonial\">\n @if (author()) {\n <span class=\"ecl-story-card__author\">{{ author() }}</span>\n }\n @if (role()) {\n <span class=\"ecl-story-card__role\">{{ role() }}</span>\n }\n @if (source()) {\n <cite class=\"ecl-story-card__source\">{{ source() }}</cite>\n }\n </div>\n }\n @if (description()) {\n <div class=\"ecl-story-card__card-description\">{{ description() }}</div>\n }\n <ng-content select=\"[eclStoryCardLink]\"></ng-content>\n </div>\n</article>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
203
+ }
204
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardGridDetailsComponent, decorators: [{
205
+ type: Component,
206
+ args: [{ selector: '[eclStoryCardGridDetails]', host: {
207
+ '[class]': 'getCssClasses("ecl-story-card__grid-details")',
208
+ '[attr.id]': 'panelId()',
209
+ '[attr.role]': '"tabpanel"',
210
+ '[attr.aria-labelledby]': 'tabId()',
211
+ '[hidden]': '!isActive()',
212
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<article class=\"ecl-story-card__grid-details-content\">\n <div class=\"ecl-story-card__content\">\n @if (isTestimonial()) {\n <div class=\"ecl-story-card__content-icon\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"45\" viewBox=\"0 0 22 45\" fill=\"none\">\n <path d=\"M0 0H22V23.3143L0 44.5714V0Z\" fill=\"currentColor\"/>\n </svg>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"45\" viewBox=\"0 0 22 45\" fill=\"none\">\n <path d=\"M0 0H22V23.3143L0 44.5714V0Z\" fill=\"currentColor\"/>\n </svg>\n </div>\n }\n @if (eclTitle()) {\n <div class=\"ecl-story-card__card-title\">{{ eclTitle() }}</div>\n }\n @if (author() || role() || source()) {\n <div class=\"ecl-story-card__testimonial\">\n @if (author()) {\n <span class=\"ecl-story-card__author\">{{ author() }}</span>\n }\n @if (role()) {\n <span class=\"ecl-story-card__role\">{{ role() }}</span>\n }\n @if (source()) {\n <cite class=\"ecl-story-card__source\">{{ source() }}</cite>\n }\n </div>\n }\n @if (description()) {\n <div class=\"ecl-story-card__card-description\">{{ description() }}</div>\n }\n <ng-content select=\"[eclStoryCardLink]\"></ng-content>\n </div>\n</article>\n" }]
213
+ }], propDecorators: { eclTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "eclTitle", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], author: [{ type: i0.Input, args: [{ isSignal: true, alias: "author", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: false }] }], linkRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => EclStoryCardLinkDirective), { ...{ read: ElementRef }, isSignal: true }] }] } });
214
+
215
+ /**
216
+ * ECL Story Card component.
217
+ *
218
+ * Renders a desktop grid accordion (user-authored) and automatically
219
+ * generates a mobile carousel from the same data.
220
+ *
221
+ * Desktop: tablist/tab/tabpanel pattern with autoplay loading bar.
222
+ * Mobile: Embla carousel with prev/next and dot navigation.
223
+ *
224
+ * @example
225
+ * <section eclStoryCard isAutoplay [autoplayDelay]="10000"
226
+ * [eclTitle]="'Stories'" [eclDescription]="'...'">
227
+ * <ul eclStoryCardList>
228
+ * <li eclStoryCardItem gridTitle="why twelve">
229
+ * <picture eclStoryCardPicture>...</picture>
230
+ * </li>
231
+ * </ul>
232
+ * <div eclStoryCardGridDetails eclTitle="..." description="...">
233
+ * <a eclStoryCardLink href="...">Read more</a>
234
+ * </div>
235
+ * </section>
236
+ */
237
+ class EclStoryCardComponent extends ECLBaseDirective {
238
+ constructor() {
239
+ super();
240
+ /** Title displayed in the story card header. */
241
+ this.eclTitle = input('', /* @ts-ignore */
242
+ ...(ngDevMode ? [{ debugName: "eclTitle" }] : /* istanbul ignore next */ []));
243
+ /** Description displayed below the title. */
244
+ this.eclDescription = input('', /* @ts-ignore */
245
+ ...(ngDevMode ? [{ debugName: "eclDescription" }] : /* istanbul ignore next */ []));
246
+ /** Variant of the story card: 'story' (default) or 'testimonial'. */
247
+ this.variant = input('story', /* @ts-ignore */
248
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
249
+ /** Whether autoplay is enabled for the grid accordion. */
250
+ this.isAutoplay = input(false, { ...(ngDevMode ? { debugName: "isAutoplay" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
251
+ /** Autoplay delay in milliseconds. Default: 10000. */
252
+ this.autoplayDelay = input(10000, /* @ts-ignore */
253
+ ...(ngDevMode ? [{ debugName: "autoplayDelay" }] : /* istanbul ignore next */ []));
254
+ /** ID for the component. All internal IDs derive from it. If not provided, auto-generated. */
255
+ this.eclId = input('', { ...(ngDevMode ? { debugName: "eclId" } : /* istanbul ignore next */ {}), alias: 'id' });
256
+ /** Emitted when the active grid item changes. */
257
+ this.selectionChange = output();
258
+ this.generatedId = `story-card-${crypto.randomUUID().slice(0, 8)}`;
259
+ this.componentId = computed(() => this.eclId() || this.generatedId, /* @ts-ignore */
260
+ ...(ngDevMode ? [{ debugName: "componentId" }] : /* istanbul ignore next */ []));
261
+ this.titleId = computed(() => `${this.componentId()}-title`, /* @ts-ignore */
262
+ ...(ngDevMode ? [{ debugName: "titleId" }] : /* istanbul ignore next */ []));
263
+ /** Embla carousel options. */
264
+ this.emblaOptions = { loop: true, direction: 'ltr' };
265
+ /** Subscribed Embla events. */
266
+ this.subscribeToEvents = ['select', 'init', 'reInit'];
267
+ /** Current carousel snap index. */
268
+ this.activeSlideIndex = signal(0, /* @ts-ignore */
269
+ ...(ngDevMode ? [{ debugName: "activeSlideIndex" }] : /* istanbul ignore next */ []));
270
+ /** Total number of items. */
271
+ this.totalSlides = computed(() => this.items().length, /* @ts-ignore */
272
+ ...(ngDevMode ? [{ debugName: "totalSlides" }] : /* istanbul ignore next */ []));
273
+ /** Previous button disabled state (carousel). */
274
+ this.prevDisabled = signal(false, /* @ts-ignore */
275
+ ...(ngDevMode ? [{ debugName: "prevDisabled" }] : /* istanbul ignore next */ []));
276
+ /** Next button disabled state (carousel). */
277
+ this.nextDisabled = signal(false, /* @ts-ignore */
278
+ ...(ngDevMode ? [{ debugName: "nextDisabled" }] : /* istanbul ignore next */ []));
279
+ /** Currently expanded grid item index. */
280
+ this.expandedIndex = signal(0, /* @ts-ignore */
281
+ ...(ngDevMode ? [{ debugName: "expandedIndex" }] : /* istanbul ignore next */ []));
282
+ /** Whether grid autoplay is currently playing. */
283
+ this.isAutoPlaying = signal(false, /* @ts-ignore */
284
+ ...(ngDevMode ? [{ debugName: "isAutoPlaying" }] : /* istanbul ignore next */ []));
285
+ this.items = contentChildren(EclStoryCardItemComponent, { ...(ngDevMode ? { debugName: "items" } : /* istanbul ignore next */ {}), descendants: true });
286
+ this.detailsPanels = contentChildren(EclStoryCardGridDetailsComponent, { ...(ngDevMode ? { debugName: "detailsPanels" } : /* istanbul ignore next */ {}), descendants: true });
287
+ this.emblaRef = viewChild(EmblaCarouselDirective, /* @ts-ignore */
288
+ ...(ngDevMode ? [{ debugName: "emblaRef" }] : /* istanbul ignore next */ []));
289
+ this.carouselImageWrappers = viewChildren('carouselImageWrapper', /* @ts-ignore */
290
+ ...(ngDevMode ? [{ debugName: "carouselImageWrappers" }] : /* istanbul ignore next */ []));
291
+ this.carouselContentWrappers = viewChildren('carouselContentWrapper', /* @ts-ignore */
292
+ ...(ngDevMode ? [{ debugName: "carouselContentWrappers" }] : /* istanbul ignore next */ []));
293
+ this.cd = inject(ChangeDetectorRef);
294
+ this.eclRtlService = inject(EclRtlService);
295
+ this.destroy$ = new Subject();
296
+ this.setupTeardown$ = new Subject();
297
+ this.cssClasses = computed(() => [
298
+ super.getCssClasses('ecl-story-card'),
299
+ this.eclDescription() ? 'ecl-story-card--has-description' : '',
300
+ this.variant() === 'testimonial' ? 'ecl-story-card--testimonial' : '',
301
+ ].join(' ').trim(), /* @ts-ignore */
302
+ ...(ngDevMode ? [{ debugName: "cssClasses" }] : /* istanbul ignore next */ []));
303
+ this.slideDuration = computed(() => `${this.autoplayDelay()}ms`, /* @ts-ignore */
304
+ ...(ngDevMode ? [{ debugName: "slideDuration" }] : /* istanbul ignore next */ []));
305
+ afterNextRender(() => {
306
+ setTimeout(() => this.clonePicturesToCarousel());
307
+ });
308
+ effect(() => {
309
+ const itemsArray = this.items();
310
+ const detailsArray = this.detailsPanels();
311
+ untracked(() => {
312
+ this.setupGrid(itemsArray, detailsArray);
313
+ });
314
+ }, { allowSignalWrites: true });
315
+ this.eclRtlService.currentRtlState$.pipe(takeUntil(this.destroy$)).subscribe((isRtl) => {
316
+ const direction = isRtl ? 'rtl' : 'ltr';
317
+ if (this.emblaOptions.direction !== direction) {
318
+ this.emblaOptions = { ...this.emblaOptions, direction };
319
+ this.cd.detectChanges();
320
+ }
321
+ });
322
+ }
323
+ ngOnDestroy() {
324
+ this.setupTeardown$.next();
325
+ this.setupTeardown$.complete();
326
+ this.destroy$.next();
327
+ this.destroy$.complete();
328
+ }
329
+ /**
330
+ * Configures the grid accordion: assigns IDs, indices, and initial state
331
+ * to each item and details panel, subscribes to item interaction events,
332
+ * and starts autoplay if enabled.
333
+ */
334
+ setupGrid(itemsArray, detailsArray) {
335
+ this.setupTeardown$.next();
336
+ const id = this.componentId();
337
+ itemsArray.forEach((item, i) => {
338
+ item.index.set(i);
339
+ item.tabId.set(`${id}-tab-${i}`);
340
+ item.panelId.set(`${id}-details-${i}`);
341
+ item.isExpanded.set(i === this.expandedIndex());
342
+ item.isAutoPlaying.set(this.isAutoPlaying());
343
+ outputToObservable(item.itemClick).pipe(takeUntil(this.setupTeardown$)).subscribe((index) => this.onGridItemClick(index));
344
+ outputToObservable(item.loadingBarAnimationEnd).pipe(takeUntil(this.setupTeardown$)).subscribe(() => this.onLoadingBarAnimationEnd());
345
+ });
346
+ detailsArray.forEach((panel, i) => {
347
+ panel.index.set(i);
348
+ panel.panelId.set(`${id}-details-${i}`);
349
+ panel.tabId.set(`${id}-tab-${i}`);
350
+ panel.isActive.set(i === this.expandedIndex());
351
+ panel.isTestimonial.set(this.variant() === 'testimonial');
352
+ });
353
+ if (this.isAutoplay()) {
354
+ this.playAutoplay();
355
+ }
356
+ }
357
+ /** Set the expanded grid item by index. */
358
+ setGridItem(index) {
359
+ const itemsArray = this.items();
360
+ const detailsArray = this.detailsPanels();
361
+ if (itemsArray.length === 0)
362
+ return;
363
+ const nextIndex = ((index % itemsArray.length) + itemsArray.length) % itemsArray.length;
364
+ itemsArray.forEach((item, i) => {
365
+ item.isExpanded.set(i === nextIndex);
366
+ item.isAutoPlaying.set(this.isAutoPlaying());
367
+ });
368
+ detailsArray.forEach((panel, i) => {
369
+ panel.isActive.set(i === nextIndex);
370
+ });
371
+ this.expandedIndex.set(nextIndex);
372
+ this.selectionChange.emit({ index: nextIndex });
373
+ }
374
+ /** Handle click on a grid item button. */
375
+ onGridItemClick(index) {
376
+ const itemsArray = this.items();
377
+ const isCurrentlyExpanded = itemsArray[index]?.isExpanded();
378
+ if (isCurrentlyExpanded && !this.isAutoPlaying()) {
379
+ this.playAutoplay();
380
+ }
381
+ else {
382
+ this.pauseAutoplay();
383
+ }
384
+ this.setGridItem(index);
385
+ }
386
+ /** Go to the previous grid item. */
387
+ onGridPrevClick() {
388
+ this.setGridItem(this.expandedIndex() - 1);
389
+ }
390
+ /** Go to the next grid item. */
391
+ onGridNextClick() {
392
+ this.setGridItem(this.expandedIndex() + 1);
393
+ }
394
+ /** Handle animation end on the loading bar (advance to next). */
395
+ onLoadingBarAnimationEnd() {
396
+ if (this.isAutoPlaying()) {
397
+ this.setGridItem(this.expandedIndex() + 1);
398
+ }
399
+ }
400
+ /** Start autoplay. */
401
+ playAutoplay() {
402
+ if (this.items().length < 2)
403
+ return;
404
+ this.isAutoPlaying.set(true);
405
+ this.items().forEach(item => item.isAutoPlaying.set(true));
406
+ }
407
+ pauseAutoplay() {
408
+ this.isAutoPlaying.set(false);
409
+ this.items().forEach(item => item.isAutoPlaying.set(false));
410
+ }
411
+ /** Play button click. */
412
+ onPlayClick() {
413
+ this.playAutoplay();
414
+ }
415
+ /** Pause button click. */
416
+ onPauseClick() {
417
+ this.pauseAutoplay();
418
+ }
419
+ /** Clone each item's projected picture and link into the corresponding carousel slide. */
420
+ clonePicturesToCarousel() {
421
+ const imageWrappers = this.carouselImageWrappers();
422
+ const contentWrappers = this.carouselContentWrappers();
423
+ const itemsArray = this.items();
424
+ const detailsArray = this.detailsPanels();
425
+ itemsArray.forEach((item, i) => {
426
+ const pictureEl = item.pictureRef();
427
+ if (pictureEl && imageWrappers[i]) {
428
+ const clone = pictureEl.nativeElement.cloneNode(true);
429
+ imageWrappers[i].nativeElement.appendChild(clone);
430
+ }
431
+ });
432
+ detailsArray.forEach((panel, i) => {
433
+ const linkEl = panel.linkRef();
434
+ if (linkEl && contentWrappers[i]) {
435
+ const clone = linkEl.nativeElement.cloneNode(true);
436
+ contentWrappers[i].nativeElement.appendChild(clone);
437
+ }
438
+ });
439
+ }
440
+ onEmblaChange(eventName) {
441
+ if (!this.emblaApi) {
442
+ this.emblaApi = this.emblaRef()?.emblaApi;
443
+ }
444
+ if (!this.emblaApi)
445
+ return;
446
+ if (eventName === 'select' || eventName === 'init' || eventName === 'reInit') {
447
+ this.syncCarouselState();
448
+ }
449
+ }
450
+ /** Sync carousel state from Embla API. */
451
+ syncCarouselState() {
452
+ if (!this.emblaApi)
453
+ return;
454
+ this.activeSlideIndex.set(this.emblaApi.selectedScrollSnap());
455
+ this.prevDisabled.set(!this.emblaApi.canScrollPrev());
456
+ this.nextDisabled.set(!this.emblaApi.canScrollNext());
457
+ }
458
+ /** Navigate carousel to previous slide. */
459
+ onCarouselPrevClick() {
460
+ this.emblaRef()?.scrollPrev();
461
+ }
462
+ /** Navigate carousel to next slide. */
463
+ onCarouselNextClick() {
464
+ this.emblaRef()?.scrollNext();
465
+ }
466
+ /** Navigate carousel to a specific slide. */
467
+ goToSlide(index) {
468
+ this.emblaRef()?.scrollTo(index);
469
+ }
470
+ /** Returns dot indices for rendering. */
471
+ getDotIndices() {
472
+ return Array.from({ length: this.totalSlides() }, (_, i) => i);
473
+ }
474
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
475
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: EclStoryCardComponent, isStandalone: true, selector: "section[eclStoryCard]", inputs: { eclTitle: { classPropertyName: "eclTitle", publicName: "eclTitle", isSignal: true, isRequired: false, transformFunction: null }, eclDescription: { classPropertyName: "eclDescription", publicName: "eclDescription", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, isAutoplay: { classPropertyName: "isAutoplay", publicName: "isAutoplay", isSignal: true, isRequired: false, transformFunction: null }, autoplayDelay: { classPropertyName: "autoplayDelay", publicName: "autoplayDelay", isSignal: true, isRequired: false, transformFunction: null }, eclId: { classPropertyName: "eclId", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { properties: { "id": "componentId()", "class": "cssClasses()", "attr.aria-labelledby": "titleId()", "style.--ecl-story-card-slide-duration": "slideDuration()" } }, queries: [{ propertyName: "items", predicate: EclStoryCardItemComponent, descendants: true, isSignal: true }, { propertyName: "detailsPanels", predicate: EclStoryCardGridDetailsComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "emblaRef", first: true, predicate: EmblaCarouselDirective, descendants: true, isSignal: true }, { propertyName: "carouselImageWrappers", predicate: ["carouselImageWrapper"], descendants: true, isSignal: true }, { propertyName: "carouselContentWrappers", predicate: ["carouselContentWrapper"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (eclTitle() || eclDescription()) {\n<div class=\"ecl-story-card__header\">\n @if (eclTitle()) {\n <div class=\"ecl-story-card__title\" [attr.id]=\"titleId()\">{{ eclTitle() }}</div>\n }\n @if (eclDescription()) {\n <div class=\"ecl-story-card__description\">{{ eclDescription() }}</div>\n }\n</div>\n}\n\n<!-- Mobile: Embla Carousel (auto-generated from items + details) -->\n<div class=\"ecl-story-card__carousel\">\n <div class=\"ecl-story-card__carousel-viewport\"\n role=\"region\"\n [attr.aria-label]=\"'ecl.story-card.SLIDER-LABEL' | translate\"\n emblaCarousel\n [options]=\"emblaOptions\"\n [subscribeToEvents]=\"subscribeToEvents\"\n (emblaChange)=\"onEmblaChange($event)\">\n <ul class=\"ecl-story-card__carousel-container\">\n @for (item of items(); track i; let i = $index) {\n <li class=\"ecl-story-card__carousel-slide\"\n [attr.aria-hidden]=\"i !== activeSlideIndex() ? true : null\">\n <article class=\"ecl-story-card__card\">\n <div class=\"ecl-story-card__image-wrapper\" #carouselImageWrapper>\n </div>\n <div class=\"ecl-story-card__content\" #carouselContentWrapper>\n @if (detailsPanels()[i]; as panel) {\n @if (panel.eclTitle()) {\n <div class=\"ecl-story-card__card-title\">{{ panel.eclTitle() }}</div>\n }\n @if (panel.description()) {\n <div class=\"ecl-story-card__card-description\">{{ panel.description() }}</div>\n }\n }\n </div>\n </article>\n </li>\n }\n </ul>\n </div>\n\n <!-- Carousel Controls -->\n @if (totalSlides() > 1) {\n <div class=\"ecl-story-card__pager\">\n <button class=\"ecl-story-card__prev\"\n [disabled]=\"prevDisabled()\"\n (click)=\"onCarouselPrevClick()\"\n [attr.aria-label]=\"'ecl.story-card.SHOW-PREV-SLIDE' | translate\">\n <ecl-icon icon=\"corner-arrow\" size=\"s\" transform=\"rotate-270\"></ecl-icon>\n <span class=\"ecl-story-card__prev-label\">\n {{ 'ecl.story-card.PREVIOUS' | translate }}\n </span>\n </button>\n\n <div class=\"ecl-story-card__dots\">\n @for (dotIndex of getDotIndices(); track dotIndex) {\n <button\n #dotButton\n class=\"ecl-story-card__dot\"\n [class.ecl-story-card__dot--active]=\"dotIndex === activeSlideIndex()\"\n [class.is-prev]=\"dotIndex === activeSlideIndex() - 1\"\n [attr.aria-label]=\"'ecl.story-card.GO-TO-SLIDE' | translate: { current: dotIndex + 1, total: totalSlides() }\"\n (click)=\"goToSlide(dotIndex)\">\n </button>\n }\n </div>\n\n <button class=\"ecl-story-card__next\"\n [disabled]=\"nextDisabled()\"\n (click)=\"onCarouselNextClick()\"\n [attr.aria-label]=\"'ecl.story-card.SHOW-NEXT-SLIDE' | translate\">\n <span class=\"ecl-story-card__next-label\">\n {{ 'ecl.story-card.NEXT' | translate }}\n </span>\n <ecl-icon icon=\"corner-arrow\" size=\"s\" transform=\"rotate-90\"></ecl-icon>\n </button>\n </div>\n }\n</div>\n\n<!-- Desktop: Grid with Accordion (user-authored content projected here) -->\n<div class=\"ecl-story-card__grid\">\n <ng-content select=\"ul[eclStoryCardList]\"></ng-content>\n <ng-content select=\"[eclStoryCardGridDetails]\"></ng-content>\n\n <!-- Grid Controls -->\n @if (totalSlides() > 1) {\n <div class=\"ecl-story-card__grid-controls\">\n <button class=\"ecl-button ecl-button--tertiary ecl-button--neutral ecl-story-card__grid-prev ecl-button--icon-only\"\n type=\"button\"\n (click)=\"onGridPrevClick()\"\n [attr.aria-label]=\"'ecl.story-card.PREVIOUS' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.PREVIOUS' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor\" icon=\"caret-left\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--secondary ecl-button--neutral ecl-story-card__grid-play ecl-button--icon-only\"\n type=\"button\"\n [style.display]=\"isAutoPlaying() ? 'none' : 'flex'\"\n (click)=\"onPlayClick()\"\n [attr.aria-label]=\"'ecl.story-card.PLAY' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.PLAY' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor-fill\" icon=\"play\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--secondary ecl-button--neutral ecl-story-card__grid-pause ecl-button--icon-only\"\n type=\"button\"\n [style.display]=\"isAutoPlaying() ? 'flex' : 'none'\"\n (click)=\"onPauseClick()\"\n [attr.aria-label]=\"'ecl.story-card.PAUSE' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.PAUSE' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor-fill\" icon=\"pause\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--tertiary ecl-button--neutral ecl-story-card__grid-next ecl-button--icon-only\"\n type=\"button\"\n (click)=\"onGridNextClick()\"\n [attr.aria-label]=\"'ecl.story-card.NEXT' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.NEXT' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor\" icon=\"caret-right\" size=\"l\"></ecl-icon>\n </span>\n </button>\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: EclIconComponent, selector: "ecl-icon", inputs: ["iconSet", "icon", "size", "color", "transform", "ariaLabelledby", "role", "title", "ariaHidden", "focusable", "isFlipHorizontal"] }, { kind: "directive", type: EmblaCarouselDirective, selector: "[emblaCarousel]", inputs: ["options", "plugins", "subscribeToEvents", "eventsThrottleTime"], outputs: ["emblaChange"], exportAs: ["emblaCarousel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
476
+ }
477
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EclStoryCardComponent, decorators: [{
478
+ type: Component,
479
+ args: [{ selector: 'section[eclStoryCard]', host: {
480
+ '[id]': 'componentId()',
481
+ '[class]': 'cssClasses()',
482
+ '[attr.aria-labelledby]': 'titleId()',
483
+ '[style.--ecl-story-card-slide-duration]': 'slideDuration()',
484
+ }, imports: [
485
+ TranslatePipe,
486
+ EclIconComponent,
487
+ EmblaCarouselDirective,
488
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (eclTitle() || eclDescription()) {\n<div class=\"ecl-story-card__header\">\n @if (eclTitle()) {\n <div class=\"ecl-story-card__title\" [attr.id]=\"titleId()\">{{ eclTitle() }}</div>\n }\n @if (eclDescription()) {\n <div class=\"ecl-story-card__description\">{{ eclDescription() }}</div>\n }\n</div>\n}\n\n<!-- Mobile: Embla Carousel (auto-generated from items + details) -->\n<div class=\"ecl-story-card__carousel\">\n <div class=\"ecl-story-card__carousel-viewport\"\n role=\"region\"\n [attr.aria-label]=\"'ecl.story-card.SLIDER-LABEL' | translate\"\n emblaCarousel\n [options]=\"emblaOptions\"\n [subscribeToEvents]=\"subscribeToEvents\"\n (emblaChange)=\"onEmblaChange($event)\">\n <ul class=\"ecl-story-card__carousel-container\">\n @for (item of items(); track i; let i = $index) {\n <li class=\"ecl-story-card__carousel-slide\"\n [attr.aria-hidden]=\"i !== activeSlideIndex() ? true : null\">\n <article class=\"ecl-story-card__card\">\n <div class=\"ecl-story-card__image-wrapper\" #carouselImageWrapper>\n </div>\n <div class=\"ecl-story-card__content\" #carouselContentWrapper>\n @if (detailsPanels()[i]; as panel) {\n @if (panel.eclTitle()) {\n <div class=\"ecl-story-card__card-title\">{{ panel.eclTitle() }}</div>\n }\n @if (panel.description()) {\n <div class=\"ecl-story-card__card-description\">{{ panel.description() }}</div>\n }\n }\n </div>\n </article>\n </li>\n }\n </ul>\n </div>\n\n <!-- Carousel Controls -->\n @if (totalSlides() > 1) {\n <div class=\"ecl-story-card__pager\">\n <button class=\"ecl-story-card__prev\"\n [disabled]=\"prevDisabled()\"\n (click)=\"onCarouselPrevClick()\"\n [attr.aria-label]=\"'ecl.story-card.SHOW-PREV-SLIDE' | translate\">\n <ecl-icon icon=\"corner-arrow\" size=\"s\" transform=\"rotate-270\"></ecl-icon>\n <span class=\"ecl-story-card__prev-label\">\n {{ 'ecl.story-card.PREVIOUS' | translate }}\n </span>\n </button>\n\n <div class=\"ecl-story-card__dots\">\n @for (dotIndex of getDotIndices(); track dotIndex) {\n <button\n #dotButton\n class=\"ecl-story-card__dot\"\n [class.ecl-story-card__dot--active]=\"dotIndex === activeSlideIndex()\"\n [class.is-prev]=\"dotIndex === activeSlideIndex() - 1\"\n [attr.aria-label]=\"'ecl.story-card.GO-TO-SLIDE' | translate: { current: dotIndex + 1, total: totalSlides() }\"\n (click)=\"goToSlide(dotIndex)\">\n </button>\n }\n </div>\n\n <button class=\"ecl-story-card__next\"\n [disabled]=\"nextDisabled()\"\n (click)=\"onCarouselNextClick()\"\n [attr.aria-label]=\"'ecl.story-card.SHOW-NEXT-SLIDE' | translate\">\n <span class=\"ecl-story-card__next-label\">\n {{ 'ecl.story-card.NEXT' | translate }}\n </span>\n <ecl-icon icon=\"corner-arrow\" size=\"s\" transform=\"rotate-90\"></ecl-icon>\n </button>\n </div>\n }\n</div>\n\n<!-- Desktop: Grid with Accordion (user-authored content projected here) -->\n<div class=\"ecl-story-card__grid\">\n <ng-content select=\"ul[eclStoryCardList]\"></ng-content>\n <ng-content select=\"[eclStoryCardGridDetails]\"></ng-content>\n\n <!-- Grid Controls -->\n @if (totalSlides() > 1) {\n <div class=\"ecl-story-card__grid-controls\">\n <button class=\"ecl-button ecl-button--tertiary ecl-button--neutral ecl-story-card__grid-prev ecl-button--icon-only\"\n type=\"button\"\n (click)=\"onGridPrevClick()\"\n [attr.aria-label]=\"'ecl.story-card.PREVIOUS' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.PREVIOUS' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor\" icon=\"caret-left\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--secondary ecl-button--neutral ecl-story-card__grid-play ecl-button--icon-only\"\n type=\"button\"\n [style.display]=\"isAutoPlaying() ? 'none' : 'flex'\"\n (click)=\"onPlayClick()\"\n [attr.aria-label]=\"'ecl.story-card.PLAY' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.PLAY' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor-fill\" icon=\"play\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--secondary ecl-button--neutral ecl-story-card__grid-pause ecl-button--icon-only\"\n type=\"button\"\n [style.display]=\"isAutoPlaying() ? 'flex' : 'none'\"\n (click)=\"onPauseClick()\"\n [attr.aria-label]=\"'ecl.story-card.PAUSE' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.PAUSE' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor-fill\" icon=\"pause\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--tertiary ecl-button--neutral ecl-story-card__grid-next ecl-button--icon-only\"\n type=\"button\"\n (click)=\"onGridNextClick()\"\n [attr.aria-label]=\"'ecl.story-card.NEXT' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.NEXT' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor\" icon=\"caret-right\" size=\"l\"></ecl-icon>\n </span>\n </button>\n </div>\n }\n</div>\n" }]
489
+ }], ctorParameters: () => [], propDecorators: { eclTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "eclTitle", required: false }] }], eclDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "eclDescription", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], isAutoplay: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAutoplay", required: false }] }], autoplayDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoplayDelay", required: false }] }], eclId: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => EclStoryCardItemComponent), { ...{ descendants: true }, isSignal: true }] }], detailsPanels: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => EclStoryCardGridDetailsComponent), { ...{ descendants: true }, isSignal: true }] }], emblaRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => EmblaCarouselDirective), { isSignal: true }] }], carouselImageWrappers: [{ type: i0.ViewChildren, args: ['carouselImageWrapper', { isSignal: true }] }], carouselContentWrappers: [{ type: i0.ViewChildren, args: ['carouselContentWrapper', { isSignal: true }] }] } });
490
+
491
+ const EUI_ECL_STORY_CARD = [
492
+ EclStoryCardComponent,
493
+ EclStoryCardItemComponent,
494
+ EclStoryCardGridDetailsComponent,
495
+ EclStoryCardListDirective,
496
+ EclStoryCardPictureDirective,
497
+ EclStoryCardLinkDirective,
498
+ ];
499
+
500
+ /**
501
+ * Generated bundle index. Do not edit.
502
+ */
503
+
504
+ export { EUI_ECL_STORY_CARD, EclStoryCardComponent, EclStoryCardGridDetailsComponent, EclStoryCardItemComponent, EclStoryCardLinkDirective, EclStoryCardListDirective, EclStoryCardPictureDirective };
505
+ //# sourceMappingURL=eui-ecl-components-ecl-story-card.mjs.map