@eui/ecl 21.0.0-alpha.3 → 21.0.0-alpha.31

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 (631) hide show
  1. package/assets/i18n-ecl/bg.json +1 -0
  2. package/assets/i18n-ecl/cs.json +1 -0
  3. package/assets/i18n-ecl/da.json +1 -0
  4. package/assets/i18n-ecl/de.json +1 -0
  5. package/assets/i18n-ecl/el.json +1 -0
  6. package/assets/i18n-ecl/en.json +1 -0
  7. package/assets/i18n-ecl/es.json +1 -0
  8. package/assets/i18n-ecl/et.json +1 -0
  9. package/assets/i18n-ecl/fi.json +1 -0
  10. package/assets/i18n-ecl/fr.json +1 -0
  11. package/assets/i18n-ecl/ga.json +1 -0
  12. package/assets/i18n-ecl/hr.json +1 -0
  13. package/assets/i18n-ecl/hu.json +1 -0
  14. package/assets/i18n-ecl/it.json +1 -0
  15. package/assets/i18n-ecl/lt.json +1 -0
  16. package/assets/i18n-ecl/lv.json +1 -0
  17. package/assets/i18n-ecl/mt.json +1 -0
  18. package/assets/i18n-ecl/nl.json +1 -0
  19. package/assets/i18n-ecl/pl.json +1 -0
  20. package/assets/i18n-ecl/pt.json +1 -0
  21. package/assets/i18n-ecl/ro.json +1 -0
  22. package/assets/i18n-ecl/sk.json +1 -0
  23. package/assets/i18n-ecl/sl.json +1 -0
  24. package/assets/i18n-ecl/sv.json +1 -0
  25. package/components/ecl-banner/index.d.ts +13 -4
  26. package/components/ecl-banner/index.d.ts.map +1 -1
  27. package/components/ecl-carousel/index.d.ts +1 -0
  28. package/components/ecl-carousel/index.d.ts.map +1 -1
  29. package/components/ecl-featured/index.d.ts +1 -1
  30. package/components/ecl-featured/index.d.ts.map +1 -1
  31. package/components/ecl-gallery/index.d.ts +1 -1
  32. package/components/ecl-gallery/index.d.ts.map +1 -1
  33. package/components/ecl-link/index.d.ts +6 -6
  34. package/components/ecl-link/index.d.ts.map +1 -1
  35. package/components/ecl-mega-menu/index.d.ts +2 -1
  36. package/components/ecl-mega-menu/index.d.ts.map +1 -1
  37. package/components/ecl-menu/index.d.ts +7 -1
  38. package/components/ecl-menu/index.d.ts.map +1 -1
  39. package/components/ecl-multiselect/index.d.ts +2 -2
  40. package/components/ecl-pagination/index.d.ts +1 -0
  41. package/components/ecl-pagination/index.d.ts.map +1 -1
  42. package/components/ecl-popover/index.d.ts +1 -1
  43. package/components/ecl-popover/index.d.ts.map +1 -1
  44. package/components/ecl-site-footer/index.d.ts +55 -32
  45. package/components/ecl-site-footer/index.d.ts.map +1 -1
  46. package/components/ecl-site-header/index.d.ts +1 -3
  47. package/components/ecl-site-header/index.d.ts.map +1 -1
  48. package/components/ecl-social-media-follow/index.d.ts +3 -1
  49. package/components/ecl-social-media-follow/index.d.ts.map +1 -1
  50. package/components/ecl-tabs/index.d.ts +5 -1
  51. package/components/ecl-tabs/index.d.ts.map +1 -1
  52. package/core/index.d.ts +7 -1
  53. package/core/index.d.ts.map +1 -1
  54. package/docs/changelog.html +427 -7760
  55. package/docs/classes/EclAccordionToggleEvent.html +18 -0
  56. package/docs/classes/EclAppLanguageDismissEvent.html +18 -0
  57. package/docs/classes/EclAreaChangeEvent.html +18 -0
  58. package/docs/classes/EclBaseEvent.html +18 -0
  59. package/docs/classes/EclBreadcrumbSegmentClickEvent.html +18 -0
  60. package/docs/classes/EclCategoryFilterItemSelectEvent.html +18 -0
  61. package/docs/classes/EclDatePickerDatePickedEvent.html +18 -0
  62. package/docs/classes/EclDomEvent.html +18 -0
  63. package/docs/classes/EclExpandableToggleEvent.html +18 -0
  64. package/docs/classes/EclFileItemsToggleEvent.html +18 -0
  65. package/docs/classes/EclFileUploadFileSelectedEvent.html +18 -0
  66. package/docs/classes/EclGalleryFullScreenEvent.html +18 -0
  67. package/docs/classes/EclGalleryHideEvent.html +18 -0
  68. package/docs/classes/EclGalleryItemClickEvent.html +18 -0
  69. package/docs/classes/EclGalleryItemEvent.html +18 -0
  70. package/docs/classes/EclGalleryMediaSource.html +18 -0
  71. package/docs/classes/EclGalleryMediaTrack.html +18 -0
  72. package/docs/classes/EclGalleryPictureImage.html +18 -0
  73. package/docs/classes/EclGalleryPictureSource.html +18 -0
  74. package/docs/classes/EclGalleryShareEvent.html +18 -0
  75. package/docs/classes/EclGalleryShowEvent.html +18 -0
  76. package/docs/classes/EclGalleryToggleItemsEvent.html +18 -0
  77. package/docs/classes/EclInpageNavigationItemClickEvent.html +18 -0
  78. package/docs/classes/EclInpageNavigationSectionEnterEvent.html +18 -0
  79. package/docs/classes/EclLanguageService.html +18 -0
  80. package/docs/classes/EclMenuItemCaretEvent.html +18 -0
  81. package/docs/classes/EclMenuItemFocusEvent.html +18 -0
  82. package/docs/classes/EclMenuItemHoverEvent.html +18 -0
  83. package/docs/classes/EclMenuItemHoverOutEvent.html +18 -0
  84. package/docs/classes/EclMenuItemKeydownEvent.html +18 -0
  85. package/docs/classes/EclMenuItemParentFocusEvent.html +18 -0
  86. package/docs/classes/EclMenuItemSelectEvent.html +18 -0
  87. package/docs/classes/EclModalCloseEvent.html +18 -0
  88. package/docs/classes/EclModalOpenEvent.html +18 -0
  89. package/docs/classes/EclMultiselectMainInputClickEvent.html +18 -0
  90. package/docs/classes/EclMultiselectOptionClickEvent.html +18 -0
  91. package/docs/classes/EclMultiselectOptionKeydownEvent.html +18 -0
  92. package/docs/classes/EclNewsTickerItemEvent.html +18 -0
  93. package/docs/classes/EclNotificationCloseEvent.html +18 -0
  94. package/docs/classes/EclPaginationEvent.html +18 -0
  95. package/docs/classes/EclPaginationItemClickEvent.html +18 -0
  96. package/docs/classes/EclRangeEvent.html +18 -0
  97. package/docs/classes/EclRatingChangeEvent.html +18 -0
  98. package/docs/classes/EclSearchFormEvent.html +18 -0
  99. package/docs/classes/EclSiteHeaderLanguageClickEvent.html +18 -0
  100. package/docs/classes/EclSiteHeaderLanguageCloseEvent.html +18 -0
  101. package/docs/classes/EclSiteHeaderLanguageSelectedEvent.html +18 -0
  102. package/docs/classes/EclSiteHeaderLoginBoxToggleEvent.html +18 -0
  103. package/docs/classes/EclSiteHeaderLoginEvent.html +18 -0
  104. package/docs/classes/EclSiteHeaderLogoClickEvent.html +18 -0
  105. package/docs/classes/EclSiteHeaderSearchEvent.html +18 -0
  106. package/docs/classes/EclSiteHeaderSearchToggleEvent.html +18 -0
  107. package/docs/classes/EclSlideEvent.html +18 -0
  108. package/docs/classes/EclSocialMediaFollowItemClickEvent.html +18 -0
  109. package/docs/classes/EclSocialMediaShareItemClickEvent.html +18 -0
  110. package/docs/classes/EclSortTableEvent.html +18 -0
  111. package/docs/classes/EclTabSelectEvent.html +18 -0
  112. package/docs/classes/EclTagRemoveEvent.html +18 -0
  113. package/docs/classes/EclTimelineItemToggleEvent.html +18 -0
  114. package/docs/components/EclAccordionComponent.html +21 -3
  115. package/docs/components/EclAccordionItemComponent.html +22 -4
  116. package/docs/components/EclAppComponent.html +20 -2
  117. package/docs/components/EclBannerComponent.html +136 -6
  118. package/docs/components/EclBlockquoteComponent.html +20 -2
  119. package/docs/components/EclBreadcrumbComponent.html +22 -9
  120. package/docs/components/EclBreadcrumbSegmentComponent.html +24 -5
  121. package/docs/components/EclButtonComponent.html +21 -3
  122. package/docs/components/EclCardBodyComponent.html +20 -2
  123. package/docs/components/EclCardComponent.html +20 -2
  124. package/docs/components/EclCarouselComponent.html +101 -2
  125. package/docs/components/EclCarouselItemComponent.html +20 -2
  126. package/docs/components/EclCategoryFilterComponent.html +20 -2
  127. package/docs/components/EclCategoryFilterItemComponent.html +21 -3
  128. package/docs/components/EclCategoryFilterListComponent.html +20 -2
  129. package/docs/components/EclCheckboxHelpComponent.html +20 -2
  130. package/docs/components/EclCheckboxLabelComponent.html +21 -3
  131. package/docs/components/EclContentBlockComponent.html +20 -2
  132. package/docs/components/EclContentItemComponent.html +20 -2
  133. package/docs/components/EclDateBlockComponent.html +20 -2
  134. package/docs/components/EclDescriptionListDefinitionComponent.html +21 -3
  135. package/docs/components/EclExpandableComponent.html +22 -4
  136. package/docs/components/EclFactFiguresComponent.html +20 -2
  137. package/docs/components/EclFactFiguresDescriptionComponent.html +20 -2
  138. package/docs/components/EclFactFiguresItemComponent.html +20 -2
  139. package/docs/components/EclFactFiguresTitleComponent.html +20 -2
  140. package/docs/components/EclFactFiguresValueComponent.html +20 -2
  141. package/docs/components/EclFactFiguresViewAllComponent.html +20 -2
  142. package/docs/components/EclFeaturedComponent.html +20 -2
  143. package/docs/components/EclFeaturedItemComponent.html +20 -2
  144. package/docs/components/EclFeaturedItemDescriptionComponent.html +20 -2
  145. package/docs/components/EclFeaturedItemFooterComponent.html +20 -2
  146. package/docs/components/EclFileComponent.html +22 -4
  147. package/docs/components/EclFileItemComponent.html +20 -2
  148. package/docs/components/EclFileItemsComponent.html +22 -4
  149. package/docs/components/EclFileTaxonomyComponent.html +20 -2
  150. package/docs/components/EclFormGroupComponent.html +20 -2
  151. package/docs/components/EclFormLabelComponent.html +20 -2
  152. package/docs/components/EclGalleryComponent.html +27 -48
  153. package/docs/components/EclGalleryFooterComponent.html +21 -3
  154. package/docs/components/EclGalleryItemComponent.html +21 -3
  155. package/docs/components/EclIconComponent.html +20 -2
  156. package/docs/components/EclInpageNavigationComponent.html +21 -3
  157. package/docs/components/EclInpageNavigationItemComponent.html +21 -3
  158. package/docs/components/EclListIllustrationComponent.html +20 -2
  159. package/docs/components/EclListIllustrationItemComponent.html +20 -2
  160. package/docs/components/EclLoadingIndicatorComponent.html +20 -2
  161. package/docs/components/EclMediaContainerComponent.html +22 -4
  162. package/docs/components/EclMegaMenuComponent.html +47 -25
  163. package/docs/components/EclMegaMenuFeaturedComponent.html +20 -2
  164. package/docs/components/EclMegaMenuInfoComponent.html +20 -2
  165. package/docs/components/EclMegaMenuItemComponent.html +25 -6
  166. package/docs/components/EclMegaMenuSubitemComponent.html +25 -6
  167. package/docs/components/EclMenuComponent.html +195 -37
  168. package/docs/components/EclMenuItemComponent.html +25 -6
  169. package/docs/components/EclMenuMegaComponent.html +20 -2
  170. package/docs/components/EclMenuMegaItemComponent.html +21 -3
  171. package/docs/components/EclModalBodyComponent.html +20 -2
  172. package/docs/components/EclModalComponent.html +20 -2
  173. package/docs/components/EclModalFooterComponent.html +20 -2
  174. package/docs/components/EclModalHeaderComponent.html +22 -4
  175. package/docs/components/EclMultiselectComponent.html +21 -5
  176. package/docs/components/EclMultiselectDropdownComponent.html +26 -45
  177. package/docs/components/EclMultiselectInputComponent.html +22 -4
  178. package/docs/components/EclMultiselectOptgroupComponent.html +20 -2
  179. package/docs/components/EclMultiselectOptionComponent.html +20 -2
  180. package/docs/components/EclNavigationListComponent.html +20 -2
  181. package/docs/components/EclNavigationListItemComponent.html +20 -2
  182. package/docs/components/EclNewsTickerComponent.html +22 -4
  183. package/docs/components/EclNewsTickerItemComponent.html +20 -2
  184. package/docs/components/EclNotificationComponent.html +22 -4
  185. package/docs/components/EclPageHeaderComponent.html +20 -2
  186. package/docs/components/EclPaginationComponent.html +20 -2
  187. package/docs/components/EclPaginationItemComponent.html +50 -6
  188. package/docs/components/EclPopoverComponent.html +27 -54
  189. package/docs/components/EclRadioHelpComponent.html +20 -2
  190. package/docs/components/EclRadioLabelComponent.html +20 -2
  191. package/docs/components/EclRangeBubbleComponent.html +20 -2
  192. package/docs/components/EclRangeValueComponent.html +20 -2
  193. package/docs/components/EclRatingFieldComponent.html +21 -3
  194. package/docs/components/EclSearchFormComponent.html +22 -4
  195. package/docs/components/EclSelectContainerComponent.html +22 -4
  196. package/docs/components/EclSiteFooterComponent.html +65 -5
  197. package/docs/components/EclSiteFooterCoreComponent.html +575 -0
  198. package/docs/components/EclSiteFooterFixedContentEUComponent.html +21 -3
  199. package/docs/components/EclSiteFooterRowCommonComponent.html +647 -0
  200. package/docs/components/EclSiteHeaderActionComponent.html +20 -2
  201. package/docs/components/EclSiteHeaderBannerTopComponent.html +20 -2
  202. package/docs/components/EclSiteHeaderComponent.html +22 -4
  203. package/docs/components/EclSiteHeaderCustomActionComponent.html +22 -4
  204. package/docs/components/EclSiteHeaderEnvironmentComponent.html +20 -2
  205. package/docs/components/EclSiteHeaderLanguageComponent.html +21 -3
  206. package/docs/components/EclSiteHeaderLanguagePopoverComponent.html +24 -11
  207. package/docs/components/EclSiteHeaderLoginComponent.html +21 -3
  208. package/docs/components/EclSiteHeaderNotificationComponent.html +20 -2
  209. package/docs/components/EclSiteHeaderSearchComponent.html +22 -4
  210. package/docs/components/EclSocialMediaFollowComponent.html +20 -2
  211. package/docs/components/EclSocialMediaFollowItemComponent.html +38 -6
  212. package/docs/components/EclSocialMediaShareComponent.html +20 -2
  213. package/docs/components/EclSocialMediaShareItemComponent.html +22 -4
  214. package/docs/components/EclSplashPageComponent.html +20 -2
  215. package/docs/components/EclSplashPageLanguageCategoryComponent.html +20 -2
  216. package/docs/components/EclSplashPageLanguageContainerComponent.html +20 -2
  217. package/docs/components/EclSplashPageLanguageLinkComponent.html +20 -2
  218. package/docs/components/EclStickyContainerComponent.html +20 -2
  219. package/docs/components/EclTabComponent.html +47 -4
  220. package/docs/components/EclTabLabelComponent.html +20 -2
  221. package/docs/components/EclTabMoreComponent.html +20 -2
  222. package/docs/components/EclTableSortButtonComponent.html +21 -3
  223. package/docs/components/EclTabsComponent.html +22 -4
  224. package/docs/components/EclTagComponent.html +21 -3
  225. package/docs/components/EclTimelineComponent.html +20 -2
  226. package/docs/components/EclTimelineItemComponent.html +22 -4
  227. package/docs/components/EclTimelineItemTogglerComponent.html +20 -2
  228. package/docs/dependencies.html +18 -0
  229. package/docs/directives/ECLBaseDirective.html +18 -0
  230. package/docs/directives/ECLClickOutsideDirective.html +18 -0
  231. package/docs/directives/ECLFormLabelOptionalDirective.html +18 -0
  232. package/docs/directives/EclBannerDescriptionDirective.html +18 -0
  233. package/docs/directives/EclBannerDescriptionLinkDirective.html +18 -0
  234. package/docs/directives/EclBannerDescriptionTextDirective.html +18 -0
  235. package/docs/directives/EclBannerImageDirective.html +18 -0
  236. package/docs/directives/EclBannerPictureDirective.html +18 -0
  237. package/docs/directives/EclBannerTitleDirective.html +18 -0
  238. package/docs/directives/EclBannerTitleLinkDirective.html +18 -0
  239. package/docs/directives/EclBannerTitleTextDirective.html +18 -0
  240. package/docs/directives/EclBannerVideoDirective.html +18 -0
  241. package/docs/directives/EclBlockquoteImageDirective.html +18 -0
  242. package/docs/directives/EclBlockquotePictureDirective.html +18 -0
  243. package/docs/directives/EclBreadcrumbContainerDirective.html +18 -0
  244. package/docs/directives/EclButtonIconContainerDirective.html +18 -0
  245. package/docs/directives/EclButtonLabelDirective.html +18 -0
  246. package/docs/directives/EclCardImageDirective.html +18 -0
  247. package/docs/directives/EclCardPictureDirective.html +18 -0
  248. package/docs/directives/EclCheckboxDirective.html +18 -0
  249. package/docs/directives/EclCheckboxInputDirective.html +18 -0
  250. package/docs/directives/EclContentBlockDescriptionDirective.html +18 -0
  251. package/docs/directives/EclContentBlockLabelDirective.html +18 -0
  252. package/docs/directives/EclContentBlockLabelsDirective.html +18 -0
  253. package/docs/directives/EclContentBlockLinkDirective.html +18 -0
  254. package/docs/directives/EclContentBlockLinksContainerDirective.html +18 -0
  255. package/docs/directives/EclContentBlockLinksDirective.html +18 -0
  256. package/docs/directives/EclContentBlockListContainerDirective.html +18 -0
  257. package/docs/directives/EclContentBlockListDirective.html +18 -0
  258. package/docs/directives/EclContentBlockPrimaryMetaDirective.html +18 -0
  259. package/docs/directives/EclContentBlockPrimaryMetasDirective.html +18 -0
  260. package/docs/directives/EclContentBlockSecondaryMetaDirective.html +18 -0
  261. package/docs/directives/EclContentBlockSecondaryMetaIconDirective.html +18 -0
  262. package/docs/directives/EclContentBlockSecondaryMetaLabelDirective.html +18 -0
  263. package/docs/directives/EclContentBlockSecondaryMetasDirective.html +18 -0
  264. package/docs/directives/EclContentBlockTagDirective.html +18 -0
  265. package/docs/directives/EclContentBlockTagsDirective.html +18 -0
  266. package/docs/directives/EclContentBlockTitleDirective.html +18 -0
  267. package/docs/directives/EclContentItemImageDirective.html +18 -0
  268. package/docs/directives/EclContentItemPictureDirective.html +18 -0
  269. package/docs/directives/EclDatePickerDirective.html +18 -0
  270. package/docs/directives/EclDescriptionListDefinitionItemDirective.html +18 -0
  271. package/docs/directives/EclDescriptionListDefinitionListDirective.html +18 -0
  272. package/docs/directives/EclDescriptionListDirective.html +18 -0
  273. package/docs/directives/EclDescriptionListTermDirective.html +18 -0
  274. package/docs/directives/EclFeaturedItemFooterLinkDirective.html +18 -0
  275. package/docs/directives/EclFeaturedItemFooterPictureDirective.html +18 -0
  276. package/docs/directives/EclFeaturedItemLinkDirective.html +18 -0
  277. package/docs/directives/EclFeedbackMessageDirective.html +18 -0
  278. package/docs/directives/EclFileDownloadDirective.html +18 -0
  279. package/docs/directives/EclFileImageDirective.html +18 -0
  280. package/docs/directives/EclFilePictureDirective.html +18 -0
  281. package/docs/directives/EclFilePreviewDirective.html +18 -0
  282. package/docs/directives/EclFileTitleDirective.html +18 -0
  283. package/docs/directives/EclFileTranslationDownloadDirective.html +18 -0
  284. package/docs/directives/EclFileUploadDirective.html +18 -0
  285. package/docs/directives/EclGalleryMediaDirective.html +18 -0
  286. package/docs/directives/EclGalleryPictureDirective.html +18 -0
  287. package/docs/directives/EclGalleryThumbnailDirective.html +18 -0
  288. package/docs/directives/EclHelpBlockDirective.html +18 -0
  289. package/docs/directives/EclHiddenDirective.html +18 -0
  290. package/docs/directives/EclIndicatorDirective.html +18 -0
  291. package/docs/directives/EclInpageNavigationListDirective.html +18 -0
  292. package/docs/directives/EclLabelDirective.html +18 -0
  293. package/docs/directives/EclLinkDirective.html +18 -0
  294. package/docs/directives/EclLinkIconContainerDirective.html +18 -0
  295. package/docs/directives/{EclIndicatorDirective-1.html → EclLinkIndicatorDirective.html} +20 -2
  296. package/docs/directives/EclLinkLabelDirective.html +18 -0
  297. package/docs/directives/EclListIllustrationIconDirective.html +18 -0
  298. package/docs/directives/EclListIllustrationImageDirective.html +18 -0
  299. package/docs/directives/EclListIllustrationPictureDirective.html +18 -0
  300. package/docs/directives/EclLoadingIndicatorLabelDirective.html +18 -0
  301. package/docs/directives/EclLoadingIndicatorOverlayDirective.html +18 -0
  302. package/docs/directives/EclMediaContainerIframeDirective.html +18 -0
  303. package/docs/directives/EclMediaContainerItemAudioDescriptionDirective.html +18 -0
  304. package/docs/directives/EclMediaContainerItemDirective.html +18 -0
  305. package/docs/directives/EclMediaContainerPictureDirective.html +18 -0
  306. package/docs/directives/EclMegaMenuContainerDirective.html +18 -0
  307. package/docs/directives/EclMegaMenuFeaturedImageDirective.html +18 -0
  308. package/docs/directives/EclMegaMenuFeaturedListDirective.html +18 -0
  309. package/docs/directives/EclMegaMenuFeaturedListItemDirective.html +18 -0
  310. package/docs/directives/EclMegaMenuFeaturedPictureDirective.html +18 -0
  311. package/docs/directives/EclMegaMenuListDirective.html +18 -0
  312. package/docs/directives/EclMegaMenuSpacerDirective.html +18 -0
  313. package/docs/directives/EclMegaMenuSublistDirective.html +18 -0
  314. package/docs/directives/EclModalBodyFixedContentDirective.html +18 -0
  315. package/docs/directives/EclModalCloseDirective.html +18 -0
  316. package/docs/directives/EclModalTriggerDirective.html +18 -0
  317. package/docs/directives/EclMultiselectOptionDirective.html +18 -0
  318. package/docs/directives/EclNavigationListImageDirective.html +18 -0
  319. package/docs/directives/EclNavigationListPictureDirective.html +18 -0
  320. package/docs/directives/EclNewsTickerIconDirective.html +18 -0
  321. package/docs/directives/EclNotificationTitleDirective.html +18 -0
  322. package/docs/directives/EclOrderedListDirective.html +18 -0
  323. package/docs/directives/EclOrderedListItemDirective.html +18 -0
  324. package/docs/directives/EclPageHeaderBackgroundImageDirective.html +18 -0
  325. package/docs/directives/EclPageHeaderBackgroundPictureDirective.html +18 -0
  326. package/docs/directives/EclPageHeaderDescriptionContainerDirective.html +18 -0
  327. package/docs/directives/EclPageHeaderDescriptionDirective.html +18 -0
  328. package/docs/directives/EclPageHeaderDescriptionPictureDirective.html +18 -0
  329. package/docs/directives/EclPageHeaderDescriptionThumbnailDirective.html +18 -0
  330. package/docs/directives/EclPageHeaderInfoDirective.html +18 -0
  331. package/docs/directives/EclPageHeaderMetaDirective.html +18 -0
  332. package/docs/directives/EclPageHeaderMetaItemDirective.html +18 -0
  333. package/docs/directives/EclPageHeaderTitleDirective.html +18 -0
  334. package/docs/directives/EclPaginationListDirective.html +18 -0
  335. package/docs/directives/EclPopoverContentDirective.html +18 -0
  336. package/docs/directives/EclPopoverToggleDirective.html +18 -0
  337. package/docs/directives/EclRadioDirective.html +18 -0
  338. package/docs/directives/EclRadioInputDirective.html +18 -0
  339. package/docs/directives/EclRangeDirective.html +20 -2
  340. package/docs/directives/EclSelectDirective.html +18 -0
  341. package/docs/directives/EclSeparatorDirective.html +18 -0
  342. package/docs/directives/EclSiteFooterColumnDirective.html +19 -1
  343. package/docs/directives/EclSiteFooterDescriptionDirective.html +18 -0
  344. package/docs/directives/EclSiteFooterLinkDirective.html +18 -0
  345. package/docs/directives/EclSiteFooterListDirective.html +18 -0
  346. package/docs/directives/EclSiteFooterListItemDirective.html +18 -0
  347. package/docs/directives/EclSiteFooterLogoDirective.html +18 -0
  348. package/docs/directives/EclSiteFooterLogoImageDirective.html +18 -0
  349. package/docs/directives/EclSiteFooterLogoItemDirective.html +18 -0
  350. package/docs/directives/EclSiteFooterLogoLinkDirective.html +18 -0
  351. package/docs/directives/EclSiteFooterLogoListDirective.html +18 -0
  352. package/docs/directives/EclSiteFooterPictureDirective.html +18 -0
  353. package/docs/directives/EclSiteFooterRowDirective.html +19 -1
  354. package/docs/directives/EclSiteFooterSectionDirective.html +359 -8
  355. package/docs/directives/{EclSiteFooterContentDirective.html → EclSiteFooterSocialMediaDirective.html} +28 -18
  356. package/docs/directives/EclSiteFooterTitleDirective.html +18 -0
  357. package/docs/directives/EclSiteFooterTitleLinkDirective.html +18 -0
  358. package/docs/directives/EclSiteHeaderCtaDirective.html +18 -0
  359. package/docs/directives/EclSiteHeaderCustomActionContentDirective.html +18 -0
  360. package/docs/directives/EclSiteHeaderCustomActionLinkDirective.html +18 -0
  361. package/docs/directives/EclSiteHeaderCustomActionTitleDirective.html +18 -0
  362. package/docs/directives/EclSiteHeaderImageDirective.html +18 -0
  363. package/docs/directives/EclSiteHeaderLinkDirective.html +18 -0
  364. package/docs/directives/EclSiteHeaderLoginDescriptionDirective.html +18 -0
  365. package/docs/directives/EclSiteHeaderLoginSeparatorDirective.html +18 -0
  366. package/docs/directives/EclSiteHeaderPictureDirective.html +18 -0
  367. package/docs/directives/EclSocialMediaFollowLinkDirective.html +18 -0
  368. package/docs/directives/EclSocialMediaShareLinkDirective.html +18 -0
  369. package/docs/directives/EclSplashPageLanguageItemDirective.html +18 -0
  370. package/docs/directives/EclSplashPageLanguageListDirective.html +18 -0
  371. package/docs/directives/EclSplashPageLogoImageDirective.html +18 -0
  372. package/docs/directives/EclSplashPageLogoLinkDirective.html +18 -0
  373. package/docs/directives/EclSplashPagePictureDirective.html +18 -0
  374. package/docs/directives/EclTableBodyDirective.html +18 -0
  375. package/docs/directives/EclTableCaptionDirective.html +18 -0
  376. package/docs/directives/EclTableCellDirective.html +18 -0
  377. package/docs/directives/EclTableCellGroupDirective.html +18 -0
  378. package/docs/directives/EclTableDirective.html +18 -0
  379. package/docs/directives/EclTableHeadDirective.html +18 -0
  380. package/docs/directives/EclTableHeaderDirective.html +18 -0
  381. package/docs/directives/EclTableResponsiveDirective.html +18 -0
  382. package/docs/directives/EclTableRowDirective.html +18 -0
  383. package/docs/directives/EclTagIconExternalDirective.html +18 -0
  384. package/docs/directives/EclTagSetDirective.html +18 -0
  385. package/docs/directives/EclTagSetItemDirective.html +18 -0
  386. package/docs/directives/EclTextAreaDirective.html +18 -0
  387. package/docs/directives/EclTextInputDirective.html +18 -0
  388. package/docs/directives/EclTimelineItemLabelDirective.html +18 -0
  389. package/docs/directives/EclTimelineItemTitleDirective.html +18 -0
  390. package/docs/directives/EclUnorderedListDirective.html +18 -0
  391. package/docs/directives/EclUnorderedListItemDirective.html +18 -0
  392. package/docs/index.html +20 -2
  393. package/docs/injectables/EclAreaDataService.html +18 -0
  394. package/docs/injectables/EclDefaultLanguageService.html +18 -0
  395. package/docs/injectables/EclHeaderMenuComunicationService.html +18 -0
  396. package/docs/injectables/EclInpageNavigationService.html +18 -0
  397. package/docs/injectables/EclMegaMenuDataService.html +18 -0
  398. package/docs/injectables/EclMegaMenuService.html +18 -0
  399. package/docs/injectables/EclRtlService.html +18 -0
  400. package/docs/injectables/EclThemeService.html +18 -0
  401. package/docs/injectables/EclUserDeviceService.html +18 -0
  402. package/docs/interfaces/EclBreadcrumb.html +18 -0
  403. package/docs/interfaces/EclCarouselItem.html +18 -0
  404. package/docs/interfaces/EclCategoryFilterItem.html +18 -0
  405. package/docs/interfaces/EclFileUpload.html +18 -0
  406. package/docs/interfaces/EclGalleryItem.html +18 -0
  407. package/docs/interfaces/EclLanguage.html +18 -0
  408. package/docs/interfaces/EclMegaMenuItem.html +18 -0
  409. package/docs/interfaces/EclMenuItem.html +18 -0
  410. package/docs/interfaces/EclModalResult.html +18 -0
  411. package/docs/interfaces/EclMultiselectOption.html +18 -0
  412. package/docs/interfaces/EclTab.html +18 -0
  413. package/docs/js/libs/bootstrap-native.js +1 -1
  414. package/docs/js/libs/jszip.min.js +13 -0
  415. package/docs/js/libs/svg-pan-zoom.min.js +3 -3
  416. package/docs/js/libs/tablesort.min.js +3 -3
  417. package/docs/js/libs/tablesort.number.min.js +3 -3
  418. package/docs/js/menu-wc.js +55 -39
  419. package/docs/js/menu-wc_es5.js +1 -1
  420. package/docs/js/routes/routes_index.js +1 -0
  421. package/docs/js/routes.js +15 -8
  422. package/docs/js/search/search_index.js +2 -2
  423. package/docs/license.html +20 -2
  424. package/docs/miscellaneous/enumerations.html +18 -0
  425. package/docs/miscellaneous/functions.html +280 -0
  426. package/docs/miscellaneous/variables.html +155 -72
  427. package/docs/modules/EclAccordionModule.html +18 -0
  428. package/docs/modules/EclAllModule.html +27 -360
  429. package/docs/modules/EclAppModule.html +18 -0
  430. package/docs/modules/EclBannerModule.html +18 -0
  431. package/docs/modules/EclBlockquoteModule.html +18 -0
  432. package/docs/modules/EclBreadcrumbModule.html +18 -0
  433. package/docs/modules/EclButtonModule.html +18 -0
  434. package/docs/modules/EclCardModule.html +18 -0
  435. package/docs/modules/EclCarouselModule.html +18 -0
  436. package/docs/modules/EclCategoryFilterModule.html +18 -0
  437. package/docs/modules/EclCheckboxModule.html +18 -0
  438. package/docs/modules/EclContentBlockModule.html +18 -0
  439. package/docs/modules/EclContentItemModule.html +18 -0
  440. package/docs/modules/EclDateBlockModule.html +18 -0
  441. package/docs/modules/EclDatePickerModule.html +18 -0
  442. package/docs/modules/EclExpandableModule.html +18 -0
  443. package/docs/modules/EclFactFiguresModule.html +18 -0
  444. package/docs/modules/EclFeaturedModule.html +18 -0
  445. package/docs/modules/EclFeedbackMessageModule.html +18 -0
  446. package/docs/modules/EclFileModule.html +18 -0
  447. package/docs/modules/EclFileUploadModule.html +18 -0
  448. package/docs/modules/EclFormGroupModule.html +18 -0
  449. package/docs/modules/EclFormLabelModule.html +18 -0
  450. package/docs/modules/EclGalleryModule.html +18 -0
  451. package/docs/modules/EclHelpBlockModule.html +18 -0
  452. package/docs/modules/EclHiddenModule.html +18 -0
  453. package/docs/modules/EclIconModule.html +18 -0
  454. package/docs/modules/EclInpageNavigationModule.html +18 -0
  455. package/docs/modules/EclLabelModule.html +18 -0
  456. package/docs/modules/EclLinkModule.html +24 -3
  457. package/docs/modules/EclListIllustrationModule.html +18 -0
  458. package/docs/modules/EclListModule.html +18 -0
  459. package/docs/modules/EclLoadingIndicatorModule.html +18 -0
  460. package/docs/modules/EclMediaContainerModule.html +18 -0
  461. package/docs/modules/EclMegaMenuModule.html +18 -0
  462. package/docs/modules/EclMenuModule.html +18 -0
  463. package/docs/modules/EclModalModule.html +18 -0
  464. package/docs/modules/EclMultiselectModule.html +18 -0
  465. package/docs/modules/EclNavigationListModule.html +18 -0
  466. package/docs/modules/EclNewsTickerModule.html +18 -0
  467. package/docs/modules/EclNotificationModule.html +18 -0
  468. package/docs/modules/EclPageHeaderModule.html +18 -0
  469. package/docs/modules/EclPaginationModule.html +18 -0
  470. package/docs/modules/EclPopoverModule.html +18 -0
  471. package/docs/modules/EclRadioModule.html +18 -0
  472. package/docs/modules/EclRangeModule.html +18 -0
  473. package/docs/modules/EclRatingFieldModule.html +18 -0
  474. package/docs/modules/EclSearchFormModule.html +18 -0
  475. package/docs/modules/EclSelectModule.html +18 -0
  476. package/docs/modules/EclSeparatorModule.html +18 -0
  477. package/docs/modules/EclSiteFooterModule.html +18 -0
  478. package/docs/modules/EclSiteHeaderModule.html +18 -0
  479. package/docs/modules/EclSocialMediaFollowModule.html +18 -0
  480. package/docs/modules/EclSocialMediaShareModule.html +18 -0
  481. package/docs/modules/EclSplashPageModule.html +18 -0
  482. package/docs/modules/EclStickyContainerModule.html +18 -0
  483. package/docs/modules/EclTableModule.html +18 -0
  484. package/docs/modules/EclTabsModule.html +18 -0
  485. package/docs/modules/EclTagModule.html +18 -0
  486. package/docs/modules/EclTextAreaModule.html +18 -0
  487. package/docs/modules/EclTextInputModule.html +18 -0
  488. package/docs/modules/EclTimelineModule.html +18 -0
  489. package/docs/modules.html +18 -0
  490. package/docs/overview.html +29 -1
  491. package/docs/pipes/BoldTextPipe.html +18 -0
  492. package/docs/properties.html +19 -1
  493. package/docs/routes.html +204 -0
  494. package/docs/template-playground/default-templates.json +192 -0
  495. package/docs/template-playground/hbs-render.service.ts +212 -0
  496. package/docs/template-playground/main.ts +9 -0
  497. package/docs/template-playground/template-editor.service.ts +173 -0
  498. package/docs/template-playground/template-playground.component.ts +614 -0
  499. package/docs/template-playground/template-playground.module.ts +29 -0
  500. package/docs/template-playground/zip-export.service.ts +86 -0
  501. package/docs/template-playground-app/app.js +1389 -0
  502. package/docs/template-playground-app/index.html +462 -0
  503. package/fesm2022/eui-ecl-components-ecl-accordion.mjs +14 -14
  504. package/fesm2022/eui-ecl-components-ecl-accordion.mjs.map +1 -1
  505. package/fesm2022/eui-ecl-components-ecl-app.mjs +7 -7
  506. package/fesm2022/eui-ecl-components-ecl-app.mjs.map +1 -1
  507. package/fesm2022/eui-ecl-components-ecl-banner.mjs +109 -81
  508. package/fesm2022/eui-ecl-components-ecl-banner.mjs.map +1 -1
  509. package/fesm2022/eui-ecl-components-ecl-blockquote.mjs +13 -13
  510. package/fesm2022/eui-ecl-components-ecl-blockquote.mjs.map +1 -1
  511. package/fesm2022/eui-ecl-components-ecl-breadcrumb.mjs +22 -23
  512. package/fesm2022/eui-ecl-components-ecl-breadcrumb.mjs.map +1 -1
  513. package/fesm2022/eui-ecl-components-ecl-button.mjs +18 -18
  514. package/fesm2022/eui-ecl-components-ecl-button.mjs.map +1 -1
  515. package/fesm2022/eui-ecl-components-ecl-card.mjs +16 -16
  516. package/fesm2022/eui-ecl-components-ecl-card.mjs.map +1 -1
  517. package/fesm2022/eui-ecl-components-ecl-carousel.mjs +53 -31
  518. package/fesm2022/eui-ecl-components-ecl-carousel.mjs.map +1 -1
  519. package/fesm2022/eui-ecl-components-ecl-category-filter.mjs +15 -15
  520. package/fesm2022/eui-ecl-components-ecl-category-filter.mjs.map +1 -1
  521. package/fesm2022/eui-ecl-components-ecl-checkbox.mjs +18 -18
  522. package/fesm2022/eui-ecl-components-ecl-checkbox.mjs.map +1 -1
  523. package/fesm2022/eui-ecl-components-ecl-content-block.mjs +58 -58
  524. package/fesm2022/eui-ecl-components-ecl-content-block.mjs.map +1 -1
  525. package/fesm2022/eui-ecl-components-ecl-content-item.mjs +13 -13
  526. package/fesm2022/eui-ecl-components-ecl-content-item.mjs.map +1 -1
  527. package/fesm2022/eui-ecl-components-ecl-date-block.mjs +7 -7
  528. package/fesm2022/eui-ecl-components-ecl-date-block.mjs.map +1 -1
  529. package/fesm2022/eui-ecl-components-ecl-date-picker.mjs +7 -7
  530. package/fesm2022/eui-ecl-components-ecl-date-picker.mjs.map +1 -1
  531. package/fesm2022/eui-ecl-components-ecl-expandable.mjs +10 -10
  532. package/fesm2022/eui-ecl-components-ecl-expandable.mjs.map +1 -1
  533. package/fesm2022/eui-ecl-components-ecl-fact-figures.mjs +22 -22
  534. package/fesm2022/eui-ecl-components-ecl-fact-figures.mjs.map +1 -1
  535. package/fesm2022/eui-ecl-components-ecl-featured.mjs +28 -26
  536. package/fesm2022/eui-ecl-components-ecl-featured.mjs.map +1 -1
  537. package/fesm2022/eui-ecl-components-ecl-feedback-message.mjs +7 -7
  538. package/fesm2022/eui-ecl-components-ecl-feedback-message.mjs.map +1 -1
  539. package/fesm2022/eui-ecl-components-ecl-file-upload.mjs +7 -7
  540. package/fesm2022/eui-ecl-components-ecl-file-upload.mjs.map +1 -1
  541. package/fesm2022/eui-ecl-components-ecl-file.mjs +41 -43
  542. package/fesm2022/eui-ecl-components-ecl-file.mjs.map +1 -1
  543. package/fesm2022/eui-ecl-components-ecl-form-group.mjs +7 -7
  544. package/fesm2022/eui-ecl-components-ecl-form-group.mjs.map +1 -1
  545. package/fesm2022/eui-ecl-components-ecl-form-label.mjs +10 -10
  546. package/fesm2022/eui-ecl-components-ecl-form-label.mjs.map +1 -1
  547. package/fesm2022/eui-ecl-components-ecl-gallery.mjs +32 -30
  548. package/fesm2022/eui-ecl-components-ecl-gallery.mjs.map +1 -1
  549. package/fesm2022/eui-ecl-components-ecl-help-block.mjs +7 -7
  550. package/fesm2022/eui-ecl-components-ecl-help-block.mjs.map +1 -1
  551. package/fesm2022/eui-ecl-components-ecl-icon.mjs +7 -7
  552. package/fesm2022/eui-ecl-components-ecl-icon.mjs.map +1 -1
  553. package/fesm2022/eui-ecl-components-ecl-inpage-navigation.mjs +20 -20
  554. package/fesm2022/eui-ecl-components-ecl-inpage-navigation.mjs.map +1 -1
  555. package/fesm2022/eui-ecl-components-ecl-label.mjs +7 -7
  556. package/fesm2022/eui-ecl-components-ecl-label.mjs.map +1 -1
  557. package/fesm2022/eui-ecl-components-ecl-link.mjs +21 -21
  558. package/fesm2022/eui-ecl-components-ecl-link.mjs.map +1 -1
  559. package/fesm2022/eui-ecl-components-ecl-list-illustration.mjs +19 -19
  560. package/fesm2022/eui-ecl-components-ecl-list-illustration.mjs.map +1 -1
  561. package/fesm2022/eui-ecl-components-ecl-list.mjs +33 -33
  562. package/fesm2022/eui-ecl-components-ecl-list.mjs.map +1 -1
  563. package/fesm2022/eui-ecl-components-ecl-loading-indicator.mjs +13 -13
  564. package/fesm2022/eui-ecl-components-ecl-loading-indicator.mjs.map +1 -1
  565. package/fesm2022/eui-ecl-components-ecl-media-container.mjs +22 -22
  566. package/fesm2022/eui-ecl-components-ecl-media-container.mjs.map +1 -1
  567. package/fesm2022/eui-ecl-components-ecl-mega-menu.mjs +66 -64
  568. package/fesm2022/eui-ecl-components-ecl-mega-menu.mjs.map +1 -1
  569. package/fesm2022/eui-ecl-components-ecl-menu.mjs +54 -37
  570. package/fesm2022/eui-ecl-components-ecl-menu.mjs.map +1 -1
  571. package/fesm2022/eui-ecl-components-ecl-modal.mjs +29 -29
  572. package/fesm2022/eui-ecl-components-ecl-modal.mjs.map +1 -1
  573. package/fesm2022/eui-ecl-components-ecl-multiselect.mjs +34 -34
  574. package/fesm2022/eui-ecl-components-ecl-multiselect.mjs.map +1 -1
  575. package/fesm2022/eui-ecl-components-ecl-navigation-list.mjs +16 -16
  576. package/fesm2022/eui-ecl-components-ecl-navigation-list.mjs.map +1 -1
  577. package/fesm2022/eui-ecl-components-ecl-news-ticker.mjs +17 -17
  578. package/fesm2022/eui-ecl-components-ecl-news-ticker.mjs.map +1 -1
  579. package/fesm2022/eui-ecl-components-ecl-notification.mjs +14 -14
  580. package/fesm2022/eui-ecl-components-ecl-notification.mjs.map +1 -1
  581. package/fesm2022/eui-ecl-components-ecl-page-header.mjs +37 -37
  582. package/fesm2022/eui-ecl-components-ecl-page-header.mjs.map +1 -1
  583. package/fesm2022/eui-ecl-components-ecl-pagination.mjs +27 -21
  584. package/fesm2022/eui-ecl-components-ecl-pagination.mjs.map +1 -1
  585. package/fesm2022/eui-ecl-components-ecl-popover.mjs +21 -21
  586. package/fesm2022/eui-ecl-components-ecl-popover.mjs.map +1 -1
  587. package/fesm2022/eui-ecl-components-ecl-radio.mjs +16 -16
  588. package/fesm2022/eui-ecl-components-ecl-radio.mjs.map +1 -1
  589. package/fesm2022/eui-ecl-components-ecl-range.mjs +14 -14
  590. package/fesm2022/eui-ecl-components-ecl-range.mjs.map +1 -1
  591. package/fesm2022/eui-ecl-components-ecl-rating-field.mjs +9 -9
  592. package/fesm2022/eui-ecl-components-ecl-rating-field.mjs.map +1 -1
  593. package/fesm2022/eui-ecl-components-ecl-search-form.mjs +10 -10
  594. package/fesm2022/eui-ecl-components-ecl-search-form.mjs.map +1 -1
  595. package/fesm2022/eui-ecl-components-ecl-select.mjs +14 -14
  596. package/fesm2022/eui-ecl-components-ecl-select.mjs.map +1 -1
  597. package/fesm2022/eui-ecl-components-ecl-separator.mjs +7 -7
  598. package/fesm2022/eui-ecl-components-ecl-separator.mjs.map +1 -1
  599. package/fesm2022/eui-ecl-components-ecl-site-footer.mjs +273 -204
  600. package/fesm2022/eui-ecl-components-ecl-site-footer.mjs.map +1 -1
  601. package/fesm2022/eui-ecl-components-ecl-site-header.mjs +100 -106
  602. package/fesm2022/eui-ecl-components-ecl-site-header.mjs.map +1 -1
  603. package/fesm2022/eui-ecl-components-ecl-social-media-follow.mjs +21 -19
  604. package/fesm2022/eui-ecl-components-ecl-social-media-follow.mjs.map +1 -1
  605. package/fesm2022/eui-ecl-components-ecl-social-media-share.mjs +16 -16
  606. package/fesm2022/eui-ecl-components-ecl-social-media-share.mjs.map +1 -1
  607. package/fesm2022/eui-ecl-components-ecl-splash-page.mjs +31 -31
  608. package/fesm2022/eui-ecl-components-ecl-splash-page.mjs.map +1 -1
  609. package/fesm2022/eui-ecl-components-ecl-sticky-container.mjs +7 -7
  610. package/fesm2022/eui-ecl-components-ecl-sticky-container.mjs.map +1 -1
  611. package/fesm2022/eui-ecl-components-ecl-table.mjs +36 -36
  612. package/fesm2022/eui-ecl-components-ecl-table.mjs.map +1 -1
  613. package/fesm2022/eui-ecl-components-ecl-tabs.mjs +26 -24
  614. package/fesm2022/eui-ecl-components-ecl-tabs.mjs.map +1 -1
  615. package/fesm2022/eui-ecl-components-ecl-tag.mjs +18 -18
  616. package/fesm2022/eui-ecl-components-ecl-tag.mjs.map +1 -1
  617. package/fesm2022/eui-ecl-components-ecl-text-area.mjs +7 -7
  618. package/fesm2022/eui-ecl-components-ecl-text-area.mjs.map +1 -1
  619. package/fesm2022/eui-ecl-components-ecl-text-input.mjs +7 -7
  620. package/fesm2022/eui-ecl-components-ecl-text-input.mjs.map +1 -1
  621. package/fesm2022/eui-ecl-components-ecl-timeline.mjs +22 -22
  622. package/fesm2022/eui-ecl-components-ecl-timeline.mjs.map +1 -1
  623. package/fesm2022/eui-ecl-core.mjs +165 -151
  624. package/fesm2022/eui-ecl-core.mjs.map +1 -1
  625. package/fesm2022/eui-ecl-shared.mjs +3 -3
  626. package/fesm2022/eui-ecl-shared.mjs.map +1 -1
  627. package/fesm2022/eui-ecl.mjs +184 -304
  628. package/fesm2022/eui-ecl.mjs.map +1 -1
  629. package/index.d.ts +1 -1
  630. package/package.json +53 -54
  631. package/docs/components/EclSiteFooterFixedContentECComponent.html +0 -571
