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,162 @@
1
+ import ICON_BACK from './arrow-back.svg'
2
+ import { google, apple } from './badges.js'
3
+
4
+ const { h, register, matter, preactHooks } = globalThis.ami
5
+ const { Asset, Box, Button, Heading, Link, RichText, SVG } = matter
6
+ const { useState, useEffect, useRef } = preactHooks
7
+
8
+ function arrayStartsWith (array, starter) {
9
+ for (const [ii, element] of starter.entries()) {
10
+ if (array[ii] !== element) {
11
+ return false
12
+ }
13
+ }
14
+
15
+ return true
16
+ }
17
+
18
+ function getBranch (branches, trail) {
19
+ for (const branch of branches) {
20
+ const branchPath = branch[0]
21
+ if (arrayStartsWith(branchPath, trail)) {
22
+ return branch
23
+ }
24
+ }
25
+
26
+ return null
27
+ }
28
+
29
+ function getNextQuestion (branch, trail, questions) {
30
+ const branchPath = branch[0]
31
+
32
+ let ii = trail.length
33
+ while (branchPath[ii] === null) {
34
+ trail.push(null)
35
+ ++ii
36
+ }
37
+
38
+ return questions[ii] // Will return undefined when end is reached.
39
+ }
40
+
41
+ function DecisionTree ({ src }) {
42
+ if (!src) {
43
+ return null // Exit early if src is missing
44
+ }
45
+ const [state, setState] = useState()
46
+ const key = useRef(0)
47
+ useEffect(() => {
48
+ (async () => {
49
+ const res = await fetch(src)
50
+ const obj = await res.json()
51
+ setState({ ...obj, trail: [] })
52
+ })().catch(console.error)
53
+ }, [src])
54
+
55
+ if (!state) {
56
+ return null
57
+ }
58
+
59
+ const branch = getBranch(state.branches, state.trail)
60
+ const question = getNextQuestion(branch, state.trail, state.questions)
61
+ const results = question ? null : branch[1].map(id => state.results[id])
62
+
63
+ const handleAnswer = event => {
64
+ event.preventDefault()
65
+ const answer = event.target.textContent
66
+ state.trail.push(answer)
67
+ setState({ ...state })
68
+ key.current++
69
+ }
70
+
71
+ const handleBack = event => {
72
+ event.preventDefault()
73
+
74
+ const removeNulls = () => {
75
+ while (state.trail.at(-1) === null) {
76
+ state.trail.pop()
77
+ }
78
+ }
79
+
80
+ removeNulls()
81
+ state.trail.pop()
82
+ removeNulls()
83
+
84
+ setState({ ...state })
85
+ key.current++
86
+ }
87
+
88
+ return h('div',
89
+ // Question.
90
+ question && h(Box, { key: key.current, className: 'rounded-2xl bg-bga text-txa grid lg:grid-cols-2 gap-5 animate-fade' },
91
+ h('div', { className: 'flex flex-col justify-center space-y-5' },
92
+ h('div', { className: 'text-center' },
93
+ h(Heading, { _level: 3 }, question.text)
94
+ ),
95
+ h('div', { className: 'flex justify-center lg:flex-nowrap flex-wrap gap-5' },
96
+ question.answers.map(answer =>
97
+ h(Button, {
98
+ _model: { name: answer },
99
+ _wide: true,
100
+ onClick: handleAnswer
101
+ })
102
+ )
103
+ ),
104
+ state.trail.length > 0 && h('div', { className: 'text-center' },
105
+ h(Link, {
106
+ tabindex: 0,
107
+ _model: { name: 'Back', icon: ICON_BACK },
108
+ _variant: 'simple',
109
+ className: 'cursor-pointer',
110
+ onClick: handleBack,
111
+ onkeydown: event => event.key === 'Enter' && handleBack(event)
112
+ })
113
+ )
114
+ ),
115
+ h('div', { className: 'overflow-hidden rounded-lg h-full' },
116
+ h(Asset, {
117
+ _tall: true,
118
+ _model: {
119
+ image: { src: question.asset }
120
+ }
121
+ })
122
+ )
123
+ ),
124
+ // Recommendation.
125
+ results && h('div', { className: 'grid lg:grid-cols-3 md:grid-cols-2 sm:grid-cols-1 gap-5 animate-fade' },
126
+ results.map(result =>
127
+ h(Result, result)
128
+ )
129
+ )
130
+ )
131
+ }
132
+
133
+ function Result ({ title, text, link, cta, asset, appStoreText, appStoreUrl, playStoreText, playStoreUrl }) {
134
+ return h('div', { className: 'bg-bga text-txa h-full rounded-2xl overflow-hidden' },
135
+ asset && h('div',
136
+ h('img', { src: asset })
137
+ ),
138
+ h(Box, { className: 'bg-bga text-txa w-full' },
139
+ h(Heading, { _level: '3' }, title),
140
+ h(RichText, text),
141
+
142
+ link && cta && h(Link, { _model: { name: cta, value: link }, _variant: 'full', target: '_blank' }),
143
+
144
+ (appStoreUrl || playStoreUrl) && h('div', { className: 'flex gap-5 max-h-16' },
145
+ h(StoreButton, { name: 'App Store', url: appStoreUrl, text: appStoreText, svgGenerator: apple }),
146
+ h(StoreButton, { name: 'Google Play', url: playStoreUrl, text: playStoreText, svgGenerator: google })
147
+ )
148
+ )
149
+ )
150
+ }
151
+
152
+ function StoreButton ({ name, url, text, svgGenerator }) {
153
+ if (!url) {
154
+ return null
155
+ }
156
+
157
+ return h(Link, { _model: { name, value: url }, 'aria-label': `${text} ${name}`, className: 'h-16' },
158
+ h(SVG, { _tall: true, _model: { src: svgGenerator(text) }, className: 'h-12 w-auto' })
159
+ )
160
+ }
161
+
162
+ register(DecisionTree, 'decision-tree')
@@ -0,0 +1,111 @@
1
+ const { register, h, matter, preactHooks } = globalThis.ami
2
+ const { Box, Heading, Link, Button } = matter
3
+ const { useEffect, useState } = preactHooks
4
+
5
+ async function getData (url) {
6
+ const profile = location.pathname.split('.html').at(-1)
7
+
8
+ if (!profile) {
9
+ return null
10
+ }
11
+
12
+ const profilePath = `${url}${profile}.json`
13
+
14
+ const res = await fetch(`${location.origin}/${profilePath}`)
15
+ if (!res.ok) {
16
+ console.error(`Failed to load resource: ${url}`)
17
+ return null
18
+ }
19
+
20
+ const json = await res.json()
21
+ const data = json?.properties?.elements
22
+
23
+ if (!data) {
24
+ return null
25
+ }
26
+
27
+ return {
28
+ name: data?.name?.value,
29
+ phone: data?.phone?.value,
30
+ mobile: data?.mobile?.value,
31
+ contactFilePath: data?.contactFile?.value,
32
+ email: data?.email?.value,
33
+ jobTitle: data?.jobTitle?.value,
34
+ ctaLink: data?.ctaLink?.value
35
+ }
36
+ }
37
+
38
+ function DynamicContactDetails (props) {
39
+ const {
40
+ src,
41
+ 'phone-number-text': phoneNumberText,
42
+ 'mobile-number-text': mobileNumberText,
43
+ 'email-text': emailText,
44
+ 'download-contact-text': downloadContactText,
45
+ 'download-contact-icon': downloadContactIcon,
46
+ 'call-to-action-text': callToActionText,
47
+ 'call-to-action-icon': callToActionIcon
48
+ } = props
49
+
50
+ const [data, setData] = useState()
51
+
52
+ if (!src) {
53
+ console.error('Missing data source.')
54
+ return null
55
+ }
56
+
57
+ useEffect(() => {
58
+ const fetchData = () => {
59
+ getData(src).then(setData).catch(console.error)
60
+ }
61
+ fetchData()
62
+ globalThis.addEventListener('popstate', fetchData)
63
+
64
+ return () => {
65
+ globalThis.removeEventListener('popstate', fetchData)
66
+ }
67
+ }, [])
68
+
69
+ if (!data) {
70
+ return null
71
+ }
72
+
73
+ return h(Box, { className: 'bg-bga text-txa rounded-2xl', itemscope: true, itemtype: 'https://schema.org/Person' },
74
+ h(Heading, { _level: 3, itemprop: 'name', className: 'text-2xl' }, data.name),
75
+ h(Heading, { _level: 4, itemprop: 'jobTitle' }, data.jobTitle),
76
+ h('div', { className: 'space-y-2' },
77
+ data.phone && phoneNumberText && h('div',
78
+ h('span', { className: 'font-bold' }, `${phoneNumberText}: `),
79
+ h(Link, { _variant: 'underline', itemprop: 'telephone', _model: { name: data.phone, value: `tel:${data.phone}` } })
80
+ ),
81
+ data.mobile && mobileNumberText && h('div',
82
+ h('span', { className: 'font-bold' }, `${mobileNumberText}: `),
83
+ h(Link, { _variant: 'underline', itemprop: 'telephone', _model: { name: data.mobile, value: `tel:${data.mobile}` } })
84
+ ),
85
+ h('div',
86
+ h('span', { className: 'font-bold' }, `${emailText}: `),
87
+ h(Link, { _variant: 'underline', itemprop: 'email', _model: { name: data.email, value: `mailto:${data.email}` } })
88
+ )
89
+ ),
90
+ h('div', { className: 'flex gap-5 sm:flex-col' },
91
+ h(Button, {
92
+ _model: {
93
+ name: downloadContactText,
94
+ value: data.contactFilePath,
95
+ icon: downloadContactIcon
96
+ }
97
+ }),
98
+ data.ctaLink && callToActionText && h(Button, {
99
+ target: '_blank',
100
+ rel: 'noopener',
101
+ _model: {
102
+ name: callToActionText,
103
+ value: data.ctaLink,
104
+ icon: callToActionIcon
105
+ }
106
+ })
107
+ )
108
+ )
109
+ }
110
+
111
+ register(DynamicContactDetails, 'dynamic-contact-details')
@@ -0,0 +1,10 @@
1
+ const { h, register, matter } = globalThis.ami
2
+ const { AccordionItem } = matter
3
+
4
+ function ExampleAccordion ({ title = 'Click me' }) {
5
+ return h(AccordionItem, {
6
+ _model: { title, text: 'You can see me now.' }
7
+ })
8
+ }
9
+
10
+ register(ExampleAccordion, 'example-accordion')
@@ -0,0 +1,12 @@
1
+ const { h, register, matter } = globalThis.ami
2
+ const { Asset } = matter
3
+
4
+ function ExampleAsset ({ src }) {
5
+ return h(Asset, {
6
+ _model: {
7
+ image: { src, width: 1920, height: 1080 }
8
+ }
9
+ })
10
+ }
11
+
12
+ register(ExampleAsset, 'example-asset')
@@ -0,0 +1,59 @@
1
+ const { h, register, matter, preactHooks } = globalThis.ami
2
+ const { useState } = preactHooks
3
+ const { Input, Box, Form, Button } = matter
4
+
5
+ function ExampleForm (props) {
6
+ const [submitted, setSubmitted] = useState(false)
7
+
8
+ const onSubmit = event => {
9
+ event.preventDefault()
10
+ setSubmitted(true)
11
+ }
12
+
13
+ if (submitted) {
14
+ return h(Box, { className: 'bg-bga text-txa rounded-2xl' }, 'Thank you for submitting the form.')
15
+ }
16
+
17
+ const options = [
18
+ h('option'),
19
+ h('option', 'A'),
20
+ h('option', 'B'),
21
+ h('option', 'C'),
22
+ ]
23
+
24
+ return h(Form, { name: 'Example form', onSubmit },
25
+ h(Box, { ...props, className: 'bg-bga text-txa rounded-2xl' },
26
+ h('div', { className: 'grid grid-cols-2 gap-4' },
27
+ h('div', { className: 'space-y-4' },
28
+ h(Field, { label: 'Required input', required: true }),
29
+ h(Field, { type: 'select', label: 'Required select', required: true, children: options }),
30
+ h(Field, { type: 'textarea', label: 'Required textarea', required: true }),
31
+ h(Field, { type: 'checkbox', label: 'Required checkbox', required: true }),
32
+ h(Field, { type: 'radio', label: 'Required radio', required: true })
33
+ ),
34
+ h('div', { className: 'space-y-4' },
35
+ h(Field, { label: 'Disabled input', disabled: true }),
36
+ h(Field, { type: 'select', label: 'Disabled select', disabled: true, children: options }),
37
+ h(Field, { type: 'textarea', label: 'Disabled textarea', disabled: true }),
38
+ h(Field, { type: 'checkbox', label: 'Disabled checkbox', disabled: true }),
39
+ h(Field, { type: 'radio', label: 'Disabled radio', disabled: true }),
40
+ h(Field, { type: 'file', label: 'Disabled file', disabled: true })
41
+ )
42
+ ),
43
+ h(Button, { type: 'submit', _model: { name: 'Submit' } })
44
+ )
45
+ )
46
+ }
47
+
48
+ function Field ({ type, label, required, disabled, children }) {
49
+ const fullLabel = required ? `${label} *` : label
50
+
51
+ return h('label', { className: 'block' },
52
+ h('span', { className: 'font-bold' }, fullLabel),
53
+ h('div',
54
+ h(Input, { type, 'data-label': label, required, disabled, children })
55
+ )
56
+ )
57
+ }
58
+
59
+ register(ExampleForm, 'example-form')
@@ -0,0 +1,10 @@
1
+ const { h, register, matter } = globalThis.ami
2
+ const { WebComponent } = matter
3
+
4
+ function ExampleNested ({ 'nested-component-script': nestedComponentScript }) {
5
+ return h(WebComponent, {
6
+ _model: { links: [{ value: nestedComponentScript }] }
7
+ })
8
+ }
9
+
10
+ register(ExampleNested, 'example-nested')
@@ -0,0 +1,51 @@
1
+ /* global location */
2
+ const { h, register, matter, preactHooks } = globalThis.ami
3
+ const { Box, Link } = matter
4
+ const { useState, useEffect } = preactHooks
5
+
6
+ function ExampleRouting () {
7
+ const [state, setState] = useState(getSuffix())
8
+
9
+ useEffect(() => {
10
+ globalThis.addEventListener('popstate', () => setState(getSuffix()))
11
+ })
12
+
13
+ return h(Box, { className: 'bg-bga text-txa rounded-2xl' },
14
+ h('p', `Current suffix: ${state}`),
15
+ h('div', { className: 'space-x-2' },
16
+ h(Link, {
17
+ _variant: 'underline',
18
+ _model: {
19
+ name: 'Link 1',
20
+ value: setSuffix('/suffix/1')
21
+ }
22
+ }),
23
+ h(Link, {
24
+ _variant: 'underline',
25
+ _model: {
26
+ name: 'Link 2',
27
+ value: setSuffix('/suffix/2')
28
+ }
29
+ })
30
+ )
31
+ )
32
+ }
33
+
34
+ function getSuffix () {
35
+ return location.pathname.split('.html')[1]
36
+ }
37
+
38
+ function setSuffix (suffix) {
39
+ const url = new URL(location)
40
+
41
+ const index = url.pathname.indexOf('.html')
42
+ let pathname = url.pathname.substring(0, index + 5)
43
+ if (pathname.endsWith('/')) {
44
+ pathname = `${pathname}index.html`
45
+ }
46
+
47
+ url.pathname = pathname + suffix
48
+ return url.href
49
+ }
50
+
51
+ register(ExampleRouting, 'example-routing')
@@ -0,0 +1,28 @@
1
+ import { ARROW_TAIL_RIGHT } from '#acinguiux-preact/main/shared/icons.js'
2
+
3
+ const { h, register, matter, } = globalThis.ami
4
+ const { Button, NavLink, SearchResult } = matter
5
+
6
+ function ExampleRTL () {
7
+ return h('div', { className: 'space-y-5' },
8
+ h(SearchResult, {
9
+ className: 'p-5',
10
+ _model: {
11
+ links: [
12
+ { name: 'One', value: '#' },
13
+ { name: 'Two', value: '#' },
14
+ { name: 'Three', value: '#' }
15
+ ]
16
+ }
17
+ }),
18
+ h(NavLink, {
19
+ _expanded: false,
20
+ _model: { name: 'Nav Link', value: '#', icon: ARROW_TAIL_RIGHT }
21
+ }),
22
+ h(Button, {
23
+ _model: { name: 'Button', value: '#', icon: ARROW_TAIL_RIGHT }
24
+ })
25
+ )
26
+ }
27
+
28
+ register(ExampleRTL, 'example-rtl')
@@ -0,0 +1,12 @@
1
+ const { h, register, matter } = globalThis.ami
2
+ const { Tabs } = matter
3
+
4
+ function ExampleTabs () {
5
+ return h(Tabs, {
6
+ _model: {
7
+ links: [...Array.from({ length: 5 }).keys()].map(ii => ({ name: `Web Component Tab ${++ii}`, value: '#' }))
8
+ }
9
+ })
10
+ }
11
+
12
+ register(ExampleTabs, 'example-tabs')
@@ -0,0 +1,34 @@
1
+ const { h, register, matter, preactHooks } = globalThis.ami
2
+ const { Box, Heading } = matter
3
+ const { useState, useEffect } = preactHooks
4
+
5
+ // Create Preact component based on hooks.
6
+ function MyPreactComponent ({ src }) {
7
+ const [data, setData] = useState()
8
+
9
+ // The src parameter is a URL to the data feed.
10
+ // It can be configured by an editor for each instance of the component.
11
+ if (!src) {
12
+ console.error('Missing data source.')
13
+ return null
14
+ }
15
+
16
+ // Fetch the data source.
17
+ useEffect(() => {
18
+ (async () => {
19
+ const res = await fetch(src)
20
+ const json = await res.json()
21
+ setData(json)
22
+ })()
23
+ }, [])
24
+
25
+ // Shape the HTML output.
26
+ // This is a hyperscript syntax; feel free to use JSX.
27
+ return h(Box, { className: 'bg-bga text-txa w-full h-full rounded-2xl overflow-hidden' },
28
+ h(Box, { className: 'pal-brand3-solid bg-bga text-txa h-full rounded-lg text-center' },
29
+ h(Heading, { _level: 3 }, data ? data.title : 'Fetching data...')
30
+ )
31
+ )
32
+ }
33
+
34
+ register(MyPreactComponent, 'example-web-component')
@@ -0,0 +1,17 @@
1
+ const { h, matter, register } = globalThis.ami
2
+ const { Button } = matter
3
+
4
+ export function FloatingButton ({ label, href, icon, onClick }) {
5
+ return h('div', {
6
+ dir: document.documentElement.dir,
7
+ _style: id => `
8
+ ${id} button, ${id} a { display: flex }
9
+ ${id}:dir(ltr) { transform: rotate(270deg) translateX(100%); transform-origin: bottom right }
10
+ ${id}:dir(rtl) { transform: rotate(90deg) translateX(-100%); transform-origin: bottom left }
11
+ `,
12
+ className: 'fixed -end-1 bottom-24 animate-fade shadow rounded-lg print:hidden',
13
+ children: h(Button, { _size: 'xs', _model: { name: label, value: href, icon }, onClick })
14
+ })
15
+ }
16
+
17
+ register(FloatingButton, 'floating-button')
@@ -0,0 +1,38 @@
1
+ const { h, matter } = globalThis.ami
2
+
3
+ function Subfield ({ field, name, className }) {
4
+ const subfield = field.subfields[name]
5
+ if (!subfield) {
6
+ return null
7
+ }
8
+
9
+ const id = `${field.attrs.name}[${name}]`
10
+ return h('div', { className },
11
+ h(matter.Input, {
12
+ ...field.attrs,
13
+ className: 'w-full',
14
+ name: id,
15
+ id,
16
+ type: subfield.options ? 'select' : field.attrs.type,
17
+ 'data-label': subfield.label,
18
+ children: subfield.options?.map(option => h('option', { value: option.value }, option.name))
19
+ }),
20
+ h('label', { for: id, className: 'text-sm' }, subfield.label)
21
+ )
22
+ }
23
+
24
+ export function Address ({ field }) {
25
+ const label = field.required === '1' ? `${field.label} *` : field.label
26
+
27
+ return h('fieldset',
28
+ h('legend', { className: 'block font-bold' }, label),
29
+ h(Subfield, { field, name: 'address' }),
30
+ h(Subfield, { field, name: 'address2' }),
31
+ h('div', { className: 'flex flex-row gap-x-5 md:flex-col sm:flex-col' },
32
+ h(Subfield, { field, name: 'city', className: 'w-full' }),
33
+ h(Subfield, { field, name: 'state', className: 'w-full' }),
34
+ h(Subfield, { field, name: 'zip', className: 'shrink-0 lg:w-20 md:w-full sm:w-full' })
35
+ ),
36
+ h(Subfield, { field, name: 'country' })
37
+ )
38
+ }
@@ -0,0 +1,42 @@
1
+ const { h, matter, preactHooks } = globalThis.ami
2
+ const { useState } = preactHooks // Preact hooks
3
+
4
+ export function Checkbox ({ field }) {
5
+ const isRequired = field.required === '1'
6
+ const label = isRequired ? `${field.label} *` : field.label
7
+ // Mark as required only if no box is checked.
8
+ const [isMarkedRequired, setIsMarkedRequired] = useState(isRequired)
9
+ let id = 1
10
+
11
+ return h('fieldset', { className: 'block space-y-1' },
12
+ h('legend', { className: 'block font-bold' }, label),
13
+ field.options.map((option, index) =>
14
+ h('label', { className: 'space-x-2 flex items-center cursor-pointer' },
15
+ h(matter.Input, {
16
+ ...field.attrs,
17
+ id: `${field.attrs.id}_${id++}`,
18
+ type: 'checkbox',
19
+ name: null,
20
+ value: option.value,
21
+ required: (index === 0) && isMarkedRequired,
22
+ 'data-label': field.label,
23
+ onChange (event) {
24
+ // Set value of the hidden field.
25
+ const fieldset = event.currentTarget.closest('fieldset')
26
+ const values = [...fieldset.querySelectorAll('input[type="checkbox"')]
27
+ .map(input => input.checked ? input.value : null)
28
+ const value = values
29
+ .filter(v => v != null)
30
+ .join('\n')
31
+
32
+ fieldset.querySelector('input[type="hidden"]').value = value
33
+ setIsMarkedRequired(isRequired && !values.some(Boolean))
34
+ }
35
+ }),
36
+ h('span', option.label)
37
+ )
38
+ ),
39
+ h(matter.Input, { type: 'hidden', name: field.attrs.name }),
40
+ field.description && h('span', { className: 'text-sm' }, field.description)
41
+ )
42
+ }
@@ -0,0 +1,22 @@
1
+ import { Wrapper } from './wrapper'
2
+ const { h, matter } = globalThis.ami
3
+
4
+ function getDatetimeFieldType (field) {
5
+ if (field.date_format && field.time_format) {
6
+ return 'datetime-local'
7
+ } else if (field.time_format) {
8
+ return 'time'
9
+ } else {
10
+ return 'date'
11
+ }
12
+ }
13
+
14
+ export function DateTime ({ field }) {
15
+ return h(Wrapper, { field },
16
+ h(matter.Input, {
17
+ ...field.attrs,
18
+ type: getDatetimeFieldType(field),
19
+ 'data-label': field.label
20
+ })
21
+ )
22
+ }
@@ -0,0 +1,8 @@
1
+ import { Wrapper } from './wrapper'
2
+ const { h, matter } = globalThis.ami
3
+
4
+ export function Description ({ field }) {
5
+ return h(Wrapper, { field },
6
+ h(matter.RichText, { ...field.attrs, className: 'w-full' }, field.section_text)
7
+ )
8
+ }
@@ -0,0 +1,8 @@
1
+ import { Wrapper } from './wrapper'
2
+ const { h, matter } = globalThis.ami
3
+
4
+ export function Input ({ field }) {
5
+ return h(Wrapper, { field },
6
+ h(matter.Input, { ...field.attrs, className: 'w-full', 'data-label': field.label })
7
+ )
8
+ }
@@ -0,0 +1,39 @@
1
+ const { h, matter } = globalThis.ami
2
+
3
+ const SHORT_FIELD = 'lg:w-20 md:w-full sm:w-full shrink-0'
4
+ const HALF_FIELD = 'lg:w-1/2 md:w-full sm:w-full'
5
+
6
+ function Subfield ({ field, name, className }) {
7
+ const subfield = field.subfields[name]
8
+ if (!subfield) {
9
+ return null
10
+ }
11
+
12
+ const id = `${field.attrs.name}[${name}]`
13
+ return h('div', { className },
14
+ h(matter.Input, {
15
+ ...field.attrs,
16
+ className: 'w-full',
17
+ name: id,
18
+ id,
19
+ 'data-label': subfield.label
20
+ }),
21
+ h('label', { for: id, className: 'text-sm' }, subfield.label)
22
+ )
23
+ }
24
+
25
+ export function Name ({ field }) {
26
+ const label = field.required === '1' ? `${field.label} *` : field.label
27
+
28
+ return h('fieldset',
29
+ h('legend', { className: 'block font-bold' }, label),
30
+ h('div', { className: 'flex flex-row gap-x-5 md:flex-col sm:flex-col' },
31
+ h(Subfield, { field, name: 'prefix', className: SHORT_FIELD }),
32
+ h(Subfield, { field, name: 'first', className: HALF_FIELD }),
33
+ h(Subfield, { field, name: 'middle', className: SHORT_FIELD }),
34
+ h(Subfield, { field, name: 'initial', className: SHORT_FIELD }),
35
+ h(Subfield, { field, name: 'last', className: HALF_FIELD }),
36
+ h(Subfield, { field, name: 'suffix', className: SHORT_FIELD })
37
+ )
38
+ )
39
+ }