acinguiux-preact-components 0.0.1

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 (313) hide show
  1. package/package.json +56 -0
  2. package/src/content/themes/theme-acinguiux-amg/theme-acinguiux-amg.css +23 -0
  3. package/src/content/themes/theme-acinguiux-cafe/theme-acinguiux-cafe.css +47 -0
  4. package/src/content/themes/theme-acinguiux-energy/theme-acinguiux-energy.css +45 -0
  5. package/src/content/themes/theme-acinguiux-livewire/theme-acinguiux-livewire.css +22 -0
  6. package/src/content/themes/theme-acinguiux-livewire-italy/theme-acinguiux-livewire-italy.css +22 -0
  7. package/src/content/themes/theme-acinguiux-recharge/theme-acinguiux-recharge.css +49 -0
  8. package/src/content/themes/theme-allon/theme-allon.css +25 -0
  9. package/src/content/themes/theme-atlas/theme-atlas.css +31 -0
  10. package/src/content/themes/theme-aurvana/resources/favicon/apple-touch-icon.png +0 -0
  11. package/src/content/themes/theme-aurvana/resources/favicon/favico.ico +0 -0
  12. package/src/content/themes/theme-aurvana/resources/favicon/favicon-96x96.png +0 -0
  13. package/src/content/themes/theme-aurvana/resources/favicon/favicon.ico +0 -0
  14. package/src/content/themes/theme-aurvana/resources/favicon/favicon.png +0 -0
  15. package/src/content/themes/theme-aurvana/resources/favicon/favicon.svg +13 -0
  16. package/src/content/themes/theme-aurvana/resources/favicon/google-touch-icon.png +0 -0
  17. package/src/content/themes/theme-aurvana/resources/favicon/manifest.json +14 -0
  18. package/src/content/themes/theme-aurvana/resources/favicon/site.webmanifest +21 -0
  19. package/src/content/themes/theme-aurvana/resources/favicon/web-app-manifest-192x192.png +0 -0
  20. package/src/content/themes/theme-aurvana/resources/favicon/web-app-manifest-512x512.png +0 -0
  21. package/src/content/themes/theme-aurvana/theme-aurvana.css +49 -0
  22. package/src/content/themes/theme-base/theme-base.css +49 -0
  23. package/src/content/themes/theme-base2/resources/favicon/android-chrome-192x192.png +0 -0
  24. package/src/content/themes/theme-base2/resources/favicon/android-chrome-512x512.png +0 -0
  25. package/src/content/themes/theme-base2/resources/favicon/apple-touch-icon.png +0 -0
  26. package/src/content/themes/theme-base2/resources/favicon/favico.ico +0 -0
  27. package/src/content/themes/theme-base2/resources/favicon/favicon-16x16.png +0 -0
  28. package/src/content/themes/theme-base2/resources/favicon/favicon-32x32.png +0 -0
  29. package/src/content/themes/theme-base2/resources/favicon/favicon-96x96.png +0 -0
  30. package/src/content/themes/theme-base2/resources/favicon/favicon.ico +0 -0
  31. package/src/content/themes/theme-base2/resources/favicon/favicon.png +0 -0
  32. package/src/content/themes/theme-base2/resources/favicon/favicon.svg +9 -0
  33. package/src/content/themes/theme-base2/resources/favicon/google-touch-icon.png +0 -0
  34. package/src/content/themes/theme-base2/resources/favicon/manifest.json +14 -0
  35. package/src/content/themes/theme-base2/resources/favicon/site.webmanifest +1 -0
  36. package/src/content/themes/theme-base2/resources/favicon/web-app-manifest-192x192.png +0 -0
  37. package/src/content/themes/theme-base2/resources/favicon/web-app-manifest-512x512.png +0 -0
  38. package/src/content/themes/theme-base2/resources/fonts/acinguiux-typeface-la-heavy-221208.woff2 +0 -0
  39. package/src/content/themes/theme-base2/theme-base2.css +47 -0
  40. package/src/content/themes/theme-eco-marathon/theme-eco-marathon.css +22 -0
  41. package/src/content/themes/theme-energy-transition-campus-amsterdam/theme-energy-transition-campus-amsterdam.css +26 -0
  42. package/src/content/themes/theme-evpass/theme-evpass.css +46 -0
  43. package/src/content/themes/theme-nam-2025/resources/favicon/apple-touch-icon.png +0 -0
  44. package/src/content/themes/theme-nam-2025/resources/favicon/favico.ico +0 -0
  45. package/src/content/themes/theme-nam-2025/resources/favicon/favicon-96x96.png +0 -0
  46. package/src/content/themes/theme-nam-2025/resources/favicon/favicon.ico +0 -0
  47. package/src/content/themes/theme-nam-2025/resources/favicon/favicon.png +0 -0
  48. package/src/content/themes/theme-nam-2025/resources/favicon/favicon.svg +9 -0
  49. package/src/content/themes/theme-nam-2025/resources/favicon/google-touch-icon.png +0 -0
  50. package/src/content/themes/theme-nam-2025/resources/favicon/manifest.json +14 -0
  51. package/src/content/themes/theme-nam-2025/resources/favicon/site.webmanifest +21 -0
  52. package/src/content/themes/theme-nam-2025/resources/favicon/web-app-manifest-192x192.png +0 -0
  53. package/src/content/themes/theme-nam-2025/resources/favicon/web-app-manifest-512x512.png +0 -0
  54. package/src/content/themes/theme-nam-2025/theme-nam-2025.css +47 -0
  55. package/src/content/themes/theme-pennzoil/theme-pennzoil.css +36 -0
  56. package/src/content/themes/theme-quaker-state/theme-quaker-state.css +63 -0
  57. package/src/content/themes/theme-tafawoq/theme-tafawoq.css +26 -0
  58. package/src/content/themes/theme-vegetable/resources/favicon/apple-touch-icon.png +0 -0
  59. package/src/content/themes/theme-vegetable/resources/favicon/favico.ico +0 -0
  60. package/src/content/themes/theme-vegetable/resources/favicon/favicon-96x96.png +0 -0
  61. package/src/content/themes/theme-vegetable/resources/favicon/favicon.ico +0 -0
  62. package/src/content/themes/theme-vegetable/resources/favicon/favicon.png +0 -0
  63. package/src/content/themes/theme-vegetable/resources/favicon/favicon.svg +13 -0
  64. package/src/content/themes/theme-vegetable/resources/favicon/google-touch-icon.png +0 -0
  65. package/src/content/themes/theme-vegetable/resources/favicon/manifest.json +14 -0
  66. package/src/content/themes/theme-vegetable/resources/favicon/site.webmanifest +21 -0
  67. package/src/content/themes/theme-vegetable/resources/favicon/web-app-manifest-192x192.png +0 -0
  68. package/src/content/themes/theme-vegetable/resources/favicon/web-app-manifest-512x512.png +0 -0
  69. package/src/content/themes/theme-vegetable/theme-vegetable.css +49 -0
  70. package/src/content/themes/theme-zeolyst/resources/fonts/type-ar-medium.woff2 +0 -0
  71. package/src/content/themes/theme-zeolyst/theme-zeolyst.css +29 -0
  72. package/src/main/atoms/audio.js +16 -0
  73. package/src/main/atoms/box.js +5 -0
  74. package/src/main/atoms/button.js +40 -0
  75. package/src/main/atoms/card.js +22 -0
  76. package/src/main/atoms/form.js +30 -0
  77. package/src/main/atoms/heading.js +17 -0
  78. package/src/main/atoms/icon.js +24 -0
  79. package/src/main/atoms/img.js +131 -0
  80. package/src/main/atoms/input.js +55 -0
  81. package/src/main/atoms/link-text.js +21 -0
  82. package/src/main/atoms/link.js +60 -0
  83. package/src/main/atoms/list.js +12 -0
  84. package/src/main/atoms/logo.js +9 -0
  85. package/src/main/atoms/menu.js +10 -0
  86. package/src/main/atoms/message.js +5 -0
  87. package/src/main/atoms/nav-link.js +49 -0
  88. package/src/main/atoms/popup.js +47 -0
  89. package/src/main/atoms/rich-text.js +128 -0
  90. package/src/main/atoms/scroller.js +224 -0
  91. package/src/main/atoms/svg.js +65 -0
  92. package/src/main/atoms/table.js +32 -0
  93. package/src/main/atoms/textarea.js +10 -0
  94. package/src/main/atoms/time.js +12 -0
  95. package/src/main/atoms/video.js +100 -0
  96. package/src/main/export-main.js +12 -0
  97. package/src/main/export-matter.js +86 -0
  98. package/src/main/export-preact-hooks.js +1 -0
  99. package/src/main/export-preact.js +1 -0
  100. package/src/main/index.js +13 -0
  101. package/src/main/molecules/asset.js +23 -0
  102. package/src/main/molecules/glossary.js +44 -0
  103. package/src/main/molecules/links.js +23 -0
  104. package/src/main/molecules/promo-text.js +27 -0
  105. package/src/main/molecules/tags.js +15 -0
  106. package/src/main/molecules/tree.js +51 -0
  107. package/src/main/organisms/accordion-item.js +106 -0
  108. package/src/main/organisms/author.js +29 -0
  109. package/src/main/organisms/breadcrumb.js +69 -0
  110. package/src/main/organisms/call-to-action.js +24 -0
  111. package/src/main/organisms/carousel.js +178 -0
  112. package/src/main/organisms/cart-item.js +156 -0
  113. package/src/main/organisms/cart.js +162 -0
  114. package/src/main/organisms/contact-form.js +141 -0
  115. package/src/main/organisms/container/ab-test.js +47 -0
  116. package/src/main/organisms/container/default.js +6 -0
  117. package/src/main/organisms/container/filtered-section.js +293 -0
  118. package/src/main/organisms/container/footer.js +12 -0
  119. package/src/main/organisms/container/grid.js +44 -0
  120. package/src/main/organisms/container/header.js +13 -0
  121. package/src/main/organisms/container/list.js +7 -0
  122. package/src/main/organisms/container/main.js +6 -0
  123. package/src/main/organisms/container/raw.js +7 -0
  124. package/src/main/organisms/container/section.js +28 -0
  125. package/src/main/organisms/container.js +29 -0
  126. package/src/main/organisms/content-owner.js +15 -0
  127. package/src/main/organisms/date-entry.js +56 -0
  128. package/src/main/organisms/external-search.js +73 -0
  129. package/src/main/organisms/filtered-item.js +163 -0
  130. package/src/main/organisms/footer-item.js +17 -0
  131. package/src/main/organisms/image-gallery.js +164 -0
  132. package/src/main/organisms/last-modified.js +20 -0
  133. package/src/main/organisms/legal-footer.js +16 -0
  134. package/src/main/organisms/list-item.js +48 -0
  135. package/src/main/organisms/metadata.js +11 -0
  136. package/src/main/organisms/navigation.js +232 -0
  137. package/src/main/organisms/notification.js +87 -0
  138. package/src/main/organisms/order-tracker.js +203 -0
  139. package/src/main/organisms/page-header-banner.js +26 -0
  140. package/src/main/organisms/page-header.js +33 -0
  141. package/src/main/organisms/page-tags.js +14 -0
  142. package/src/main/organisms/page.js +260 -0
  143. package/src/main/organisms/press-release.js +24 -0
  144. package/src/main/organisms/product-admin.js +204 -0
  145. package/src/main/organisms/promo-banner.js +28 -0
  146. package/src/main/organisms/promo-bottom.js +23 -0
  147. package/src/main/organisms/promo-button.js +8 -0
  148. package/src/main/organisms/promo-card-cover.js +35 -0
  149. package/src/main/organisms/promo-card.js +33 -0
  150. package/src/main/organisms/promo-full.js +20 -0
  151. package/src/main/organisms/promo-image.js +22 -0
  152. package/src/main/organisms/promo-lure.js +22 -0
  153. package/src/main/organisms/promo-product-card.js +187 -0
  154. package/src/main/organisms/promo-product-full.js +293 -0
  155. package/src/main/organisms/promo-simple.js +23 -0
  156. package/src/main/organisms/quote.js +21 -0
  157. package/src/main/organisms/search-form.js +42 -0
  158. package/src/main/organisms/search-nav.js +66 -0
  159. package/src/main/organisms/search-result.js +53 -0
  160. package/src/main/organisms/slider.js +26 -0
  161. package/src/main/organisms/standalone-asset.js +22 -0
  162. package/src/main/organisms/tabs.js +277 -0
  163. package/src/main/organisms/topbar.js +83 -0
  164. package/src/main/organisms/web-component.js +53 -0
  165. package/src/main/routing/annotation.js +9 -0
  166. package/src/main/routing/component.js +138 -0
  167. package/src/main/routing/empty.js +5 -0
  168. package/src/main/routing/error-handler.js +64 -0
  169. package/src/main/routing/placeholder-image.svg +5 -0
  170. package/src/main/routing/router.js +219 -0
  171. package/src/main/shared/analytics.js +677 -0
  172. package/src/main/shared/bubble-event.js +11 -0
  173. package/src/main/shared/custom-element.js +21 -0
  174. package/src/main/shared/deep-selector.js +28 -0
  175. package/src/main/shared/disable-transparency.js +10 -0
  176. package/src/main/shared/format-time.js +8 -0
  177. package/src/main/shared/get-id.js +5 -0
  178. package/src/main/shared/get-meta.js +3 -0
  179. package/src/main/shared/get-size-class.js +3 -0
  180. package/src/main/shared/get-size.js +11 -0
  181. package/src/main/shared/h.js +88 -0
  182. package/src/main/shared/hash-jump.js +33 -0
  183. package/src/main/shared/icons/arrow-back.svg +1 -0
  184. package/src/main/shared/icons/arrow-down.svg +1 -0
  185. package/src/main/shared/icons/arrow-next.svg +1 -0
  186. package/src/main/shared/icons/arrow-tail-right.svg +1 -0
  187. package/src/main/shared/icons/arrow-tail-up.svg +1 -0
  188. package/src/main/shared/icons/arrow-up.svg +1 -0
  189. package/src/main/shared/icons/asset-download.svg +1 -0
  190. package/src/main/shared/icons/logo.svg +5 -0
  191. package/src/main/shared/icons/low-carbon-placeholder.svg +9 -0
  192. package/src/main/shared/icons/media-pause.svg +1 -0
  193. package/src/main/shared/icons/media-play.svg +1 -0
  194. package/src/main/shared/icons/navigation-burger.svg +1 -0
  195. package/src/main/shared/icons/navigation-close.svg +1 -0
  196. package/src/main/shared/icons/navigation-link.svg +1 -0
  197. package/src/main/shared/icons/navigation-refresh.svg +1 -0
  198. package/src/main/shared/icons/navigation-search.svg +1 -0
  199. package/src/main/shared/icons/navigation-share.svg +1 -0
  200. package/src/main/shared/icons/toggle-newwindow.svg +1 -0
  201. package/src/main/shared/icons.js +18 -0
  202. package/src/main/shared/id-from-string.js +5 -0
  203. package/src/main/shared/mark-selection.js +19 -0
  204. package/src/main/shared/register.js +26 -0
  205. package/src/main/shared/renderer.js +43 -0
  206. package/src/main/shared/simple-consent-api.js +70 -0
  207. package/src/main/shared/split-links.js +11 -0
  208. package/src/main/shared/t.js +60 -0
  209. package/src/main/shared/twind.js +837 -0
  210. package/src/main/shared/update-head.js +34 -0
  211. package/src/main/shared/update-scrollbar-width.js +30 -0
  212. package/src/main/shared/use-link.js +151 -0
  213. package/src/main/shared/use-persistent-state.js +42 -0
  214. package/src/main/shared/wait-for-dom-ready.js +6 -0
  215. package/src/main/shared/wcm-mode.js +4 -0
  216. package/src/wcs/components/acinguiux-preact-doc/acinguiux-preact-doc.js +207 -0
  217. package/src/wcs/components/admin-dashboard/admin-dashboard.js +487 -0
  218. package/src/wcs/components/admin-login/admin-login.js +91 -0
  219. package/src/wcs/components/bazaar-voice/bazaar-voice.js +56 -0
  220. package/src/wcs/components/chatbot-koreai/chatbot-koreai.js +176 -0
  221. package/src/wcs/components/chatbot-koreai/koreai-transport.js +217 -0
  222. package/src/wcs/components/chatbot-ms/chatbot-ms.js +210 -0
  223. package/src/wcs/components/chatbot-test/chatbot-test.js +44 -0
  224. package/src/wcs/components/comparison-chart/comparison-chart.js +111 -0
  225. package/src/wcs/components/consent-banner/consent-banner.js +248 -0
  226. package/src/wcs/components/consent-banner/icons/ccpa.svg +6 -0
  227. package/src/wcs/components/consent-banner/icons/info.svg +1 -0
  228. package/src/wcs/components/consent-banner/provider-onetrust.js +131 -0
  229. package/src/wcs/components/decision-tree/arrow-back.svg +3 -0
  230. package/src/wcs/components/decision-tree/badges.js +37 -0
  231. package/src/wcs/components/decision-tree/decision-tree.js +162 -0
  232. package/src/wcs/components/dynamic-contact-details/dynamic-contact-details.js +111 -0
  233. package/src/wcs/components/example-accordion/example-accordion.js +10 -0
  234. package/src/wcs/components/example-asset/example-asset.js +12 -0
  235. package/src/wcs/components/example-form/example-form.js +59 -0
  236. package/src/wcs/components/example-nested/example-nested.js +10 -0
  237. package/src/wcs/components/example-routing/example-routing.js +51 -0
  238. package/src/wcs/components/example-rtl/example-rtl.js +28 -0
  239. package/src/wcs/components/example-tabs/example-tabs.js +12 -0
  240. package/src/wcs/components/example-web-component/example-web-component.js +34 -0
  241. package/src/wcs/components/floating-button/floating-button.js +17 -0
  242. package/src/wcs/components/formstack-form/fields/address.js +38 -0
  243. package/src/wcs/components/formstack-form/fields/checkbox.js +42 -0
  244. package/src/wcs/components/formstack-form/fields/date.js +22 -0
  245. package/src/wcs/components/formstack-form/fields/description.js +8 -0
  246. package/src/wcs/components/formstack-form/fields/input.js +8 -0
  247. package/src/wcs/components/formstack-form/fields/name.js +39 -0
  248. package/src/wcs/components/formstack-form/fields/radio.js +24 -0
  249. package/src/wcs/components/formstack-form/fields/rating.js +53 -0
  250. package/src/wcs/components/formstack-form/fields/section.js +8 -0
  251. package/src/wcs/components/formstack-form/fields/select.js +10 -0
  252. package/src/wcs/components/formstack-form/fields/textarea.js +8 -0
  253. package/src/wcs/components/formstack-form/fields/wrapper.js +11 -0
  254. package/src/wcs/components/formstack-form/formstack-form.js +280 -0
  255. package/src/wcs/components/fuel-prices/fuel-prices.js +45 -0
  256. package/src/wcs/components/furniture-overview/furniture-overview.js +115 -0
  257. package/src/wcs/components/gauge-value/gauge-value.js +65 -0
  258. package/src/wcs/components/help-centre/api.js +150 -0
  259. package/src/wcs/components/help-centre/help-centre.js +400 -0
  260. package/src/wcs/components/help-centre/icon-search.svg +1 -0
  261. package/src/wcs/components/image-gen/admin-panel.js +248 -0
  262. package/src/wcs/components/image-gen/image-gen.js +385 -0
  263. package/src/wcs/components/image-gen/labels.js +37 -0
  264. package/src/wcs/components/image-gen/use-api.js +392 -0
  265. package/src/wcs/components/inspired-gallery/inspired-gallery.js +118 -0
  266. package/src/wcs/components/launch-container/launch-container.js +95 -0
  267. package/src/wcs/components/launch-container/ledger.js +140 -0
  268. package/src/wcs/components/lng-map/lng-map.js +44 -0
  269. package/src/wcs/components/mouseflow-analytics/mouseflow-analytics.js +39 -0
  270. package/src/wcs/components/msds-search/msds-search.js +127 -0
  271. package/src/wcs/components/msds-search/navigation-search.svg +3 -0
  272. package/src/wcs/components/product-catalogue/icon-back.svg +3 -0
  273. package/src/wcs/components/product-catalogue/icon-cart.svg +3 -0
  274. package/src/wcs/components/product-catalogue/icon-close.svg +3 -0
  275. package/src/wcs/components/product-catalogue/product-catalogue.js +215 -0
  276. package/src/wcs/components/product-links/icon-cart.svg +3 -0
  277. package/src/wcs/components/product-links/product-links.js +43 -0
  278. package/src/wcs/components/rio-iframe/rio-iframe.js +137 -0
  279. package/src/wcs/components/salsify-products/filter-tools.js +60 -0
  280. package/src/wcs/components/salsify-products/icon-cart.svg +3 -0
  281. package/src/wcs/components/salsify-products/process-products.js +53 -0
  282. package/src/wcs/components/salsify-products/route-tools.js +54 -0
  283. package/src/wcs/components/salsify-products/salsify-products.js +281 -0
  284. package/src/wcs/components/shout-out/shout-out.js +51 -0
  285. package/src/wcs/components/simple-chart/simple-chart.js +53 -0
  286. package/src/wcs/components/single-stat/single-stat.js +85 -0
  287. package/src/wcs/components/site-feedback/site-feedback.js +56 -0
  288. package/src/wcs/components/skds-search/navigation-search.svg +3 -0
  289. package/src/wcs/components/skds-search/skds-search.js +103 -0
  290. package/src/wcs/components/smart-banner/smart-banner.js +104 -0
  291. package/src/wcs/components/standalone-table/arrow-up-down.svg +3 -0
  292. package/src/wcs/components/standalone-table/arrow-up.svg +3 -0
  293. package/src/wcs/components/standalone-table/standalone-table.js +440 -0
  294. package/src/wcs/components/station-locator/station-locator.js +49 -0
  295. package/src/wcs/components/store-badges/badges.js +60 -0
  296. package/src/wcs/components/store-badges/store-badges.js +93 -0
  297. package/src/wcs/components/topbar-button/person.svg +1 -0
  298. package/src/wcs/components/topbar-button/topbar-button.js +22 -0
  299. package/src/wcs/components/universal-gallery/universal-gallery.js +308 -0
  300. package/src/wcs/components/zendesk-chat/zendesk-chat.js +133 -0
  301. package/src/wcs/shared/chat-bot/README.md +61 -0
  302. package/src/wcs/shared/chat-bot/chat-bot.js +216 -0
  303. package/src/wcs/shared/chat-bot/resources/arrow-next.svg +1 -0
  304. package/src/wcs/shared/chat-bot/resources/navigation-close.svg +1 -0
  305. package/src/wcs/shared/chat-bot/resources/person.svg +1 -0
  306. package/src/wcs/shared/chat-bot/resources/upload.svg +1 -0
  307. package/src/wcs/shared/filtered-data/README.md +52 -0
  308. package/src/wcs/shared/filtered-data/fetch-data.js +33 -0
  309. package/src/wcs/shared/filtered-data/filtered-data.js +337 -0
  310. package/src/wcs/shared/promo-with-popup/icon-close.svg +3 -0
  311. package/src/wcs/shared/promo-with-popup/icon-next.svg +3 -0
  312. package/src/wcs/shared/promo-with-popup/icon-prev.svg +3 -0
  313. package/src/wcs/shared/promo-with-popup/promo-with-popup.js +93 -0