@@ -0,0 +1,1389 @@
1
+ /**
2
+ * Compodoc Template Playground Application
3
+ * Main JavaScript file that handles all playground functionality
4
+ */
5
+
6
+ class TemplatePlayground {
7
+ constructor() {
8
+ this.editor = null;
9
+ this.currentTemplate = null;
10
+ this.currentData = {};
11
+ this.originalData = {};
12
+ this.customVariables = {};
13
+ this.debounceTimer = null;
14
+ this.sessionId = null;
15
+
16
+ // Track last visited doc URL in the iframe
17
+ this.lastVisitedDocUrl = null;
18
+ window.addEventListener('message', (event) => {
19
+ if (event.data && event.data.type === 'compodoc-iframe-navigate') {
20
+ this.lastVisitedDocUrl = event.data.url;
21
+ // Optionally persist in sessionStorage
22
+ sessionStorage.setItem('compodocLastVisitedDocUrl', this.lastVisitedDocUrl);
23
+ }
24
+ });
25
+ // Restore from sessionStorage if available
26
+ const storedUrl = sessionStorage.getItem('compodocLastVisitedDocUrl');
27
+ if (storedUrl) {
28
+ this.lastVisitedDocUrl = storedUrl;
29
+ }
30
+
31
+ this.init();
32
+ }
33
+
34
+ async init() {
35
+ try {
36
+ // Check JSZip availability on startup
37
+ setTimeout(() => {
38
+ if (typeof JSZip !== 'undefined') {
39
+ console.log('✅ JSZip loaded successfully');
40
+ } else if (window.JSZipLoadError) {
41
+ console.error('❌ JSZip failed to load from all CDNs');
42
+ } else {
43
+ console.warn('⚠️ JSZip still loading...');
44
+ }
45
+ }, 2000);
46
+
47
+ // First create a session
48
+ await this.createSession();
49
+ await this.initializeMonacoEditor();
50
+ this.setupEventListeners();
51
+ this.setupResizer();
52
+ await this.loadTemplateList();
53
+ console.log('🎨 Template Playground initialized successfully');
54
+ } catch (error) {
55
+ console.error('Failed to initialize Template Playground:', error);
56
+ this.showError('Failed to initialize editor. Please refresh the page.');
57
+ }
58
+ }
59
+
60
+ async createSession() {
61
+ try {
62
+ const response = await fetch('/api/session/create', {
63
+ method: 'POST',
64
+ headers: {
65
+ 'Content-Type': 'application/json'
66
+ }
67
+ });
68
+
69
+ if (!response.ok) {
70
+ throw new Error('Failed to create session');
71
+ }
72
+
73
+ const result = await response.json();
74
+ this.sessionId = result.sessionId;
75
+ console.log('Session created:', this.sessionId);
76
+ } catch (error) {
77
+ console.error('Error creating session:', error);
78
+ throw error;
79
+ }
80
+ }
81
+
82
+ async loadTemplateList() {
83
+ try {
84
+ const response = await fetch(`/api/session/${this.sessionId}/templates`);
85
+ if (!response.ok) {
86
+ throw new Error('Failed to load templates');
87
+ }
88
+
89
+ const result = await response.json();
90
+ const templates = result.templates;
91
+
92
+ // Update the template dropdown
93
+ const dropdown = document.getElementById('templateSelect');
94
+ if (dropdown) {
95
+ dropdown.innerHTML = '<option value="">Select a template...</option>';
96
+
97
+ // Group templates by type
98
+ const mainTemplates = templates.filter(t => t.type === 'template');
99
+ const partials = templates.filter(t => t.type === 'partial');
100
+
101
+ if (mainTemplates.length > 0) {
102
+ const mainGroup = document.createElement('optgroup');
103
+ mainGroup.label = 'Main Templates';
104
+ mainTemplates.forEach(template => {
105
+ const option = document.createElement('option');
106
+ option.value = template.path;
107
+ option.textContent = template.name;
108
+ mainGroup.appendChild(option);
109
+ });
110
+ dropdown.appendChild(mainGroup);
111
+ }
112
+
113
+ if (partials.length > 0) {
114
+ const partialsGroup = document.createElement('optgroup');
115
+ partialsGroup.label = 'Partials';
116
+ partials.forEach(template => {
117
+ const option = document.createElement('option');
118
+ option.value = template.path;
119
+ option.textContent = template.name;
120
+ partialsGroup.appendChild(option);
121
+ });
122
+ dropdown.appendChild(partialsGroup);
123
+ }
124
+ }
125
+ } catch (error) {
126
+ console.error('Error loading template list:', error);
127
+ this.showError('Failed to load template list');
128
+ }
129
+ }
130
+
131
+ async initializeMonacoEditor() {
132
+ return new Promise((resolve, reject) => {
133
+ require.config({ paths: { 'vs': 'https://cdn.jsdelivr.net/npm/monaco-editor@0.45.0/min/vs' }});
134
+
135
+ require(['vs/editor/editor.main'], () => {
136
+ try {
137
+ // Register Handlebars language
138
+ monaco.languages.register({ id: 'handlebars' });
139
+
140
+ // Define Handlebars syntax highlighting
141
+ monaco.languages.setMonarchTokensProvider('handlebars', {
142
+ tokenizer: {
143
+ root: [
144
+ [/\{\{\{.*?\}\}\}/, 'string.html'],
145
+ [/\{\{.*?\}\}/, 'keyword'],
146
+ [/<[^>]+>/, 'tag'],
147
+ [/<!--.*?-->/, 'comment'],
148
+ [/"[^"]*"/, 'string'],
149
+ [/'[^']*'/, 'string'],
150
+ [/[{}[\]()]/, 'delimiter.bracket'],
151
+ [/[a-zA-Z_$][\w$]*/, 'identifier'],
152
+ ]
153
+ }
154
+ });
155
+
156
+ // Create the editor
157
+ this.editor = monaco.editor.create(document.getElementById('templateEditor'), {
158
+ value: '<!-- Select a template to start editing -->',
159
+ language: 'handlebars',
160
+ theme: 'vs',
161
+ automaticLayout: true,
162
+ wordWrap: 'on',
163
+ minimap: { enabled: false },
164
+ scrollBeyondLastLine: false,
165
+ fontSize: 14,
166
+ lineNumbers: 'on',
167
+ renderWhitespace: 'selection'
168
+ });
169
+
170
+ // Setup editor change listener with debouncing
171
+ this.editor.onDidChangeModelContent(() => {
172
+ this.debouncePreviewUpdate();
173
+ });
174
+
175
+ resolve();
176
+ } catch (error) {
177
+ reject(error);
178
+ }
179
+ });
180
+ });
181
+ }
182
+
183
+ setupEventListeners() {
184
+ // Template selection
185
+ document.getElementById('templateSelect').addEventListener('change', (e) => {
186
+ this.loadTemplate(e.target.value);
187
+ });
188
+
189
+ // Variable management
190
+ document.getElementById('resetVariables').addEventListener('click', () => {
191
+ this.resetVariables();
192
+ });
193
+
194
+ document.getElementById('exportData').addEventListener('click', () => {
195
+ this.exportData();
196
+ });
197
+
198
+ // Template actions
199
+ document.getElementById('refreshPreview').addEventListener('click', () => {
200
+ this.updatePreview();
201
+ });
202
+
203
+ document.getElementById('copyTemplate').addEventListener('click', () => {
204
+ this.copyTemplate();
205
+ });
206
+
207
+ document.getElementById('downloadTemplate').addEventListener('click', () => {
208
+ this.downloadTemplate();
209
+ });
210
+
211
+ // Enter key for adding variables
212
+ // ['newVariableName', 'newVariableType', 'newVariableValue'].forEach(id => {
213
+ // document.getElementById(id).addEventListener('keypress', (e) => {
214
+ // if (e.key === 'Enter' && !e.shiftKey) {
215
+ // e.preventDefault();
216
+ // this.addCustomVariable();
217
+ // }
218
+ // });
219
+ // });
220
+ }
221
+
222
+ setupResizer() {
223
+ const resizer = document.getElementById('resizer');
224
+ const variablesPanel = document.querySelector('.variables-panel');
225
+ let isResizing = false;
226
+
227
+ resizer.addEventListener('mousedown', (e) => {
228
+ isResizing = true;
229
+ document.addEventListener('mousemove', handleMouseMove);
230
+ document.addEventListener('mouseup', handleMouseUp);
231
+ e.preventDefault();
232
+ });
233
+
234
+ function handleMouseMove(e) {
235
+ if (!isResizing) return;
236
+
237
+ const containerRect = document.querySelector('.playground-content').getBoundingClientRect();
238
+ const newWidth = e.clientX - containerRect.left;
239
+
240
+ if (newWidth >= 250 && newWidth <= containerRect.width - 400) {
241
+ variablesPanel.style.width = newWidth + 'px';
242
+ }
243
+ }
244
+
245
+ function handleMouseUp() {
246
+ isResizing = false;
247
+ document.removeEventListener('mousemove', handleMouseMove);
248
+ document.removeEventListener('mouseup', handleMouseUp);
249
+ }
250
+ }
251
+
252
+ async loadTemplate(templatePath) {
253
+ if (!templatePath) {
254
+ this.clearTemplate();
255
+ return;
256
+ }
257
+
258
+ try {
259
+ this.showLoading('Loading template and configuration...');
260
+
261
+ // Load configuration data instead of template-specific data
262
+ const configResponse = await fetch(`/api/session/${this.sessionId}/config`);
263
+ if (!configResponse.ok) {
264
+ throw new Error('Failed to load configuration data');
265
+ }
266
+
267
+ const { config } = await configResponse.json();
268
+
269
+ // Format config data to match expected structure
270
+ this.currentData = {
271
+ categories: {
272
+ compodocConfig: {
273
+ title: 'Compodoc Configuration Options',
274
+ description: 'Edit these configuration options to customize the generated documentation. Changes will automatically regenerate the documentation.',
275
+ data: config
276
+ }
277
+ }
278
+ };
279
+ this.originalData = JSON.parse(JSON.stringify(this.currentData));
280
+
281
+ // Load template content - try specific template first, then fallback
282
+ let templateContent = '';
283
+ try {
284
+ const encodedTemplatePathForContent = encodeURIComponent(templatePath);
285
+ const templateResponse = await fetch(`/api/session/${this.sessionId}/template/${encodedTemplatePathForContent}`);
286
+ if (templateResponse.ok) {
287
+ const template = await templateResponse.json();
288
+ templateContent = template.content;
289
+ } else {
290
+ // Use a generic template based on type
291
+ templateContent = this.getGenericTemplate(templatePath);
292
+ }
293
+ } catch (error) {
294
+ console.warn('Could not load specific template, using generic:', error);
295
+ templateContent = this.getGenericTemplate(templatePath);
296
+ }
297
+
298
+ this.currentTemplate = {
299
+ path: templatePath,
300
+ content: templateContent
301
+ };
302
+
303
+ // Defensive: Only update metadata if config data is present
304
+ if (this.currentData && this.currentData.categories && this.currentData.categories.compodocConfig && this.currentData.categories.compodocConfig.data) {
305
+ this.updateTemplateMetadata(templatePath, this.currentData.categories.compodocConfig.data);
306
+ } else {
307
+ this.updateTemplateMetadata(templatePath, {});
308
+ }
309
+ this.editor.setValue(templateContent);
310
+ this.renderVariables();
311
+ this.updatePreview();
312
+
313
+ this.hideLoading();
314
+
315
+ } catch (error) {
316
+ console.error('Error loading template:', error);
317
+ this.showError(`Failed to load template: ${error.message}`);
318
+ }
319
+ }
320
+
321
+ getGenericTemplate(templatePath) {
322
+ const templates = {
323
+ component: `<ol class="breadcrumb">
324
+ <li class="breadcrumb-item">{{t "components" }}</li>
325
+ <li class="breadcrumb-item">{{name}}</li>
326
+ </ol>
327
+
328
+ <div class="component-info">
329
+ <h3>{{name}}</h3>
330
+ <p class="description">{{description}}</p>
331
+
332
+ {{#if selector}}
333
+ <p><strong>Selector:</strong> <code>{{selector}}</code></p>
334
+ {{/if}}
335
+
336
+ {{#if inputs}}
337
+ <h4>Inputs</h4>
338
+ <ul>
339
+ {{#each inputs}}
340
+ <li><strong>{{name}}</strong> ({{type}}): {{description}}</li>
341
+ {{/each}}
342
+ </ul>
343
+ {{/if}}
344
+
345
+ {{#if outputs}}
346
+ <h4>Outputs</h4>
347
+ <ul>
348
+ {{#each outputs}}
349
+ <li><strong>{{name}}</strong> ({{type}}): {{description}}</li>
350
+ {{/each}}
351
+ </ul>
352
+ {{/if}}
353
+ </div>`,
354
+ module: `<ol class="breadcrumb">
355
+ <li class="breadcrumb-item">{{t "modules" }}</li>
356
+ <li class="breadcrumb-item">{{name}}</li>
357
+ </ol>
358
+
359
+ <div class="module-info">
360
+ <h3>{{name}}</h3>
361
+ <p class="description">{{description}}</p>
362
+
363
+ {{#if declarations}}
364
+ <h4>Declarations</h4>
365
+ <ul>
366
+ {{#each declarations}}
367
+ <li>{{name}} ({{type}})</li>
368
+ {{/each}}
369
+ </ul>
370
+ {{/if}}
371
+
372
+ {{#if imports}}
373
+ <h4>Imports</h4>
374
+ <ul>
375
+ {{#each imports}}
376
+ <li>{{name}}</li>
377
+ {{/each}}
378
+ </ul>
379
+ {{/if}}
380
+ </div>`,
381
+ interface: `<ol class="breadcrumb">
382
+ <li class="breadcrumb-item">{{t "interfaces" }}</li>
383
+ <li class="breadcrumb-item">{{name}}</li>
384
+ </ol>
385
+
386
+ <div class="interface-info">
387
+ <h3>{{name}}</h3>
388
+ <p class="description">{{description}}</p>
389
+
390
+ {{#if properties}}
391
+ <h4>Properties</h4>
392
+ <table class="table">
393
+ <thead>
394
+ <tr>
395
+ <th>Name</th>
396
+ <th>Type</th>
397
+ <th>Optional</th>
398
+ <th>Description</th>
399
+ </tr>
400
+ </thead>
401
+ <tbody>
402
+ {{#each properties}}
403
+ <tr>
404
+ <td><code>{{name}}</code></td>
405
+ <td><code>{{type}}</code></td>
406
+ <td>{{#if optional}}Yes{{else}}No{{/if}}</td>
407
+ <td>{{description}}</td>
408
+ </tr>
409
+ {{/each}}
410
+ </tbody>
411
+ </table>
412
+ {{/if}}
413
+ </div>`,
414
+ class: `<ol class="breadcrumb">
415
+ <li class="breadcrumb-item">{{t "classes" }}</li>
416
+ <li class="breadcrumb-item">{{name}}</li>
417
+ </ol>
418
+
419
+ <div class="class-info">
420
+ <h3>{{name}}</h3>
421
+ <p class="description">{{description}}</p>
422
+
423
+ {{#if methods}}
424
+ <h4>Methods</h4>
425
+ {{#each methods}}
426
+ <div class="method">
427
+ <h5>{{name}}</h5>
428
+ <p>{{description}}</p>
429
+ <p><strong>Returns:</strong> <code>{{type}}</code></p>
430
+ </div>
431
+ {{/each}}
432
+ {{/if}}
433
+ </div>`
434
+ };
435
+
436
+ return templates[templatePath] || `<h3>{{name}}</h3>
437
+ <p>{{description}}</p>
438
+ <p><strong>Type:</strong> ${templatePath}</p>`;
439
+ }
440
+
441
+ updateTemplateMetadata(templatePath, data) {
442
+ const metadata = document.getElementById('templateMetadata');
443
+ document.getElementById('templateName').textContent = data.name || templatePath;
444
+ document.getElementById('templateFile').textContent = data.file || `${templatePath}.hbs`;
445
+ document.getElementById('templateDescription').textContent = data.description || `Template for ${templatePath}`;
446
+ metadata.style.display = 'block';
447
+ }
448
+
449
+ renderVariables() {
450
+ const container = document.getElementById('variablesList');
451
+ container.innerHTML = '';
452
+
453
+ // Check if we have the new categorized data format
454
+ if (this.currentData && this.currentData.categories) {
455
+ this.renderCategorizedVariables(container);
456
+ } else {
457
+ // Fallback to legacy format
458
+ this.renderLegacyVariables(container);
459
+ }
460
+
461
+ // Remove custom variables section
462
+ // this.renderCustomVariables(container);
463
+ }
464
+
465
+ renderCategorizedVariables(container) {
466
+ const categories = this.currentData.categories;
467
+
468
+ // Only render Compodoc Configuration section
469
+ if (categories.compodocConfig) {
470
+ // Add a special header for config section
471
+ const configHeader = document.createElement('div');
472
+ configHeader.innerHTML = `
473
+ <div style="
474
+ background: linear-gradient(135deg, #2196F3, #1976D2);
475
+ color: white;
476
+ padding: 8px 16px;
477
+ margin-bottom: 16px;
478
+ border-radius: 6px;
479
+ font-size: 12px;
480
+ font-weight: 600;
481
+ text-transform: uppercase;
482
+ letter-spacing: 0.5px;
483
+ ">
484
+ <i class="fas fa-cog"></i> Editable Configuration
485
+ </div>
486
+ `;
487
+ container.appendChild(configHeader);
488
+
489
+ this.createCategorySection(
490
+ container,
491
+ 'compodoc-config',
492
+ categories.compodocConfig.title,
493
+ categories.compodocConfig.description,
494
+ categories.compodocConfig.data,
495
+ '#2196F3', // Blue for config
496
+ 'config' // Mark as config category - these will be editable
497
+ );
498
+ }
499
+
500
+ // Template variables section removed - only show config options
501
+ }
502
+
503
+ createCategorySection(container, categoryId, title, description, data, accentColor, categoryType = 'template') {
504
+ const section = document.createElement('div');
505
+ section.className = 'variable-category';
506
+ section.style.marginBottom = '20px';
507
+
508
+ section.innerHTML = `
509
+ <div class="category-header" style="
510
+ background: linear-gradient(135deg, ${accentColor}15, ${accentColor}05);
511
+ border-left: 4px solid ${accentColor};
512
+ padding: 12px 16px;
513
+ margin-bottom: 10px;
514
+ border-radius: 0 6px 6px 0;
515
+ cursor: pointer;
516
+ transition: all 0.3s ease;
517
+ ">
518
+ <div style="display: flex; align-items: center; justify-content: space-between;">
519
+ <div>
520
+ <h3 style="
521
+ margin: 0;
522
+ color: ${accentColor};
523
+ font-size: 14px;
524
+ font-weight: 600;
525
+ text-transform: uppercase;
526
+ letter-spacing: 0.5px;
527
+ ">${title}</h3>
528
+ <p style="
529
+ margin: 4px 0 0 0;
530
+ color: #666;
531
+ font-size: 12px;
532
+ line-height: 1.4;
533
+ ">${description}</p>
534
+ </div>
535
+ <button class="category-toggle" style="
536
+ background: ${accentColor};
537
+ color: white;
538
+ border: none;
539
+ width: 24px;
540
+ height: 24px;
541
+ border-radius: 50%;
542
+ display: flex;
543
+ align-items: center;
544
+ justify-content: center;
545
+ cursor: pointer;
546
+ font-size: 12px;
547
+ transition: transform 0.3s ease;
548
+ ">
549
+ <i class="fas fa-chevron-down"></i>
550
+ </button>
551
+ </div>
552
+ </div>
553
+ <div class="category-content" style="
554
+ padding: 0 16px;
555
+ max-height: 400px;
556
+ overflow-y: auto;
557
+ border-left: 4px solid ${accentColor}20;
558
+ margin-left: 12px;
559
+ ">
560
+ <div class="category-variables"></div>
561
+ </div>
562
+ `;
563
+
564
+ // Add toggle functionality
565
+ const header = section.querySelector('.category-header');
566
+ const content = section.querySelector('.category-content');
567
+ const toggle = section.querySelector('.category-toggle');
568
+
569
+ header.addEventListener('click', () => {
570
+ const isCollapsed = content.style.display === 'none';
571
+ content.style.display = isCollapsed ? 'block' : 'none';
572
+ toggle.style.transform = isCollapsed ? 'rotate(0deg)' : 'rotate(-180deg)';
573
+ });
574
+
575
+ container.appendChild(section);
576
+
577
+ // Populate variables in this category
578
+ const variableContainer = section.querySelector('.category-variables');
579
+ this.createVariableElements(data, '', variableContainer, 0, accentColor, categoryType);
580
+ }
581
+
582
+ renderLegacyVariables(container) {
583
+ // Legacy rendering for backward compatibility
584
+ const section = document.createElement('div');
585
+ section.innerHTML = `
586
+ <div class="category-header" style="padding: 12px 16px; background: #f8f9fa; margin-bottom: 10px;">
587
+ <h3 style="margin: 0; color: #333; font-size: 14px;">Template Data</h3>
588
+ <p style="margin: 4px 0 0 0; color: #666; font-size: 12px;">Available template variables and context</p>
589
+ </div>
590
+ <div class="category-variables"></div>
591
+ `;
592
+
593
+ container.appendChild(section);
594
+ const variableContainer = section.querySelector('.category-variables');
595
+ this.createVariableElements(this.currentData, '', variableContainer);
596
+ }
597
+
598
+ renderCustomVariables(container) {
599
+ if (Object.keys(this.customVariables).length === 0) return;
600
+
601
+ const section = document.createElement('div');
602
+ section.className = 'variable-category custom-variables';
603
+ section.style.marginTop = '20px';
604
+
605
+ section.innerHTML = `
606
+ <div class="category-header" style="
607
+ background: linear-gradient(135deg, #FF9800 15%, #FF9800 05%);
608
+ border-left: 4px solid #FF9800;
609
+ padding: 12px 16px;
610
+ margin-bottom: 10px;
611
+ border-radius: 0 6px 6px 0;
612
+ ">
613
+ <div style="display: flex; align-items: center; justify-content: space-between;">
614
+ <div>
615
+ <h3 style="
616
+ margin: 0;
617
+ color: #FF9800;
618
+ font-size: 14px;
619
+ font-weight: 600;
620
+ text-transform: uppercase;
621
+ letter-spacing: 0.5px;
622
+ ">Custom Variables</h3>
623
+ <p style="
624
+ margin: 4px 0 0 0;
625
+ color: #666;
626
+ font-size: 12px;
627
+ line-height: 1.4;
628
+ ">User-defined variables for template customization</p>
629
+ </div>
630
+ <button class="btn-icon" id="addCustomVariableBtn" style="
631
+ background: #FF9800;
632
+ color: white;
633
+ border: none;
634
+ width: 24px;
635
+ height: 24px;
636
+ border-radius: 50%;
637
+ cursor: pointer;
638
+ font-size: 12px;
639
+ " onclick="templatePlayground.addCustomVariable()" title="Add Custom Variable">
640
+ <i class="fas fa-plus"></i>
641
+ </button>
642
+ </div>
643
+ </div>
644
+ <div class="custom-variables-content" style="
645
+ padding: 0 16px;
646
+ border-left: 4px solid #FF980020;
647
+ margin-left: 12px;
648
+ "></div>
649
+ `;
650
+
651
+ container.appendChild(section);
652
+
653
+ // Add custom variables
654
+ const customContainer = section.querySelector('.custom-variables-content');
655
+ Object.entries(this.customVariables).forEach(([key, value]) => {
656
+ this.createVariableElement(key, typeof value, value, customContainer, true, null, '#FF9800');
657
+ });
658
+ }
659
+
660
+ createVariableElements(obj, prefix, container, depth = 0, accentColor = '#007bff', categoryType = 'template') {
661
+ if (depth > 3) return; // Prevent too deep nesting
662
+
663
+ const sortedEntries = Object.entries(obj).sort(([a], [b]) => {
664
+ // Sort by importance: put functions and complex objects at the end
665
+ const aIsSimple = typeof obj[a] !== 'object' && typeof obj[a] !== 'function';
666
+ const bIsSimple = typeof obj[b] !== 'object' && typeof obj[b] !== 'function';
667
+ if (aIsSimple && !bIsSimple) return -1;
668
+ if (!aIsSimple && bIsSimple) return 1;
669
+ return a.localeCompare(b);
670
+ });
671
+
672
+ sortedEntries.forEach(([key, value]) => {
673
+ const fullKey = prefix ? `${prefix}.${key}` : key;
674
+
675
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
676
+ // Create expandable object
677
+ if (depth < 3) {
678
+ const objectElement = document.createElement('div');
679
+ objectElement.className = 'variable-item expandable-object';
680
+ objectElement.style.marginBottom = '8px';
681
+
682
+ const isExpanded = depth === 0; // Expand top-level objects by default
683
+
684
+ objectElement.innerHTML = `
685
+ <div class="variable-header" style="
686
+ display: flex;
687
+ align-items: center;
688
+ padding: 8px 12px;
689
+ background: ${depth === 0 ? '#f8f9fa' : '#ffffff'};
690
+ border: 1px solid #e9ecef;
691
+ border-radius: 4px;
692
+ cursor: pointer;
693
+ transition: all 0.2s ease;
694
+ ">
695
+ <button class="expand-toggle" style="
696
+ background: none;
697
+ border: none;
698
+ color: ${accentColor};
699
+ font-size: 12px;
700
+ margin-right: 8px;
701
+ cursor: pointer;
702
+ transform: ${isExpanded ? 'rotate(90deg)' : 'rotate(0deg)'};
703
+ transition: transform 0.2s ease;
704
+ ">
705
+ <i class="fas fa-chevron-right"></i>
706
+ </button>
707
+ <div class="variable-name" style="
708
+ font-weight: ${depth === 0 ? '600' : '500'};
709
+ color: ${depth === 0 ? '#333' : '#555'};
710
+ flex: 1;
711
+ font-size: ${depth === 0 ? '13px' : '12px'};
712
+ ">${key}</div>
713
+ <div class="variable-type" style="
714
+ font-size: 10px;
715
+ color: #888;
716
+ background: #f1f3f4;
717
+ padding: 2px 6px;
718
+ border-radius: 10px;
719
+ text-transform: uppercase;
720
+ letter-spacing: 0.3px;
721
+ ">object</div>
722
+ </div>
723
+ <div class="nested-variables" style="
724
+ margin-top: 4px;
725
+ padding-left: ${(depth + 1) * 16}px;
726
+ border-left: 2px solid ${accentColor}20;
727
+ margin-left: 20px;
728
+ display: ${isExpanded ? 'block' : 'none'};
729
+ "></div>
730
+ `;
731
+
732
+ // Add click handler for expansion
733
+ const header = objectElement.querySelector('.variable-header');
734
+ const toggle = objectElement.querySelector('.expand-toggle');
735
+ const nested = objectElement.querySelector('.nested-variables');
736
+
737
+ header.addEventListener('click', () => {
738
+ const isCurrentlyExpanded = nested.style.display !== 'none';
739
+ nested.style.display = isCurrentlyExpanded ? 'none' : 'block';
740
+ toggle.style.transform = isCurrentlyExpanded ? 'rotate(0deg)' : 'rotate(90deg)';
741
+ });
742
+
743
+ container.appendChild(objectElement);
744
+
745
+ const nestedContainer = objectElement.querySelector('.nested-variables');
746
+ this.createVariableElements(value, fullKey, nestedContainer, depth + 1, accentColor, categoryType);
747
+ }
748
+ } else {
749
+ this.createVariableElement(key, typeof value, value, container, false, fullKey, accentColor, categoryType);
750
+ }
751
+ });
752
+ }
753
+
754
+ createVariableElement(name, type, value, container, isCustom = false, fullPath = null, accentColor = '#007bff', categoryType = 'template') {
755
+ const variableElement = document.createElement('div');
756
+ variableElement.className = 'variable-item simple-variable';
757
+ variableElement.style.marginBottom = '6px';
758
+
759
+ let displayValue = value;
760
+ let rows = 1;
761
+
762
+ if (typeof value === 'object' && value !== null) {
763
+ displayValue = JSON.stringify(value, null, 2);
764
+ rows = Math.min(displayValue.split('\n').length, 6);
765
+ } else if (typeof value === 'string') {
766
+ displayValue = value;
767
+ rows = Math.min(displayValue.split('\n').length, 4);
768
+ } else if (typeof value === 'function') {
769
+ displayValue = value.toString().substring(0, 100) + '...';
770
+ type = 'function';
771
+ rows = 2;
772
+ } else {
773
+ displayValue = String(value);
774
+ }
775
+
776
+ // Determine if variable should be editable
777
+ // Config variables are editable, template variables are read-only, custom variables are always editable
778
+ const isEditable = isCustom || categoryType === 'config';
779
+
780
+ // Determine type color
781
+ const getTypeColor = (type) => {
782
+ switch (type) {
783
+ case 'string': return '#4CAF50';
784
+ case 'number': return '#2196F3';
785
+ case 'boolean': return '#FF9800';
786
+ case 'function': return '#9C27B0';
787
+ case 'object': return '#607D8B';
788
+ default: return '#666';
789
+ }
790
+ };
791
+
792
+ // Render dropdown for string config variables with known options
793
+ let inputElement = '';
794
+ const selectOptions = {
795
+ theme: [
796
+ 'gitbook', 'laravel', 'material', 'readthedocs', 'postmark', 'vagrant', 'minimal', 'default', 'plain', 'stripe', 'aglio', 'book', 'github', 'vuepress', 'docusaurus', 'mkdocs', 'slate', 'swagger', 'modern', 'clean', 'classic', 'simple', 'bootstrap', 'angular', 'react', 'vue', 'bulma', 'tailwind', 'windicss', 'dracula', 'solarized', 'nord', 'night', 'light', 'dark', 'custom'
797
+ ],
798
+ language: [
799
+ 'en-US', 'fr-FR', 'de-DE', 'es-ES', 'it-IT', 'ja-JP', 'ko-KR', 'nl-NL', 'pl-PL', 'pt-BR', 'ru-RU', 'sk-SK', 'zh-CN', 'zh-TW', 'bg-BG', 'hu-HU', 'ka-GE'
800
+ ],
801
+ exportFormat: [
802
+ 'html', 'json', 'pdf'
803
+ ]
804
+ };
805
+ if (isEditable && type === 'string' && selectOptions[name]) {
806
+ inputElement = `<select class="variable-value" onchange="templatePlayground.updateVariable('${fullPath || name}', this.value, ${isCustom}, '${categoryType}')">
807
+ ${selectOptions[name].map(opt => `<option value="${opt}" ${value === opt ? 'selected' : ''}>${opt}</option>`).join('')}
808
+ </select>`;
809
+ } else if (isEditable && type === 'boolean') {
810
+ inputElement = `<input type="checkbox" class="variable-value" style="width: 18px; height: 18px; margin-right: 8px; vertical-align: middle;" ${value ? 'checked' : ''} onchange="templatePlayground.updateVariable('${fullPath || name}', this.checked, ${isCustom}, '${categoryType}')">`;
811
+ } else {
812
+ inputElement = `<textarea class="variable-value" style="
813
+ width: 100%;
814
+ min-height: ${rows * 16}px;
815
+ border: 1px solid #ddd;
816
+ border-radius: 3px;
817
+ padding: 6px 8px;
818
+ font-size: 11px;
819
+ font-family: 'Consolas', 'Monaco', monospace;
820
+ resize: vertical;
821
+ background: #f8f9fa;
822
+ ${isEditable ? '' : 'background: #f1f3f4; cursor: not-allowed;'}
823
+ }"
824
+ ${isEditable ? `onchange=\"templatePlayground.updateVariable('${fullPath || name}', this.value, ${isCustom}, '${categoryType}')\"` : 'readonly'}
825
+ rows="${rows}">${displayValue}</textarea>`;
826
+ }
827
+
828
+ variableElement.innerHTML = `
829
+ <div style="
830
+ display: flex;
831
+ align-items: flex-start;
832
+ padding: 8px 12px;
833
+ background: white;
834
+ border: 1px solid #e9ecef;
835
+ border-radius: 4px;
836
+ transition: all 0.2s ease;
837
+ " onmouseover="this.style.borderColor='${accentColor}'" onmouseout="this.style.borderColor='#e9ecef'">
838
+ <div style="flex: 1; min-width: 0;">
839
+ <div style="display: flex; align-items: center; margin-bottom: 4px;">
840
+ <div class="variable-name" style="
841
+ font-weight: 500;
842
+ color: #333;
843
+ font-size: 12px;
844
+ margin-right: 8px;
845
+ font-family: 'Consolas', 'Monaco', monospace;
846
+ ">${name}</div>
847
+ <div class="variable-type" style="
848
+ font-size: 9px;
849
+ color: ${getTypeColor(type)};
850
+ background: ${getTypeColor(type)}15;
851
+ padding: 2px 6px;
852
+ border-radius: 8px;
853
+ text-transform: uppercase;
854
+ letter-spacing: 0.3px;
855
+ font-weight: 600;
856
+ ">${type}</div>
857
+ ${isCustom ? `
858
+ <button class="btn-icon" style="
859
+ background: #ffebee;
860
+ color: #d32f2f;
861
+ border: none;
862
+ width: 18px;
863
+ height: 18px;
864
+ border-radius: 50%;
865
+ margin-left: auto;
866
+ cursor: pointer;
867
+ font-size: 10px;
868
+ " onclick="templatePlayground.removeVariable('${name}')" title="Remove variable">
869
+ <i class="fas fa-times"></i>
870
+ </button>
871
+ ` : ''}
872
+ </div>
873
+ ${inputElement}
874
+ </div>
875
+ </div>
876
+ `;
877
+
878
+ container.appendChild(variableElement);
879
+ }
880
+
881
+ updateVariable(path, value, isCustom = false, categoryType = 'template') {
882
+ try {
883
+ let parsedValue;
884
+
885
+ // Try to parse as JSON first
886
+ try {
887
+ parsedValue = JSON.parse(value);
888
+ } catch {
889
+ // If not valid JSON, treat as string
890
+ parsedValue = value;
891
+ }
892
+
893
+ if (isCustom) {
894
+ this.customVariables[path] = parsedValue;
895
+ this.debouncePreviewUpdate();
896
+ } else if (categoryType === 'config') {
897
+ // Handle config variable updates
898
+ this.updateSessionConfig(path, parsedValue);
899
+ } else {
900
+ // Update nested property for template variables
901
+ this.setNestedProperty(this.currentData, path, parsedValue);
902
+ this.debouncePreviewUpdate();
903
+ }
904
+
905
+ } catch (error) {
906
+ console.error('Error updating variable:', error);
907
+ }
908
+ }
909
+
910
+ async updateSessionConfig(configPath, newValue) {
911
+ try {
912
+ // Update the local config data immediately for responsiveness
913
+ this.setNestedProperty(this.currentData.categories.compodocConfig.data, configPath, newValue);
914
+
915
+ // Prepare config update for server
916
+ const configUpdate = {};
917
+ this.setNestedProperty(configUpdate, configPath, newValue);
918
+
919
+ this.showMessage('💾 Saving configuration...', 'info');
920
+
921
+ // Send config update to server
922
+ const response = await fetch(`/api/session/${this.sessionId}/config`, {
923
+ method: 'POST',
924
+ headers: {
925
+ 'Content-Type': 'application/json'
926
+ },
927
+ body: JSON.stringify({
928
+ config: configUpdate
929
+ })
930
+ });
931
+
932
+ if (!response.ok) {
933
+ throw new Error(`Server responded with ${response.status}`);
934
+ }
935
+
936
+ const result = await response.json();
937
+
938
+ if (result.success) {
939
+ this.showSuccess('✅ Configuration saved! Documentation regenerating...');
940
+ // Automatically update the preview after config is saved
941
+ this.updatePreview();
942
+ } else {
943
+ throw new Error(result.message || 'Failed to save configuration');
944
+ }
945
+
946
+ } catch (error) {
947
+ console.error('Error updating session config:', error);
948
+ this.showError(`❌ Failed to save configuration: ${error.message}`);
949
+
950
+ // Revert the local change if save failed
951
+ this.renderVariables();
952
+ }
953
+ }
954
+
955
+ setNestedProperty(obj, path, value) {
956
+ const keys = path.split('.');
957
+ const lastKey = keys.pop();
958
+ const target = keys.reduce((current, key) => current && current[key], obj);
959
+
960
+ if (target && lastKey) {
961
+ target[lastKey] = value;
962
+ }
963
+ }
964
+
965
+ addCustomVariable() {
966
+ const nameInput = document.getElementById('newVariableName');
967
+ const typeInput = document.getElementById('newVariableType');
968
+ const valueInput = document.getElementById('newVariableValue');
969
+
970
+ const name = nameInput.value.trim();
971
+ const type = typeInput.value.trim() || 'string';
972
+ const valueStr = valueInput.value.trim();
973
+
974
+ if (!name) {
975
+ this.showError('Variable name is required');
976
+ return;
977
+ }
978
+
979
+ let value;
980
+ try {
981
+ if (valueStr) {
982
+ value = JSON.parse(valueStr);
983
+ } else {
984
+ value = type === 'boolean' ? false : type === 'number' ? 0 : '';
985
+ }
986
+ } catch {
987
+ value = valueStr;
988
+ }
989
+
990
+ this.customVariables[name] = value;
991
+
992
+ // Clear inputs
993
+ nameInput.value = '';
994
+ typeInput.value = '';
995
+ valueInput.value = '';
996
+
997
+ this.renderVariables();
998
+ this.debouncePreviewUpdate();
999
+ this.showSuccess('Variable added successfully');
1000
+ }
1001
+
1002
+ removeVariable(name) {
1003
+ delete this.customVariables[name];
1004
+ this.renderVariables();
1005
+ this.debouncePreviewUpdate();
1006
+ }
1007
+
1008
+ resetVariables() {
1009
+ this.currentData = JSON.parse(JSON.stringify(this.originalData));
1010
+ this.customVariables = {};
1011
+ this.renderVariables();
1012
+ this.updatePreview();
1013
+ this.showSuccess('Variables reset to default values');
1014
+ }
1015
+
1016
+ debouncePreviewUpdate() {
1017
+ clearTimeout(this.debounceTimer);
1018
+ this.debounceTimer = setTimeout(() => {
1019
+ this.updatePreview();
1020
+ }, 300);
1021
+ }
1022
+
1023
+ async updatePreview() {
1024
+ if (!this.currentTemplate) return;
1025
+
1026
+ try {
1027
+ this.setPreviewStatus('🚀 Generating documentation with CompoDoc CLI...', true);
1028
+
1029
+ const templateContent = this.editor.getValue();
1030
+
1031
+ // Use CompoDoc CLI generation API
1032
+ const response = await fetch(`/api/session/${this.sessionId}/generate-docs`, {
1033
+ method: 'POST',
1034
+ headers: {
1035
+ 'Content-Type': 'application/json'
1036
+ },
1037
+ body: JSON.stringify({
1038
+ customTemplateContent: templateContent,
1039
+ templatePath: this.currentTemplate ? this.currentTemplate.path : null,
1040
+ mockData: { ...this.currentData, ...this.customVariables }
1041
+ })
1042
+ });
1043
+
1044
+ if (!response.ok) {
1045
+ const errorData = await response.json();
1046
+ throw new Error(errorData.details || `Server responded with ${response.status}`);
1047
+ }
1048
+
1049
+ const result = await response.json();
1050
+
1051
+ if (result.success) {
1052
+ // Documentation generated successfully, now load it in iframe
1053
+ this.setPreviewStatus('📄 Loading generated documentation...', true);
1054
+
1055
+ // Point iframe to the last visited documentation page if available
1056
+ const iframe = document.getElementById('templatePreviewFrame');
1057
+ if (iframe) {
1058
+ let url = `/docs/${this.sessionId}/index.html?t=` + Date.now();
1059
+ if (this.lastVisitedDocUrl) {
1060
+ // Remove /docs/<sessionId>/ prefix if present
1061
+ let docPath = this.lastVisitedDocUrl.replace(new RegExp(`^/docs/${this.sessionId}/?`), '');
1062
+ url = `/docs/${this.sessionId}/${docPath}`;
1063
+ url += (url.includes('?') ? '&' : '?') + 't=' + Date.now();
1064
+ }
1065
+ iframe.src = url;
1066
+
1067
+ iframe.onload = () => {
1068
+ this.setPreviewStatus('✅ Documentation loaded successfully', false);
1069
+ setTimeout(() => {
1070
+ this.setPreviewStatus('', false);
1071
+ }, 2000);
1072
+ };
1073
+
1074
+ iframe.onerror = () => {
1075
+ this.setPreviewStatus('❌ Failed to load generated documentation', false);
1076
+ };
1077
+ } else {
1078
+ this.setPreviewStatus('❌ Preview iframe not found', false);
1079
+ }
1080
+ } else {
1081
+ throw new Error('Documentation generation failed');
1082
+ }
1083
+
1084
+ } catch (error) {
1085
+ console.error('Error generating documentation:', error);
1086
+ this.setPreviewStatus(`❌ Error: ${error.message}`, false);
1087
+
1088
+ // Show error in iframe
1089
+ const iframe = document.getElementById('templatePreviewFrame');
1090
+ if (iframe) {
1091
+ const errorHtml = `
1092
+ <html>
1093
+ <head>
1094
+ <title>Documentation Generation Error</title>
1095
+ <style>
1096
+ body {
1097
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
1098
+ padding: 40px;
1099
+ background: #f8f9fa;
1100
+ color: #333;
1101
+ line-height: 1.6;
1102
+ }
1103
+ .error-container {
1104
+ background: white;
1105
+ padding: 30px;
1106
+ border-radius: 8px;
1107
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
1108
+ max-width: 600px;
1109
+ margin: 0 auto;
1110
+ }
1111
+ .error-icon {
1112
+ color: #dc3545;
1113
+ font-size: 48px;
1114
+ text-align: center;
1115
+ margin-bottom: 20px;
1116
+ }
1117
+ .error-title {
1118
+ color: #dc3545;
1119
+ margin-bottom: 15px;
1120
+ text-align: center;
1121
+ }
1122
+ .error-message {
1123
+ background: #f8d7da;
1124
+ border: 1px solid #f5c6cb;
1125
+ color: #721c24;
1126
+ padding: 15px;
1127
+ border-radius: 4px;
1128
+ margin-bottom: 20px;
1129
+ font-family: monospace;
1130
+ }
1131
+ .suggestions {
1132
+ background: #d1ecf1;
1133
+ border: 1px solid #bee5eb;
1134
+ color: #0c5460;
1135
+ padding: 15px;
1136
+ border-radius: 4px;
1137
+ }
1138
+ .suggestions h4 {
1139
+ margin-top: 0;
1140
+ margin-bottom: 10px;
1141
+ }
1142
+ .suggestions ul {
1143
+ margin-bottom: 0;
1144
+ padding-left: 20px;
1145
+ }
1146
+ .retry-button {
1147
+ background: #007bff;
1148
+ color: white;
1149
+ border: none;
1150
+ padding: 10px 20px;
1151
+ border-radius: 4px;
1152
+ cursor: pointer;
1153
+ font-size: 14px;
1154
+ margin-top: 15px;
1155
+ display: block;
1156
+ margin-left: auto;
1157
+ margin-right: auto;
1158
+ }
1159
+ .retry-button:hover {
1160
+ background: #0056b3;
1161
+ }
1162
+ </style>
1163
+ </head>
1164
+ <body>
1165
+ <div class="error-container">
1166
+ <div class="error-icon">⚠️</div>
1167
+ <h2 class="error-title">Documentation Generation Failed</h2>
1168
+ <div class="error-message">
1169
+ <div class="suggestions">
1170
+ <h4>Possible solutions:</h4>
1171
+ <ul>
1172
+ <li>Check if your Handlebars template syntax is valid</li>
1173
+ <li>Ensure all referenced partials exist</li>
1174
+ <li>Verify that template variables match the expected data structure</li>
1175
+ <li>Try refreshing the page and loading a different template</li>
1176
+ </ul>
1177
+ </div>
1178
+ <button class="retry-button" onclick="parent.templatePlayground.updatePreview()">
1179
+ 🔄 Retry Generation
1180
+ </button>
1181
+ </div>
1182
+ </body>
1183
+ </html>
1184
+ `;
1185
+ iframe.srcdoc = errorHtml;
1186
+ }
1187
+ }
1188
+ }
1189
+
1190
+ setPreviewStatus(text, isLoading) {
1191
+ const statusElement = document.getElementById('previewStatus');
1192
+ statusElement.innerHTML = isLoading ?
1193
+ `<div class="spinner"></div> ${text}` : text;
1194
+ }
1195
+
1196
+ async copyTemplate() {
1197
+ try {
1198
+ await navigator.clipboard.writeText(this.editor.getValue());
1199
+ this.showSuccess('Template copied to clipboard');
1200
+ } catch (error) {
1201
+ console.error('Error copying template:', error);
1202
+ this.showError('Failed to copy template');
1203
+ }
1204
+ }
1205
+
1206
+ async downloadTemplate() {
1207
+ try {
1208
+ if (!this.sessionId) {
1209
+ this.showError('No active session. Please refresh the page and try again.');
1210
+ return;
1211
+ }
1212
+
1213
+ // Show loading state
1214
+ this.showLoading('Creating complete template package...');
1215
+
1216
+ // Call server-side ZIP creation endpoint for all templates
1217
+ const response = await fetch(`/api/session/${this.sessionId}/download-all-templates`, {
1218
+ method: 'POST',
1219
+ headers: {
1220
+ 'Content-Type': 'application/json',
1221
+ }
1222
+ });
1223
+
1224
+ this.hideLoading();
1225
+
1226
+ if (!response.ok) {
1227
+ if (response.headers.get('content-type')?.includes('application/json')) {
1228
+ const errorData = await response.json();
1229
+ throw new Error(errorData.error || 'Failed to create template package');
1230
+ } else {
1231
+ throw new Error(`Server error: ${response.status} ${response.statusText}`);
1232
+ }
1233
+ }
1234
+
1235
+ // Get the ZIP file as a blob
1236
+ const zipBlob = await response.blob();
1237
+
1238
+ // Get filename from response headers or construct it
1239
+ const contentDisposition = response.headers.get('Content-Disposition');
1240
+ let filename = `compodoc-templates-${this.sessionId}.zip`;
1241
+
1242
+ if (contentDisposition) {
1243
+ const filenameMatch = contentDisposition.match(/filename="([^"]+)"/);
1244
+ if (filenameMatch) {
1245
+ filename = filenameMatch[1];
1246
+ }
1247
+ }
1248
+
1249
+ // Create download link and trigger download
1250
+ const url = URL.createObjectURL(zipBlob);
1251
+ const a = document.createElement('a');
1252
+ a.href = url;
1253
+ a.download = filename;
1254
+ document.body.appendChild(a);
1255
+ a.click();
1256
+ document.body.removeChild(a);
1257
+ URL.revokeObjectURL(url);
1258
+
1259
+ this.showSuccess('Complete template package downloaded successfully');
1260
+
1261
+ } catch (error) {
1262
+ console.error('Error downloading template:', error);
1263
+ this.hideLoading();
1264
+
1265
+ let errorMessage = 'Failed to download complete template package';
1266
+
1267
+ if (error.message) {
1268
+ errorMessage = error.message;
1269
+ }
1270
+
1271
+ this.showError(errorMessage);
1272
+ }
1273
+ }
1274
+
1275
+ exportData() {
1276
+ try {
1277
+ // Generate the CompoDoc CLI command based on current config
1278
+ const config = this.currentData.categories?.compodocConfig?.data || {};
1279
+ const booleanFlags = [
1280
+ 'hideGenerator', 'disableSourceCode', 'disableGraph', 'disableCoverage', 'disablePrivate', 'disableProtected', 'disableInternal',
1281
+ 'disableLifeCycleHooks', 'disableConstructors', 'disableRoutesGraph', 'disableSearch', 'disableDependencies', 'disableProperties',
1282
+ 'disableDomTree', 'disableTemplateTab', 'disableStyleTab', 'disableMainGraph', 'disableFilePath', 'disableOverview',
1283
+ 'hideDarkModeToggle', 'minimal', 'serve', 'open', 'watch', 'silent',
1284
+ 'coverageTest', 'coverageTestThresholdFail', 'coverageTestShowOnlyFailed'
1285
+ ];
1286
+ const valueFlags = [
1287
+ 'theme', 'language', 'base', 'customFavicon', 'customLogo', 'assetsFolder', 'extTheme', 'includes', 'includesName', 'output', 'port', 'hostname',
1288
+ 'exportFormat', 'coverageTestThreshold', 'coverageMinimumPerFile', 'unitTestCoverage', 'gaID', 'gaSite', 'maxSearchResults', 'toggleMenuItems', 'navTabConfig'
1289
+ ];
1290
+ let cmd = ['npx compodoc'];
1291
+ for (const flag of booleanFlags) {
1292
+ if (config[flag] === true) {
1293
+ cmd.push(`--${flag}`);
1294
+ }
1295
+ }
1296
+ for (const flag of valueFlags) {
1297
+ if (config[flag] !== undefined && config[flag] !== "") {
1298
+ let value = config[flag];
1299
+ if (Array.isArray(value) || typeof value === 'object') {
1300
+ value = JSON.stringify(value);
1301
+ }
1302
+ cmd.push(`--${flag} \"${value}\"`);
1303
+ }
1304
+ }
1305
+ // Always include -p and -d
1306
+ cmd.push(`-p \"tsconfig.json\"`);
1307
+ cmd.push(`-d \"${config.output || './documentation/'}\"`);
1308
+ const commandString = cmd.join(' ');
1309
+
1310
+ const blob = new Blob([commandString], { type: 'text/plain' });
1311
+ const url = URL.createObjectURL(blob);
1312
+ const a = document.createElement('a');
1313
+ a.href = url;
1314
+ a.download = `compodoc-command.txt`;
1315
+ document.body.appendChild(a);
1316
+ a.click();
1317
+ document.body.removeChild(a);
1318
+ URL.revokeObjectURL(url);
1319
+
1320
+ this.showSuccess('CompoDoc CLI command exported successfully');
1321
+ } catch (error) {
1322
+ console.error('Error exporting command:', error);
1323
+ this.showError('Failed to export command');
1324
+ }
1325
+ }
1326
+
1327
+ clearTemplate() {
1328
+ this.currentTemplate = null;
1329
+ this.currentData = {};
1330
+ this.originalData = {};
1331
+ this.customVariables = {};
1332
+
1333
+ this.editor.setValue('<!-- Select a template to start editing -->');
1334
+ document.getElementById('templateMetadata').style.display = 'none';
1335
+ document.getElementById('variablesList').innerHTML = `
1336
+ <div class="loading">
1337
+ <div class="spinner"></div>
1338
+ Select a template to see variables
1339
+ </div>
1340
+ `;
1341
+ // Clear iframe
1342
+ const iframe = document.getElementById('templatePreviewFrame');
1343
+ if (iframe) {
1344
+ iframe.src = 'data:text/html,<div style="padding: 20px; text-align: center; color: #666;"><div style="font-size: 18px; margin-bottom: 10px;">📝</div>Select a template to see preview</div>';
1345
+ }
1346
+ }
1347
+
1348
+ showLoading(message) {
1349
+ document.getElementById('variablesList').innerHTML = `
1350
+ <div class="loading">
1351
+ <div class="spinner"></div>
1352
+ ${message}
1353
+ </div>
1354
+ `;
1355
+ }
1356
+
1357
+ hideLoading() {
1358
+ // Loading will be replaced by renderVariables()
1359
+ }
1360
+
1361
+ showError(message) {
1362
+ this.showMessage(message, 'error');
1363
+ }
1364
+
1365
+ showSuccess(message) {
1366
+ this.showMessage(message, 'success');
1367
+ }
1368
+
1369
+ showMessage(message, type) {
1370
+ const className = type === 'error' ? 'error-message' : 'success-message';
1371
+ const messageElement = document.createElement('div');
1372
+ messageElement.className = className;
1373
+ messageElement.textContent = message;
1374
+
1375
+ const container = document.querySelector('.variables-panel .panel-content');
1376
+ container.insertBefore(messageElement, container.firstChild);
1377
+
1378
+ setTimeout(() => {
1379
+ if (messageElement.parentElement) {
1380
+ messageElement.parentElement.removeChild(messageElement);
1381
+ }
1382
+ }, 3000);
1383
+ }
1384
+ }
1385
+
1386
+ // Initialize the playground when DOM is loaded
1387
+ document.addEventListener('DOMContentLoaded', () => {
1388
+ window.templatePlayground = new TemplatePlayground();
1389
+ });