@@ -0,0 +1,53 @@
1
+ import { Box } from '../atoms/box.js'
2
+ import { Heading } from '../atoms/heading.js'
3
+ import { Icon } from '../atoms/icon.js'
4
+ import { Link } from '../atoms/link.js'
5
+ import { RichText } from '../atoms/rich-text.js'
6
+ import h from '../shared/h.js'
7
+ import idFromString from '../shared/id-from-string.js'
8
+ import { ARROW_NEXT } from '../shared/icons.js'
9
+
10
+ function LinkTrail ({ _model }) {
11
+ const { links } = _model
12
+
13
+ // Get a list of <LI> elements.
14
+ const lis = []
15
+ for (let ii = 0; ii < links.length; ++ii) {
16
+ const { [ii]: link } = links
17
+ const isLast = ii === links.length - 1
18
+
19
+ // Item
20
+ lis.push(h('li',
21
+ h('span',
22
+ h(Link, { _variant: 'simple', _model: link })
23
+ )
24
+ ))
25
+
26
+ // >
27
+ isLast || lis.push(
28
+ h('li', { 'aria-hidden': true },
29
+ h(Icon, { _size: 'xs', _rtlFlip: true }, ARROW_NEXT)
30
+ )
31
+ )
32
+ }
33
+
34
+ return h('div',
35
+ h('ol', {
36
+ className: 'flex sm:flex-wrap md:flex-wrap items-center p-0 space-x-2',
37
+ children: lis
38
+ })
39
+ )
40
+ }
41
+
42
+ export function SearchResult ({ _model, ...props }) {
43
+ const { links, text } = _model
44
+ const lastBreadcrumbLink = links?.at(-1)
45
+
46
+ return h(Box, { ...props, className: 'bg-bga text-txa rounded-2xl' },
47
+ h(Heading, { _level: 3, id: idFromString(lastBreadcrumbLink.name) },
48
+ h(Link, { _model: { ...lastBreadcrumbLink, icon: null }, _variant: 'full' })
49
+ ),
50
+ h(LinkTrail, { _model: { links: _model.links.slice(0, -1) } }),
51
+ h(RichText, text)
52
+ )
53
+ }
@@ -0,0 +1,26 @@
1
+ import { Scroller } from '../atoms/scroller.js'
2
+ import h from '../shared/h.js'
3
+
4
+ const VARIANTS = {
5
+ xl: [1.25, 1.25, 1.25]
6
+ }
7
+
8
+ export function Slider ({ _model, _variant, children, ...props }) {
9
+ const autoplay = props.autoplay ?? _model?.autoplay ?? false
10
+ const infinite = props.infinite ?? _model?.infinite ?? false
11
+ const interval = props.interval ?? _model?.interval ?? 3500
12
+ const hideControls = props.hideControls ?? _model?.hideControls ?? false
13
+
14
+ return h('div', {
15
+ ...props,
16
+ className: 'w-full',
17
+ children: h(Scroller, {
18
+ _count: VARIANTS[_variant],
19
+ _autoplay: autoplay,
20
+ _infinite: infinite,
21
+ _interval: interval,
22
+ _hideControls: hideControls,
23
+ children
24
+ })
25
+ })
26
+ }
@@ -0,0 +1,22 @@
1
+ import { Heading } from '../atoms/heading.js'
2
+ import { Asset } from '../molecules/asset.js'
3
+ import { ValidationError } from '../routing/error-handler.js'
4
+ import h from '../shared/h.js'
5
+
6
+ export function StandaloneAsset ({ _model, ...props }) {
7
+ const { asset, title } = _model
8
+ if (!asset.src) {
9
+ throw new ValidationError()
10
+ }
11
+
12
+ // StandaloneAsset should inherit parent colour.
13
+ return h('div', { ...props, _color: null, className: 'space-y-2' }, [
14
+ title && h(Heading, { _level: 3 }, title),
15
+ h('figure', { className: 'col-span-2 space-y-2' },
16
+ h('div', { className: 'rounded-2xl overflow-hidden' },
17
+ h(Asset, { _model })
18
+ ),
19
+ asset.caption && h('figcaption', asset.caption)
20
+ )
21
+ ])
22
+ }
@@ -0,0 +1,277 @@
1
+ /* global ResizeObserver, getComputedStyle */
2
+ import { useEffect, useMemo, useRef, useState } from 'preact/hooks'
3
+ import { Icon } from '../atoms/icon.js'
4
+ import { Menu } from '../atoms/menu.js'
5
+ import { NavLink } from '../atoms/nav-link.js'
6
+ import { ValidationError } from '../routing/error-handler.js'
7
+ import getId from '../shared/get-id.js'
8
+ import h from '../shared/h.js'
9
+ import { ARROW_BACK, ARROW_NEXT } from '../shared/icons.js'
10
+ import t from '../shared/t.js'
11
+ import { MEDIUM } from '../shared/twind.js'
12
+
13
+ const SCROLL_TOLERANCE = 2
14
+ const MOBILE_STYLE = 'overflow-x: auto; overflow-y: hidden; flex-wrap: nowrap'
15
+
16
+ export function Tabs ({ _model, _variant, _color, children, ...props }) {
17
+ // We cannot exit here on falsy model to avoid breaking rules of hooks.
18
+ const rawLinks = _model?.links || []
19
+ if (rawLinks.length === 0) {
20
+ throw new ValidationError()
21
+ }
22
+
23
+ const hasPanels = Boolean(children?.length)
24
+
25
+ // Generate ids for tabs and panels.
26
+ const ids = useMemo(() => ({
27
+ tabs: rawLinks.map(getId), // Needed for the compact variant regardless of panel presence.
28
+ panels: hasPanels && rawLinks.map(getId)
29
+ }), [])
30
+ // Configure links.
31
+ const tabPanelHashes = useMemo(() => hasPanels && rawLinks.map(link =>
32
+ link.name ? `tab-${hashFromString(link.name)}` : getId()), []
33
+ )
34
+ const links = useMemo(() => hasPanels
35
+ ? rawLinks.map((link, i) => ({ ...link, value: `#${tabPanelHashes[i]}` }))
36
+ : rawLinks)
37
+
38
+ const [selectedIndex] = useSelectedTab({ rawLinks, tabPanelHashes })
39
+
40
+ return h('div', { ...props, className: 'w-full relative', style: '--actual-bg-color: transparent' },
41
+ _variant === 'compact'
42
+ ? h(TabDropdown, { links, hasPanels, ids, selectedIndex })
43
+ : h(TabButtons, { links, hasPanels, ids, selectedIndex }),
44
+ hasPanels && h(TabPanels, { panels: children, ids, selectedIndex })
45
+ )
46
+ }
47
+
48
+ function getInheritedBgColor (element) {
49
+ const defaultColor = 'rgba(0, 0, 0, 0)'
50
+ if (element) {
51
+ const bgColor = getComputedStyle(element).backgroundColor
52
+ if (bgColor !== defaultColor) {
53
+ return bgColor
54
+ }
55
+
56
+ // Needs to work in Shadow DOM.
57
+ return getInheritedBgColor(element?.parentElement ?? element?.parentNode?.host)
58
+ }
59
+
60
+ return defaultColor
61
+ }
62
+
63
+ function hashFromString (text) {
64
+ return text?.trim().toLowerCase().replaceAll(/\s+/g, '-')
65
+ }
66
+
67
+ function TabButtons ({ links, hasPanels, ids, selectedIndex }) {
68
+ const ref = useRef(null)
69
+ const [state, setState] = useState({ left: false, right: false })
70
+
71
+ // Update left and right arrows based on the scroll.
72
+ const updateBlurs = el => {
73
+ setState({
74
+ left: el.scrollWidth > el.clientWidth && Math.abs(el.scrollLeft) > SCROLL_TOLERANCE,
75
+ right: el.scrollWidth > el.clientWidth && Math.abs(el.scrollLeft) < el.scrollWidth - el.clientWidth - SCROLL_TOLERANCE
76
+ })
77
+ }
78
+
79
+ useEffect(() => {
80
+ const outerContainer = ref?.current
81
+ if (!outerContainer) {
82
+ return
83
+ }
84
+
85
+ // Tabs do not support palettes.
86
+ // The left and right gradient must therefore use the actual background colour.
87
+ // Since there is no currentBackgroundColour variable (akin to currentColour), we need to get it via ref.
88
+ const bgColor = getInheritedBgColor(outerContainer)
89
+ outerContainer.style.setProperty('--actual-bg-color', bgColor)
90
+
91
+ // Update left and right arrows on resize.
92
+ const tabContainer = outerContainer.querySelector('[role="tablist"]')
93
+ const resizeObserver = new ResizeObserver(() => updateBlurs(tabContainer))
94
+ resizeObserver.observe(tabContainer)
95
+ }, [])
96
+
97
+ return h('div', {
98
+ className: `relative border-txa/20 border-b ${hasPanels ? 'mb-5' : ''}`,
99
+ ref,
100
+ style: '--actual-bg-color: transparent',
101
+ children: [
102
+ h(Arrow, { right: false, visible: state.left }),
103
+ h('div', { // Tabs
104
+ // Make it scrollable on mobile and touch (and with mobile class for testing).
105
+ _style: id => `
106
+ ${id} { scrollbar-width: none; -ms-overflow-style: none }
107
+ ${id}::-webkit-scrollbar { display: none }
108
+ .mobile ${id} { ${MOBILE_STYLE} }
109
+ @media screen and (max-width: ${MEDIUM}px) and (hover: none) {
110
+ ${id} { ${MOBILE_STYLE} }
111
+ }
112
+ `,
113
+ onScroll: event => updateBlurs(event.target),
114
+ className: 'w-full flex flex-wrap px-6',
115
+ role: 'tablist',
116
+ 'aria-owns': ids.tabs?.join?.(' '),
117
+ children: links.map((link, ii) => {
118
+ const selected = ii === selectedIndex
119
+ return h('div', { className: 'shrink-0' },
120
+ h(NavLink, {
121
+ id: ids.tabs?.[ii],
122
+ className: 'cursor-pointer',
123
+ role: 'tab',
124
+ 'aria-controls': ids.panels?.[ii],
125
+ 'aria-selected': selected,
126
+ _selection: 'bottom',
127
+ _size: 'lg',
128
+ _model: {
129
+ value: link.value,
130
+ name: link.name === 'All' ? t('All') : link.name,
131
+ selected
132
+ }
133
+ })
134
+ )
135
+ })
136
+ }),
137
+ h(Arrow, { right: true, visible: state.right })
138
+ ]
139
+ })
140
+ }
141
+
142
+ function Arrow ({ right, visible }) {
143
+ const icon = { false: ARROW_BACK, true: ARROW_NEXT }[right]
144
+ const style = {
145
+ false: 'left: 0; justify-content: left; background: linear-gradient(90deg, var(--actual-bg-color) 33%, transparent)',
146
+ true: 'right: 0; justify-content: right; background: linear-gradient(-90deg, var(--actual-bg-color) 33%, transparent)'
147
+ }[document.dir === 'rtl' ? !right : right]
148
+
149
+ return h('div', {
150
+ className: `absolute top-0 bottom-0 w-12 bg-bga items-center animate-fade ${visible ? 'flex' : 'hidden'}`,
151
+ style,
152
+ children: h(Icon, { _size: 'xs', _rtlFlip: true }, icon)
153
+ })
154
+ }
155
+
156
+ function TabDropdown ({ links, hasPanels, ids, selectedIndex }) {
157
+ const [isExpanded, setIsExpanded] = useState(false)
158
+ const buttonRef = useRef(null)
159
+ const menuId = useMemo(() => getId(), [])
160
+ const currentLink = links[selectedIndex]
161
+
162
+ const closeDropdown = () => {
163
+ buttonRef.current?.base?.querySelector?.('a')?.focus()
164
+ setIsExpanded(false)
165
+ }
166
+
167
+ let menu
168
+ if (isExpanded) {
169
+ // Show menu.
170
+ menu = h(Menu, {
171
+ id: menuId,
172
+ onClick: closeDropdown,
173
+ children: h('div', {
174
+ className: 'py-1',
175
+ role: 'tablist',
176
+ 'aria-owns': ids.tabs?.join?.(' '),
177
+ children: links.map((link, ii) => h(NavLink, {
178
+ id: ids.tabs?.[ii],
179
+ _selection: 'right',
180
+ role: 'tab',
181
+ 'aria-controls': ids.panels?.[ii],
182
+ 'aria-selected': ii === selectedIndex,
183
+ _model: {
184
+ ...link,
185
+ name: link.name === 'All' ? t('All') : link.name,
186
+ selected: ii === selectedIndex
187
+ }
188
+ }))
189
+ })
190
+ })
191
+ } else {
192
+ menu = h('div', { id: menuId, className: 'hidden' })
193
+ }
194
+
195
+ return h('div', {
196
+ className: `border-txa/20 border-b ${hasPanels ? 'mb-5' : ''} flex`,
197
+ onKeyDown: event => { event.key === 'Escape' && closeDropdown() },
198
+ children: h('div', { className: 'relative mx-6' },
199
+ h(NavLink, {
200
+ _selection: 'bottom',
201
+ _size: 'lg',
202
+ _highlighted: isExpanded,
203
+ _expanded: false,
204
+ _model: { ...currentLink, selected: true },
205
+ ref: buttonRef,
206
+ tabindex: '0', // Applies focus outline.
207
+ role: 'button',
208
+ 'aria-expanded': isExpanded,
209
+ 'aria-controls': menuId,
210
+ onClick: event => {
211
+ event.preventDefault()
212
+ if (isExpanded) {
213
+ closeDropdown()
214
+ } else {
215
+ setIsExpanded(true)
216
+ }
217
+ }
218
+ }),
219
+ menu
220
+ )
221
+ })
222
+ }
223
+
224
+ function TabPanels ({ panels, ids, selectedIndex }) {
225
+ return panels?.map?.((child, ii) => {
226
+ const selected = ii === selectedIndex
227
+ const id = ids.panels?.[ii]
228
+ return (selected || id) && h('div', {
229
+ className: `${selected ? 'animate-fade' : 'hidden'}`,
230
+ ...id && {
231
+ role: 'tabpanel',
232
+ id
233
+ }
234
+ }, selected ? child : undefined)
235
+ })
236
+ }
237
+
238
+ function useSelectedTab ({ rawLinks, tabPanelHashes }) {
239
+ const linksSelectedIndex = rawLinks.findIndex(l => l.selected === true) || 0
240
+ const lastLiksSelectedIndex = useRef(linksSelectedIndex)
241
+
242
+ const [selectedIndex, setSelectedIndex] = useState(getSelectedIndexByHash)
243
+
244
+ function getSelectedIndexByHash (defaultOnlyIfNoHash = false) {
245
+ const hash = globalThis.decodeURIComponent(globalThis.location.hash.substring(1))
246
+ const anchorIndex = tabPanelHashes?.findIndex?.(id => id === hash)
247
+ if (anchorIndex >= 0) {
248
+ return anchorIndex
249
+ } else {
250
+ return (!defaultOnlyIfNoHash || !hash) ? Math.max(linksSelectedIndex, 0) : null
251
+ }
252
+ }
253
+
254
+ useEffect(() => {
255
+ const hashChangeHandler = () => {
256
+ // Prevent resetting current tab if the hash was changed to an unknown value (e.g. anchor or a different Tabs organism).
257
+ const newSelectedIndex = getSelectedIndexByHash(true)
258
+ newSelectedIndex !== null && setSelectedIndex(newSelectedIndex)
259
+ }
260
+
261
+ globalThis.addEventListener('hashchange', hashChangeHandler)
262
+
263
+ return () => {
264
+ globalThis.removeEventListener('hashchange', hashChangeHandler)
265
+ }
266
+ }, [])
267
+
268
+ // React on model selected flag change
269
+ useEffect(() => {
270
+ if ((linksSelectedIndex !== lastLiksSelectedIndex.current) && (linksSelectedIndex >= 0)) {
271
+ setSelectedIndex(linksSelectedIndex)
272
+ lastLiksSelectedIndex.current = linksSelectedIndex
273
+ }
274
+ }, [linksSelectedIndex !== lastLiksSelectedIndex.current])
275
+
276
+ return [selectedIndex]
277
+ }
@@ -0,0 +1,83 @@
1
+ import { useMemo, useState, useEffect } from 'preact/hooks'
2
+ import { Button } from '../atoms/button.js'
3
+ import { Menu } from '../atoms/menu.js'
4
+ import { NavLink } from '../atoms/nav-link.js'
5
+ import { ValidationError } from '../routing/error-handler.js'
6
+ import h from '../shared/h.js'
7
+ import markSelection from '../shared/mark-selection.js'
8
+ import splitLinks from '../shared/split-links.js'
9
+
10
+ export function Topbar ({ _model, _variant, ...props }) {
11
+ const { links } = _model
12
+ if (links.length === 0) {
13
+ throw new ValidationError()
14
+ }
15
+
16
+ const [mainLinks, sideLinks] = useMemo(() => splitLinks(links), [links])
17
+ markSelection(mainLinks)
18
+ const left = _variant === 'left' || Boolean(sideLinks)
19
+
20
+ return h('div', {
21
+ ...props,
22
+ className: 'w-full bg-bga text-txa',
23
+ children: h('div', { className: 'm-auto max-w-page flex', role: 'list' },
24
+ h(MainLinks, { links: mainLinks, left }),
25
+ sideLinks && h(SideLinks, { links: sideLinks })
26
+ )
27
+ })
28
+ }
29
+
30
+ function MainLinks ({ links, left = false }) {
31
+ return [
32
+ !left && h('div', { className: 'grow' }),
33
+ h('div', { className: 'flex' },
34
+ links.map(link => h('div', { className: left ? 'grow-0 text-sm' : 'grow-0', role: 'listitem' },
35
+ h(NavLink, { _model: link, _selection: 'top' })
36
+ ))
37
+ )
38
+ ]
39
+ }
40
+
41
+ function SideLinks ({ links }) {
42
+ const [isExpanded, setExpanded] = useState(false)
43
+
44
+ useEffect(() => {
45
+ const handler = () => setExpanded(false)
46
+ globalThis.addEventListener('route', handler)
47
+ return () => globalThis.removeEventListener('route', handler)
48
+ }, [])
49
+
50
+ if (!links || links.length === 0) {
51
+ return null
52
+ }
53
+
54
+ const moreThanOne = links.length > 1
55
+ const onKeyUp = event => event.key.startsWith('Esc') && setExpanded(false)
56
+
57
+ return [
58
+ h('div', { className: 'grow' }),
59
+ h('div', { className: 'grow-0 flex items-center h-12 relative px-1', onKeyUp },
60
+ !moreThanOne && h(Button, { _model: links[0], _size: 'xs' }),
61
+ moreThanOne && [
62
+ h(Button, {
63
+ _expanded: isExpanded,
64
+ _model: { ...links[0], value: undefined },
65
+ _size: 'xs',
66
+ onClick (event) {
67
+ event.preventDefault()
68
+ setExpanded(expanded => !expanded)
69
+ }
70
+ }),
71
+ isExpanded && h(Menu, { role: 'list', style: 'top: calc(100% + 8px); inset-inline-end: 4px' },
72
+ h('div', { className: 'py-1' },
73
+ links.slice(1).map(link =>
74
+ h('div', { role: 'listitem' },
75
+ h(NavLink, { _model: link, _selection: 'right' })
76
+ )
77
+ )
78
+ )
79
+ )
80
+ ]
81
+ )
82
+ ]
83
+ }
@@ -0,0 +1,53 @@
1
+ import { useMemo } from 'preact/hooks'
2
+ import { Message } from '../atoms/message.js'
3
+ import { Annotation } from '../routing/annotation.js'
4
+ import h from '../shared/h.js'
5
+ import { isPublish } from '../shared/wcm-mode.js'
6
+
7
+ function isInvalidAttribute (name) {
8
+ try {
9
+ document.createAttribute(name)
10
+ return false
11
+ } catch {
12
+ return true
13
+ }
14
+ }
15
+
16
+ export function WebComponent ({ _model, ...props }) {
17
+ const { links } = _model
18
+ const src = links?.[0]?.value
19
+ const [elementName, attrs] = useMemo(() => [
20
+ src
21
+ ?.replace(/\?.*/, '')
22
+ .split('/')
23
+ .pop()
24
+ .split('.')
25
+ .shift()
26
+ .replaceAll(/[^a-zA-Z-]/g, ''),
27
+ links
28
+ .slice(1)
29
+ .reduce((obj, link) => ({ ...obj, [link.name]: link.value }), {})
30
+ ], [src, links])
31
+
32
+ // Validate attrs.
33
+ const invalidAttrNames = useMemo(() => Object.keys(attrs).filter(isInvalidAttribute), [attrs])
34
+
35
+ // Allow only same origin script.
36
+ if (!src || globalThis.origin !== new URL(src, globalThis.origin).origin) {
37
+ return h(Message, props, 'Invalid script source.')
38
+ }
39
+
40
+ // Invalid attrs.
41
+ if (invalidAttrNames.length) {
42
+ const formattedNames = invalidAttrNames.map(attrName => `"${attrName}"`).join(', ')
43
+ return h(Message, props, `Invalid attribute name: ${formattedNames}`)
44
+ }
45
+
46
+ return h('div', { ...props, className: 'w-full h-full' },
47
+ !isPublish && h('div', { className: 'relative' },
48
+ h(Annotation, elementName) // Annotate web components on author.
49
+ ),
50
+ h('script', { src, type: 'module', crossorigin: 'anonymous', async: true }),
51
+ h(elementName, { ...attrs, className: 'w-full h-full' })
52
+ )
53
+ }
@@ -0,0 +1,9 @@
1
+ import h from '../shared/h.js'
2
+
3
+ export function Annotation ({ children }) {
4
+ return h('div', {
5
+ // Use z-20 for floating elements.
6
+ className: 'absolute start-0 top-0 bg-txa text-bga text-xs uppercase z-20 tracking-widest px-1',
7
+ children
8
+ })
9
+ }
@@ -0,0 +1,138 @@
1
+ import { Message } from '../atoms/message.js'
2
+ import * as matter from '../export-matter.js'
3
+ import h from '../shared/h.js'
4
+ import { isPublish } from '../shared/wcm-mode.js'
5
+ import { Empty } from './empty.js'
6
+ import { ErrorHandler } from './error-handler.js'
7
+
8
+ const AUTHOR_SNIPPET_ORGANISMS = {
9
+ Notification: 'Notification'
10
+ }
11
+
12
+ // Track all component models by the Preact key.
13
+ export const componentModels = new Map()
14
+
15
+ function normalizeNestedColumns (componentModel, parentComponentModel) {
16
+ if (parentComponentModel?.colspan) {
17
+ // Make sure the child is capped.
18
+ if (!componentModel.colspan) {
19
+ componentModel.colspan = parentComponentModel.colspan
20
+ }
21
+
22
+ // Reset colstart if larger than available width of the container.
23
+ if (componentModel.colstart && componentModel.colstart > parentComponentModel.colspan) {
24
+ componentModel.colstart = 1
25
+ }
26
+
27
+ // Adjust colspan if colstart + colspan does not fit in the container.
28
+ const colstart = componentModel.colstart || 1
29
+ if (componentModel.colspan + colstart + 1 > parentComponentModel.colspan) {
30
+ componentModel.colspan = parentComponentModel.colspan - colstart + 1
31
+ }
32
+ }
33
+ }
34
+
35
+ function getChildren (componentModel, trail) {
36
+ // Container handling.
37
+ const children = []
38
+ const _wrap = []
39
+
40
+ const childrenToIterate = componentModel?.children ?? []
41
+ for (const [ii, childComponentModel] of childrenToIterate.entries()) {
42
+ normalizeNestedColumns(childComponentModel, componentModel)
43
+
44
+ // Get wrapper configuration for container.
45
+ const { colstart, colspan } = childComponentModel
46
+ _wrap.push({ colstart, colspan })
47
+
48
+ // Get children
49
+ children.push(h(Component, {
50
+ _componentModel: childComponentModel,
51
+ _model: childComponentModel.model,
52
+ _parentColspan: colspan,
53
+ _trail: trail && [...trail, ii]
54
+ }))
55
+ }
56
+
57
+ return { _wrap, children }
58
+ }
59
+
60
+ function resolveOrganism (_componentModel) {
61
+ let [organismName, variantName] = (_componentModel?.organism ?? '').split('.')
62
+ variantName = variantName?.toLowerCase()
63
+
64
+ let Organism = matter[organismName]
65
+ if (!Organism) {
66
+ Organism = Empty
67
+ organismName = 'Empty'
68
+ console.log(`Unable to resolve organism: ${_componentModel.id}`)
69
+ }
70
+
71
+ return { Organism, organismName, variantName }
72
+ }
73
+
74
+ function fastHash (str) {
75
+ let hash = 0
76
+ for (let ii = 0; ii < str.length; ++ii) {
77
+ hash = (hash << 5) - hash + str.codePointAt(ii)
78
+ }
79
+ return hash >>> 0
80
+ }
81
+
82
+ function getKey (componentModel, trail) {
83
+ // Return trail for containers.
84
+ if (trail && componentModel.children) {
85
+ return trail.join('/')
86
+ }
87
+
88
+ // Return hash for web components
89
+ if (componentModel.organism === 'WebComponent') {
90
+ return fastHash(JSON.stringify(componentModel.model))
91
+ }
92
+
93
+ // Do not use keys for regular components.
94
+ return componentModel.id
95
+ }
96
+
97
+ export function Component ({ _componentModel, _parentColspan, _trail = ['0'] }) {
98
+ const { Organism, organismName, variantName } = resolveOrganism(_componentModel)
99
+
100
+ // Clear component models for each new page.
101
+ if (_componentModel?.organism === 'Page') {
102
+ componentModels.clear()
103
+ }
104
+
105
+ // Reset trail for main container (and children)
106
+ if (_componentModel?.organism === 'Container.Main') {
107
+ _trail = null
108
+ }
109
+
110
+ // Get key and store component model.
111
+ const key = getKey(_componentModel, _trail)
112
+ componentModels.set(key, _componentModel)
113
+
114
+ // Get organism properties.
115
+ const organismProps = {
116
+ key,
117
+ _color: _componentModel.color,
118
+ _model: _componentModel.model,
119
+ _variant: variantName,
120
+ _parentColspan,
121
+ _mobileCols: _componentModel.mobileCols,
122
+ 'data-key': key,
123
+ 'data-name': organismName,
124
+ id: _componentModel.id
125
+ }
126
+
127
+ if (!isPublish && Object.keys(AUTHOR_SNIPPET_ORGANISMS).includes(organismName)) {
128
+ // Show author snippet for selected components.
129
+ return h(Message, AUTHOR_SNIPPET_ORGANISMS[organismName])
130
+ }
131
+
132
+ // Resolve children and wrap configuration.
133
+ const { _wrap, children } = getChildren(_componentModel, _trail)
134
+
135
+ return h(ErrorHandler,
136
+ h(Organism, { ...organismProps, _wrap }, children)
137
+ )
138
+ }
@@ -0,0 +1,5 @@
1
+ import h from '../shared/h.js'
2
+
3
+ export function Empty (props) {
4
+ return h('div', { ...props })
5
+ }