@salesforcedevs/dx-components 0.26.1-alpha0.6 → 0.27.0

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 (327) hide show
  1. package/LICENSE +12 -0
  2. package/lwc.config.json +2 -1
  3. package/package.json +3 -9
  4. package/src/assets/icons/action-sprite/svg/symbols.svg +1 -0
  5. package/src/assets/icons/brand-sprite/svg/symbols.svg +1381 -0
  6. package/src/assets/icons/custom-sprite/svg/symbols.svg +1 -0
  7. package/src/assets/icons/doctype-sprite/svg/symbols.svg +1 -0
  8. package/src/assets/icons/general-sprite/svg/symbols.svg +3013 -0
  9. package/src/assets/icons/salesforcebrand-sprite/svg/symbols.svg +257 -0
  10. package/src/assets/icons/standard-sprite/svg/symbols.svg +1 -0
  11. package/src/assets/icons/utility-sprite/svg/symbols.svg +1 -0
  12. package/src/assets/svg/card-news-learn-moar.svg +415 -0
  13. package/src/assets/svg/cloud-1.svg +24 -0
  14. package/src/assets/svg/cloud-2.svg +18 -0
  15. package/src/assets/svg/codey.svg +93 -0
  16. package/src/assets/svg/command.svg +9 -0
  17. package/src/assets/svg/control.svg +10 -0
  18. package/src/assets/svg/docs-empty-state-small.svg +72 -0
  19. package/src/assets/svg/docs-empty-state.svg +86 -0
  20. package/src/assets/svg/dsc-home-news-bear.svg +3 -0
  21. package/src/assets/svg/dsc-home-news-community.png +0 -0
  22. package/src/assets/svg/dsc-home-news-goatbear.svg +257 -0
  23. package/src/assets/svg/dsc-home-news-samplegallery.svg +76 -0
  24. package/src/assets/svg/empty-state-assistant.svg +1 -0
  25. package/src/assets/svg/fch-blog-cloud-1.png +0 -0
  26. package/src/assets/svg/fch-blog-cloud-2.png +0 -0
  27. package/src/assets/svg/fch-blog-planet.png +0 -0
  28. package/src/assets/svg/feature-backdrop1.svg +10 -0
  29. package/src/assets/svg/feature-backdrop2.svg +10 -0
  30. package/src/assets/svg/featured-demo-art-blank.svg +76 -0
  31. package/src/assets/svg/featured-demo-art-eBikes.svg +77 -0
  32. package/src/assets/svg/footer-graphic-large.svg +207 -0
  33. package/src/assets/svg/footer-graphic-mountains-small.svg +17 -0
  34. package/src/assets/svg/footer-graphic-mountains.svg +21 -0
  35. package/src/assets/svg/footer-graphic-trees-small.svg +33 -0
  36. package/src/assets/svg/footer-graphic-trees.svg +62 -0
  37. package/src/assets/svg/lake-mountain.svg +79 -0
  38. package/src/assets/svg/podcast-subscription-clouds-small.svg +49 -0
  39. package/src/assets/svg/podcast-subscription-clouds.svg +57 -0
  40. package/src/assets/svg/podcasts-subscription-apple.svg +164 -0
  41. package/src/assets/svg/podcasts-subscription-google.svg +29 -0
  42. package/src/assets/svg/podcasts-subscription-spotify.svg +11 -0
  43. package/src/assets/svg/salesforce-cloud.svg +7 -0
  44. package/src/assets/svg/salesforce-logo-corporate.svg +21 -0
  45. package/src/assets/svg/salesforce-logo.svg +14 -0
  46. package/src/assets/svg/sidebar-loading.svg +34 -0
  47. package/src/assets/svg/slack-cta-podcast-background-left.svg +28 -0
  48. package/src/assets/svg/slack-cta-podcast-background-right.svg +38 -0
  49. package/src/assets/svg/trees.svg +42 -0
  50. package/src/modules/base-elements/archiveCard/archiveCard.ts +35 -0
  51. package/src/modules/base-elements/headerBase/headerBase.ts +204 -0
  52. package/src/modules/dx/banner/banner.css +46 -0
  53. package/src/modules/dx/banner/banner.html +13 -0
  54. package/src/modules/dx/banner/banner.ts +14 -0
  55. package/src/modules/dx/brandThemeProvider/brandCssVars.ts +10 -0
  56. package/src/modules/dx/brandThemeProvider/brandThemeProvider.html +3 -0
  57. package/src/modules/dx/brandThemeProvider/brandThemeProvider.ts +46 -0
  58. package/src/modules/dx/breadcrumbs/breadcrumbs.css +111 -0
  59. package/src/modules/dx/breadcrumbs/breadcrumbs.html +44 -0
  60. package/src/modules/dx/breadcrumbs/breadcrumbs.ts +122 -0
  61. package/src/modules/dx/button/button.css +175 -0
  62. package/src/modules/dx/button/button.html +43 -0
  63. package/src/modules/dx/button/button.ts +63 -0
  64. package/src/modules/dx/cardBlogPost/cardBlogPost.css +13 -0
  65. package/src/modules/dx/cardBlogPost/cardBlogPost.html +24 -0
  66. package/src/modules/dx/cardBlogPost/cardBlogPost.ts +23 -0
  67. package/src/modules/dx/cardBlogPostProvider/cardBlogPostProvider.css +3 -0
  68. package/src/modules/dx/cardBlogPostProvider/cardBlogPostProvider.html +16 -0
  69. package/src/modules/dx/cardBlogPostProvider/cardBlogPostProvider.ts +29 -0
  70. package/src/modules/dx/cardCallout/cardCallout.css +57 -0
  71. package/src/modules/dx/cardCallout/cardCallout.html +15 -0
  72. package/src/modules/dx/cardCallout/cardCallout.ts +37 -0
  73. package/src/modules/dx/cardContent/cardContent.css +52 -0
  74. package/src/modules/dx/cardContent/cardContent.html +59 -0
  75. package/src/modules/dx/cardContent/cardContent.ts +68 -0
  76. package/src/modules/dx/cardDemo/cardDemo.css +1 -0
  77. package/src/modules/dx/cardDemo/cardDemo.html +12 -0
  78. package/src/modules/dx/cardDemo/cardDemo.ts +11 -0
  79. package/src/modules/dx/cardDocs/cardDocs.css +50 -0
  80. package/src/modules/dx/cardDocs/cardDocs.html +20 -0
  81. package/src/modules/dx/cardDocs/cardDocs.ts +30 -0
  82. package/src/modules/dx/cardEvent/cardEvent.css +107 -0
  83. package/src/modules/dx/cardEvent/cardEvent.html +94 -0
  84. package/src/modules/dx/cardEvent/cardEvent.ts +42 -0
  85. package/src/modules/dx/cardExpanded/cardExpanded.css +49 -0
  86. package/src/modules/dx/cardExpanded/cardExpanded.html +37 -0
  87. package/src/modules/dx/cardExpanded/cardExpanded.ts +45 -0
  88. package/src/modules/dx/cardGrid/cardGrid.css +89 -0
  89. package/src/modules/dx/cardGrid/cardGrid.html +46 -0
  90. package/src/modules/dx/cardGrid/cardGrid.ts +140 -0
  91. package/src/modules/dx/cardMinimal/cardMinimal.css +31 -0
  92. package/src/modules/dx/cardMinimal/cardMinimal.html +13 -0
  93. package/src/modules/dx/cardMinimal/cardMinimal.ts +3 -0
  94. package/src/modules/dx/cardNews/cardNews.css +159 -0
  95. package/src/modules/dx/cardNews/cardNews.html +37 -0
  96. package/src/modules/dx/cardNews/cardNews.ts +62 -0
  97. package/src/modules/dx/cardPodcastEpisode/cardPodcastEpisode.css +19 -0
  98. package/src/modules/dx/cardPodcastEpisode/cardPodcastEpisode.html +36 -0
  99. package/src/modules/dx/cardPodcastEpisode/cardPodcastEpisode.ts +36 -0
  100. package/src/modules/dx/cardPodcastEpisodeProvider/cardPodcastEpisodeProvider.css +3 -0
  101. package/src/modules/dx/cardPodcastEpisodeProvider/cardPodcastEpisodeProvider.html +12 -0
  102. package/src/modules/dx/cardPodcastEpisodeProvider/cardPodcastEpisodeProvider.ts +29 -0
  103. package/src/modules/dx/cardSmall/cardSmall.css +32 -0
  104. package/src/modules/dx/cardSmall/cardSmall.html +42 -0
  105. package/src/modules/dx/cardSmall/cardSmall.ts +38 -0
  106. package/src/modules/dx/cardTitle/cardTitle.css +41 -0
  107. package/src/modules/dx/cardTitle/cardTitle.html +20 -0
  108. package/src/modules/dx/cardTitle/cardTitle.ts +27 -0
  109. package/src/modules/dx/cardTrailheadModule/cardTrailheadModule.css +24 -0
  110. package/src/modules/dx/cardTrailheadModule/cardTrailheadModule.html +20 -0
  111. package/src/modules/dx/cardTrailheadModule/cardTrailheadModule.ts +18 -0
  112. package/src/modules/dx/cardVideoPreview/cardVideoPreview.css +14 -0
  113. package/src/modules/dx/cardVideoPreview/cardVideoPreview.html +26 -0
  114. package/src/modules/dx/cardVideoPreview/cardVideoPreview.ts +13 -0
  115. package/src/modules/dx/checkbox/checkbox.css +168 -0
  116. package/src/modules/dx/checkbox/checkbox.html +26 -0
  117. package/src/modules/dx/checkbox/checkbox.ts +55 -0
  118. package/src/modules/dx/checkboxGroup/checkboxGroup.css +12 -0
  119. package/src/modules/dx/checkboxGroup/checkboxGroup.html +15 -0
  120. package/src/modules/dx/checkboxGroup/checkboxGroup.ts +77 -0
  121. package/src/modules/dx/codeBlock/codeBlock.css +128 -0
  122. package/src/modules/dx/codeBlock/codeBlock.html +79 -0
  123. package/src/modules/dx/codeBlock/codeBlock.ts +215 -0
  124. package/src/modules/dx/codeBlock/darkTheme.css +88 -0
  125. package/src/modules/dx/codeBlock/lightTheme.css +72 -0
  126. package/src/modules/dx/dropdown/dropdown.css +93 -0
  127. package/src/modules/dx/dropdown/dropdown.html +67 -0
  128. package/src/modules/dx/dropdown/dropdown.ts +182 -0
  129. package/src/modules/dx/dropdownOption/dropdownOption.css +61 -0
  130. package/src/modules/dx/dropdownOption/dropdownOption.html +53 -0
  131. package/src/modules/dx/dropdownOption/dropdownOption.ts +39 -0
  132. package/src/modules/dx/emptyState/emptyState.css +64 -0
  133. package/src/modules/dx/emptyState/emptyState.html +9 -0
  134. package/src/modules/dx/emptyState/emptyState.ts +20 -0
  135. package/src/modules/dx/feature/feature.css +135 -0
  136. package/src/modules/dx/feature/feature.html +33 -0
  137. package/src/modules/dx/feature/feature.ts +34 -0
  138. package/src/modules/dx/featureGrid/featureGrid.html +3 -0
  139. package/src/modules/dx/featureGrid/featureGrid.ts +15 -0
  140. package/src/modules/dx/featuredContentHeader/featuredContentHeader.css +469 -0
  141. package/src/modules/dx/featuredContentHeader/featuredContentHeader.html +96 -0
  142. package/src/modules/dx/featuredContentHeader/featuredContentHeader.ts +113 -0
  143. package/src/modules/dx/featuredContentHeader/svgs.ts +35 -0
  144. package/src/modules/dx/featuresList/featuresList.css +24 -0
  145. package/src/modules/dx/featuresList/featuresList.html +20 -0
  146. package/src/modules/dx/featuresList/featuresList.ts +21 -0
  147. package/src/modules/dx/footer/footer.css +405 -0
  148. package/src/modules/dx/footer/footer.html +145 -0
  149. package/src/modules/dx/footer/footer.ts +124 -0
  150. package/src/modules/dx/footer/links.ts +140 -0
  151. package/src/modules/dx/footerOption/footerOption.css +4 -0
  152. package/src/modules/dx/footerOption/footerOption.html +12 -0
  153. package/src/modules/dx/footerOption/footerOption.ts +19 -0
  154. package/src/modules/dx/formattedDateTime/formattedDateTime.html +1 -0
  155. package/src/modules/dx/formattedDateTime/formattedDateTime.ts +72 -0
  156. package/src/modules/dx/grid/grid.css +48 -0
  157. package/src/modules/dx/grid/grid.html +3 -0
  158. package/src/modules/dx/grid/grid.md +14 -0
  159. package/src/modules/dx/grid/grid.ts +72 -0
  160. package/src/modules/dx/groupBio/groupBio.css +49 -0
  161. package/src/modules/dx/groupBio/groupBio.html +29 -0
  162. package/src/modules/dx/groupBio/groupBio.ts +41 -0
  163. package/src/modules/dx/groupText/groupText.css +119 -0
  164. package/src/modules/dx/groupText/groupText.html +65 -0
  165. package/src/modules/dx/groupText/groupText.ts +93 -0
  166. package/src/modules/dx/headTags/headTags.html +3 -0
  167. package/src/modules/dx/headTags/headTags.ts +39 -0
  168. package/src/modules/dx/header/__benchmarks__/header.benchmark.js +45 -0
  169. package/src/modules/dx/header/header.css +109 -0
  170. package/src/modules/dx/header/header.html +129 -0
  171. package/src/modules/dx/header/header.ts +27 -0
  172. package/src/modules/dx/headerMobileNavMenu/headerMobileNavMenu.css +160 -0
  173. package/src/modules/dx/headerMobileNavMenu/headerMobileNavMenu.html +73 -0
  174. package/src/modules/dx/headerMobileNavMenu/headerMobileNavMenu.ts +102 -0
  175. package/src/modules/dx/headerMobileNavMenuOption/headerMobileNavMenuOption.css +5 -0
  176. package/src/modules/dx/headerMobileNavMenuOption/headerMobileNavMenuOption.html +14 -0
  177. package/src/modules/dx/headerMobileNavMenuOption/headerMobileNavMenuOption.ts +20 -0
  178. package/src/modules/dx/headerNav/headerNav.css +31 -0
  179. package/src/modules/dx/headerNav/headerNav.html +48 -0
  180. package/src/modules/dx/headerNav/headerNav.ts +56 -0
  181. package/src/modules/dx/headerSearch/headerSearch.css +62 -0
  182. package/src/modules/dx/headerSearch/headerSearch.html +64 -0
  183. package/src/modules/dx/headerSearch/headerSearch.ts +159 -0
  184. package/src/modules/dx/helmet/helmet.css +83 -0
  185. package/src/modules/dx/helmet/helmet.html +39 -0
  186. package/src/modules/dx/helmet/helmet.ts +27 -0
  187. package/src/modules/dx/hr/hr.css +55 -0
  188. package/src/modules/dx/hr/hr.html +23 -0
  189. package/src/modules/dx/hr/hr.ts +45 -0
  190. package/src/modules/dx/icon/icon.css +14 -0
  191. package/src/modules/dx/icon/icon.html +11 -0
  192. package/src/modules/dx/icon/icon.ts +85 -0
  193. package/src/modules/dx/iconBadge/iconBadge.css +40 -0
  194. package/src/modules/dx/iconBadge/iconBadge.html +10 -0
  195. package/src/modules/dx/iconBadge/iconBadge.ts +42 -0
  196. package/src/modules/dx/imageAndLabel/imageAndLabel.css +54 -0
  197. package/src/modules/dx/imageAndLabel/imageAndLabel.html +22 -0
  198. package/src/modules/dx/imageAndLabel/imageAndLabel.ts +16 -0
  199. package/src/modules/dx/input/input.css +165 -0
  200. package/src/modules/dx/input/input.html +58 -0
  201. package/src/modules/dx/input/input.ts +238 -0
  202. package/src/modules/dx/input/validators.ts +5 -0
  203. package/src/modules/dx/instrumentation/instrumentation.html +1 -0
  204. package/src/modules/dx/instrumentation/instrumentation.ts +116 -0
  205. package/src/modules/dx/interactiveImage/interactiveImage.css +59 -0
  206. package/src/modules/dx/interactiveImage/interactiveImage.html +32 -0
  207. package/src/modules/dx/interactiveImage/interactiveImage.ts +71 -0
  208. package/src/modules/dx/lazy/lazy.html +5 -0
  209. package/src/modules/dx/lazy/lazy.ts +163 -0
  210. package/src/modules/dx/logo/logo.css +33 -0
  211. package/src/modules/dx/logo/logo.html +6 -0
  212. package/src/modules/dx/logo/logo.ts +8 -0
  213. package/src/modules/dx/modalDrawer/modalDrawer.css +40 -0
  214. package/src/modules/dx/modalDrawer/modalDrawer.html +11 -0
  215. package/src/modules/dx/modalDrawer/modalDrawer.ts +27 -0
  216. package/src/modules/dx/newsletterForm/newsletterForm.css +73 -0
  217. package/src/modules/dx/newsletterForm/newsletterForm.html +73 -0
  218. package/src/modules/dx/newsletterForm/newsletterForm.ts +238 -0
  219. package/src/modules/dx/pagination/pagination.css +51 -0
  220. package/src/modules/dx/pagination/pagination.html +45 -0
  221. package/src/modules/dx/pagination/pagination.ts +93 -0
  222. package/src/modules/dx/podcastHost/podcastHost.css +62 -0
  223. package/src/modules/dx/podcastHost/podcastHost.html +28 -0
  224. package/src/modules/dx/podcastHost/podcastHost.ts +13 -0
  225. package/src/modules/dx/podcastPlayer/podcastPlayer.css +10 -0
  226. package/src/modules/dx/podcastPlayer/podcastPlayer.html +3 -0
  227. package/src/modules/dx/podcastPlayer/podcastPlayer.ts +5 -0
  228. package/src/modules/dx/podcastSubscription/podcastSubscription.css +91 -0
  229. package/src/modules/dx/podcastSubscription/podcastSubscription.html +24 -0
  230. package/src/modules/dx/podcastSubscription/podcastSubscription.ts +58 -0
  231. package/src/modules/dx/popover/popover.css +63 -0
  232. package/src/modules/dx/popover/popover.html +16 -0
  233. package/src/modules/dx/popover/popover.ts +313 -0
  234. package/src/modules/dx/radioGroup/radioGroup.css +12 -0
  235. package/src/modules/dx/radioGroup/radioGroup.html +16 -0
  236. package/src/modules/dx/radioGroup/radioGroup.ts +65 -0
  237. package/src/modules/dx/relativeDateTime/relativeDateTime.html +3 -0
  238. package/src/modules/dx/relativeDateTime/relativeDateTime.ts +113 -0
  239. package/src/modules/dx/searchResults/coveo.css +18989 -0
  240. package/src/modules/dx/searchResults/searchResults.css +387 -0
  241. package/src/modules/dx/searchResults/searchResults.html +104 -0
  242. package/src/modules/dx/searchResults/searchResults.ts +186 -0
  243. package/src/modules/dx/section/section.css +130 -0
  244. package/src/modules/dx/section/section.html +66 -0
  245. package/src/modules/dx/section/section.ts +41 -0
  246. package/src/modules/dx/sectionSignup/sectionSignup.css +43 -0
  247. package/src/modules/dx/sectionSignup/sectionSignup.html +23 -0
  248. package/src/modules/dx/sectionSignup/sectionSignup.ts +44 -0
  249. package/src/modules/dx/select/select.css +44 -0
  250. package/src/modules/dx/select/select.html +60 -0
  251. package/src/modules/dx/select/select.ts +23 -0
  252. package/src/modules/dx/sidebar/sidebar.css +192 -0
  253. package/src/modules/dx/sidebar/sidebar.html +94 -0
  254. package/src/modules/dx/sidebar/sidebar.ts +255 -0
  255. package/src/modules/dx/sidebarOld/sidebarOld.css +160 -0
  256. package/src/modules/dx/sidebarOld/sidebarOld.html +70 -0
  257. package/src/modules/dx/sidebarOld/sidebarOld.ts +187 -0
  258. package/src/modules/dx/sidebarSearch/sidebarSearch.css +3 -0
  259. package/src/modules/dx/sidebarSearch/sidebarSearch.html +26 -0
  260. package/src/modules/dx/sidebarSearch/sidebarSearch.ts +437 -0
  261. package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.css +36 -0
  262. package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.html +14 -0
  263. package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.ts +70 -0
  264. package/src/modules/dx/skipNavLink/skipNavLink.css +21 -0
  265. package/src/modules/dx/skipNavLink/skipNavLink.html +3 -0
  266. package/src/modules/dx/skipNavLink/skipNavLink.ts +3 -0
  267. package/src/modules/dx/slackCta/slackCta.css +47 -0
  268. package/src/modules/dx/slackCta/slackCta.html +17 -0
  269. package/src/modules/dx/slackCta/slackCta.ts +12 -0
  270. package/src/modules/dx/socials/socials.css +35 -0
  271. package/src/modules/dx/socials/socials.html +22 -0
  272. package/src/modules/dx/socials/socials.ts +81 -0
  273. package/src/modules/dx/spinner/spinner.css +750 -0
  274. package/src/modules/dx/spinner/spinner.html +6 -0
  275. package/src/modules/dx/spinner/spinner.ts +20 -0
  276. package/src/modules/dx/tab/tab.css +106 -0
  277. package/src/modules/dx/tab/tab.html +13 -0
  278. package/src/modules/dx/tab/tab.ts +52 -0
  279. package/src/modules/dx/toc/toc.css +94 -0
  280. package/src/modules/dx/toc/toc.html +28 -0
  281. package/src/modules/dx/toc/toc.ts +77 -0
  282. package/src/modules/dx/tooltip/microtip.css +269 -0
  283. package/src/modules/dx/tooltip/tooltip.css +36 -0
  284. package/src/modules/dx/tooltip/tooltip.html +5 -0
  285. package/src/modules/dx/tooltip/tooltip.ts +6 -0
  286. package/src/modules/dx/topics/topics.css +25 -0
  287. package/src/modules/dx/topics/topics.html +12 -0
  288. package/src/modules/dx/topics/topics.ts +25 -0
  289. package/src/modules/dx/tree/tree.css +5 -0
  290. package/src/modules/dx/tree/tree.html +11 -0
  291. package/src/modules/dx/tree/tree.ts +72 -0
  292. package/src/modules/dx/tree/treeHandler.ts +100 -0
  293. package/src/modules/dx/treeItem/treeItem.css +14 -0
  294. package/src/modules/dx/treeItem/treeItem.html +22 -0
  295. package/src/modules/dx/treeItem/treeItem.ts +110 -0
  296. package/src/modules/dx/treeTile/treeTile.css +190 -0
  297. package/src/modules/dx/treeTile/treeTile.html +27 -0
  298. package/src/modules/dx/treeTile/treeTile.ts +59 -0
  299. package/src/modules/dx/typeBadge/typeBadge.css +74 -0
  300. package/src/modules/dx/typeBadge/typeBadge.html +5 -0
  301. package/src/modules/dx/typeBadge/typeBadge.ts +65 -0
  302. package/src/modules/dx/typeBadgeGroup/typeBadgeGroup.css +12 -0
  303. package/src/modules/dx/typeBadgeGroup/typeBadgeGroup.html +11 -0
  304. package/src/modules/dx/typeBadgeGroup/typeBadgeGroup.ts +18 -0
  305. package/src/modules/helpers/animations/animations.css +15 -0
  306. package/src/modules/helpers/button/button.css +4 -0
  307. package/src/modules/helpers/card/card.css +258 -0
  308. package/src/modules/helpers/code/code.css +296 -0
  309. package/src/modules/helpers/commonHeader/commonHeader.css +130 -0
  310. package/src/modules/helpers/reset/reset.css +559 -0
  311. package/src/modules/helpers/sidebar/sidebar.css +21 -0
  312. package/src/modules/helpers/slds/slds.css +191 -0
  313. package/src/modules/helpers/table/table.css +110 -0
  314. package/src/modules/helpers/text/text.css +163 -0
  315. package/src/modules/utils/coveo/coveo.ts +70 -0
  316. package/src/modules/utils/css/css.ts +43 -0
  317. package/src/modules/utils/devices/devices.ts +1 -0
  318. package/src/modules/utils/highlight/highlight.ts +32 -0
  319. package/src/modules/utils/normalizers/normalizers.ts +91 -0
  320. package/src/modules/utils/options/options.ts +39 -0
  321. package/src/modules/utils/prismjs/prismjs.html +3 -0
  322. package/src/modules/utils/prismjs/prismjs.ts +3321 -0
  323. package/src/modules/utils/recentSearches/recentSearches.ts +57 -0
  324. package/src/modules/utils/regexps/regexps.ts +5 -0
  325. package/src/modules/utils/seo/seo.ts +4 -0
  326. package/src/modules/utils/slot/slot.ts +17 -0
  327. package/src/modules/utils/wordpress/wordpress.ts +13 -0
@@ -0,0 +1,187 @@
1
+ import cx from "classnames";
2
+ import { track } from "dx/instrumentation";
3
+ import { LightningElement, api } from "lwc";
4
+
5
+ import { TreeNode, SidebarGtmAction } from "typings/custom";
6
+ import { toJson } from "utils/normalizers";
7
+
8
+ const WAIT_TIME = 500;
9
+ const MOBILE_SIZE_MATCH = "768px";
10
+ const TOGGLE_BUTTON_LABEL = "Toggle Sidebar";
11
+
12
+ export default class Sidebar extends LightningElement {
13
+ @api header: string = "";
14
+
15
+ @api
16
+ get value() {
17
+ return this._value;
18
+ }
19
+
20
+ set value(value) {
21
+ this._value = value;
22
+ }
23
+
24
+ @api
25
+ get trees() {
26
+ return this._trees;
27
+ }
28
+
29
+ set trees(value: string | Array<TreeNode>) {
30
+ let parsedValue = toJson(value);
31
+ if (parsedValue && !Array.isArray(parsedValue)) {
32
+ parsedValue = [parsedValue];
33
+ }
34
+
35
+ this._trees = parsedValue || [];
36
+
37
+ this._trees.forEach((tree) => this.assignValueToLabel(tree));
38
+ this.assignFilteredTrees();
39
+ }
40
+
41
+ private expanded: boolean = true;
42
+ private _toggleHovered: boolean = false;
43
+ private _searchTimeout?: number;
44
+ private _value?: string = undefined;
45
+ private _trees!: Array<TreeNode>;
46
+
47
+ private filteredTrees: Array<{ key: string; tree: TreeNode }> = [];
48
+ private mobile: boolean = true;
49
+ private searchText: string = "";
50
+ private matchMedia!: MediaQueryList;
51
+ private valueToLabel: { [key: string]: string } = {};
52
+
53
+ private get anyResultMatch() {
54
+ return this.filteredTrees.length > 0;
55
+ }
56
+
57
+ private get containerClass() {
58
+ return cx("container", {
59
+ collapsed: !this.expanded,
60
+ "container-border-active": this._toggleHovered,
61
+ "container-mobile": this.mobile
62
+ });
63
+ }
64
+
65
+ private get headerMobile() {
66
+ return (
67
+ (this.value && this.valueToLabel[this.value]) ||
68
+ Object.values(this.valueToLabel)[0] ||
69
+ ""
70
+ );
71
+ }
72
+
73
+ connectedCallback() {
74
+ this.matchMedia = window.matchMedia(
75
+ `(max-width: ${MOBILE_SIZE_MATCH})`
76
+ );
77
+
78
+ this.expanded = !this.matchMedia.matches;
79
+ this.onMediaChange(this.matchMedia);
80
+ this.matchMedia.addEventListener("change", this.onMediaChange);
81
+ }
82
+
83
+ disconnectedCallback() {
84
+ this.matchMedia.removeEventListener("change", this.onMediaChange);
85
+ }
86
+
87
+ private onMediaChange = (event: MediaQueryListEvent | MediaQueryList) =>
88
+ (this.mobile = event.matches);
89
+
90
+ private onSelect(event: CustomEvent) {
91
+ this._value = event.detail.name;
92
+ }
93
+
94
+ private onToggleClick(event: Event) {
95
+ this.expanded = !this.expanded;
96
+ this._toggleHovered = false;
97
+ const sideNavAction: SidebarGtmAction = this.expanded
98
+ ? "expand"
99
+ : "collapse";
100
+ track(event.currentTarget!, "custEv_leftNavLinkClick", {
101
+ sideNavAction,
102
+ clickText: TOGGLE_BUTTON_LABEL
103
+ });
104
+ }
105
+
106
+ private onToggleMouseEnter() {
107
+ this._toggleHovered = true;
108
+ }
109
+
110
+ private onToggleMouseLeave() {
111
+ this._toggleHovered = false;
112
+ }
113
+
114
+ /*
115
+ * Debouncing this method: Do not apply searchText filter as long as this
116
+ * function is being called to avoid running the recursivity logic very often.
117
+ **/
118
+ private onSearchChange(event: CustomEvent) {
119
+ this.searchText = event.detail;
120
+ window.clearTimeout(this._searchTimeout);
121
+ this._searchTimeout = window.setTimeout(() => {
122
+ this.assignFilteredTrees();
123
+ this.dispatchEvent(
124
+ new CustomEvent("highlightedtermchange", {
125
+ detail: this.searchText,
126
+ composed: true,
127
+ bubbles: true
128
+ })
129
+ );
130
+ }, WAIT_TIME);
131
+ }
132
+
133
+ private assignFilteredTrees() {
134
+ this.filteredTrees = this._trees
135
+ .map((singleTree) => {
136
+ return {
137
+ key: this.makeKey(),
138
+ tree: this.searchText
139
+ ? this.findMatch(
140
+ new RegExp(this.searchText.toLowerCase().trim()),
141
+ singleTree
142
+ )!
143
+ : singleTree
144
+ };
145
+ })
146
+ .filter((filteredTree) => filteredTree.tree);
147
+ }
148
+
149
+ private makeKey(): string {
150
+ return Math.random().toString(36).substring(7);
151
+ }
152
+
153
+ private findMatch(
154
+ valuePattern: RegExp,
155
+ node: TreeNode
156
+ ): TreeNode | undefined {
157
+ if (valuePattern.test(node.label.toLowerCase())) {
158
+ return { ...node, isExpanded: true };
159
+ }
160
+
161
+ const filteredChildren = this.filterChildren(
162
+ valuePattern,
163
+ node.children
164
+ );
165
+ return filteredChildren.length > 0
166
+ ? { ...node, children: filteredChildren, isExpanded: true }
167
+ : undefined;
168
+ }
169
+
170
+ private filterChildren(
171
+ valuePattern: RegExp,
172
+ children?: Array<TreeNode>
173
+ ): Array<TreeNode> {
174
+ return !children || children.length === 0
175
+ ? []
176
+ : (children
177
+ .map((child) => this.findMatch(valuePattern, child))
178
+ .filter((child) => child) as Array<TreeNode>);
179
+ }
180
+
181
+ private assignValueToLabel(node: TreeNode): void {
182
+ this.valueToLabel[node.name] = node.label;
183
+ if (node.children && node.children.length > 0) {
184
+ node.children.forEach((child) => this.assignValueToLabel(child));
185
+ }
186
+ }
187
+ }
@@ -0,0 +1,3 @@
1
+ .search-box {
2
+ --dx-c-input-width: 100%;
3
+ }
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <dx-dropdown
3
+ aria-label="Recent Searches"
4
+ open={isDropdownOpen}
5
+ options={recentSearches}
6
+ onchange={onClickRecentSearch}
7
+ onrequestclose={onDropdownRequestClose}
8
+ full-width
9
+ >
10
+ <dx-input
11
+ class="search-box"
12
+ type="search"
13
+ placeholder="Search"
14
+ role="search"
15
+ aria-label="Search in this guide"
16
+ icon-symbol="search"
17
+ size="small"
18
+ value={value}
19
+ onchange={onInputChange}
20
+ onfocus={onInputFocus}
21
+ onclear={onInputClear}
22
+ shortcut-key="j"
23
+ clearable
24
+ ></dx-input>
25
+ </dx-dropdown>
26
+ </template>
@@ -0,0 +1,437 @@
1
+ import { LightningElement, api } from "lwc";
2
+ import debounce from "debounce";
3
+ import {
4
+ Result,
5
+ ResultList,
6
+ Unsubscribe,
7
+ ResultsPerPage,
8
+ SearchBox,
9
+ buildResultList,
10
+ buildResultsPerPage,
11
+ buildSearchBox,
12
+ loadAdvancedSearchQueryActions,
13
+ SearchEngine,
14
+ SearchAppState,
15
+ loadQueryActions
16
+ } from "@coveo/headless";
17
+ import { buildSearchEngine, getSidebarSearchParams } from "utils/coveo";
18
+ import { RecentSearches } from "utils/recentSearches";
19
+ import { toJson } from "utils/normalizers";
20
+ import {
21
+ Option,
22
+ PopoverRequestCloseType,
23
+ SidebarSearchResult
24
+ } from "typings/custom";
25
+
26
+ export const SESSION_KEY = "dx-sidebar-search-state";
27
+
28
+ const DEFAULT_RESULT_COUNT = 20;
29
+ const SEARCH_DEBOUNCE_DELAY = 780;
30
+
31
+ const UserRecentSearches = new RecentSearches();
32
+
33
+ const normalizeCoveoAdvancedQueryValue = (version: string): string =>
34
+ version.split(".").join("\\.");
35
+
36
+ export default class SidebarSearch extends LightningElement {
37
+ @api coveoOrganizationId!: string;
38
+ @api coveoPublicAccessToken!: string;
39
+ @api coveoSearchHub!: string;
40
+ @api
41
+ get coveoAdvancedQueryConfig(): { [key: string]: any } {
42
+ return this._coveoAdvancedQueryConfig;
43
+ }
44
+ set coveoAdvancedQueryConfig(value) {
45
+ const jsonValue = toJson(value);
46
+ const hasChanged =
47
+ this._coveoAdvancedQueryConfig &&
48
+ Object.entries(jsonValue).some(
49
+ ([key, val]: [string, any]) =>
50
+ this._coveoAdvancedQueryConfig[key] !== val
51
+ );
52
+ this._coveoAdvancedQueryConfig = jsonValue;
53
+
54
+ if (hasChanged && this.engine && this.value !== "") {
55
+ this.dispatchOnLoading(true);
56
+ }
57
+
58
+ if (hasChanged && this.engine) {
59
+ // set advanced filters needs access to the latest coveoAdvancedQueryConfig
60
+ this.setAdvancedFilters(this.engine);
61
+ this.submitSearch(true);
62
+ }
63
+ }
64
+
65
+ @api
66
+ public fetchMoreResults() {
67
+ if (this.resultList?.state?.moreResultsAvailable) {
68
+ this.fetchingMoreResults = true;
69
+ this.resultList.fetchMoreResults();
70
+ }
71
+ }
72
+
73
+ @api
74
+ setInputValue(searchTerm: string) {
75
+ if (searchTerm !== this.value) {
76
+ this.value = searchTerm || "";
77
+ this.handleValueChange(true);
78
+ }
79
+ }
80
+
81
+ private _coveoAdvancedQueryConfig!: { [key: string]: any };
82
+ private dropdownRequestedOpen: boolean = false;
83
+ private recentSearches: Option[] = [];
84
+ private unsubscribeFromResultList: Unsubscribe = () => {};
85
+ private resultList: ResultList | null = null;
86
+ private resultsPerPage: ResultsPerPage | null = null;
87
+ private preloadedState?: SearchAppState;
88
+ private searchBox: SearchBox | null = null;
89
+ private value?: string = "";
90
+ private engine: SearchEngine | null = null;
91
+ private fetchingMoreResults: boolean = false;
92
+ private didRender = false;
93
+
94
+ private get hasCorrectCoveoConfig(): boolean {
95
+ const coveoConfigurations = [
96
+ this.coveoOrganizationId,
97
+ this.coveoPublicAccessToken,
98
+ this.coveoSearchHub,
99
+ this.coveoAdvancedQueryConfig
100
+ ];
101
+
102
+ return coveoConfigurations.every(
103
+ (val) =>
104
+ !!val && (typeof val === "string" || typeof val === "object")
105
+ );
106
+ }
107
+
108
+ private get isDropdownOpen() {
109
+ return (
110
+ this.dropdownRequestedOpen &&
111
+ this.recentSearches &&
112
+ this.recentSearches.length > 0 &&
113
+ !this.value
114
+ );
115
+ }
116
+
117
+ constructor() {
118
+ super();
119
+
120
+ this.updateRecentSearches();
121
+ this.value = getSidebarSearchParams() || "";
122
+ }
123
+
124
+ disconnectedCallback() {
125
+ this.unsubscribeFromResultList();
126
+ }
127
+
128
+ renderedCallback() {
129
+ // in prod some of the critical coveo configuration attributes seem to arrive later
130
+ // so I needed to put this coveo startup flow here where we can wait for them to arrive
131
+
132
+ if (this.hasCorrectCoveoConfig && !this.engine) {
133
+ this.initializeUserSession();
134
+ this.initializeCoveo();
135
+ } else if (!this.hasCorrectCoveoConfig) {
136
+ console.error(
137
+ "Incorrect coveo search configuration provided. All coveo configuration attributes must be defined.",
138
+ {
139
+ coveoOrganizationId: this.coveoOrganizationId,
140
+ coveoPublicAccessToken: this.coveoPublicAccessToken,
141
+ coveoSearchHub: this.coveoSearchHub,
142
+ coveoAdvancedQueryConfig: this.coveoAdvancedQueryConfig
143
+ }
144
+ );
145
+ }
146
+
147
+ // If this is the first render and there is a search value, trigger
148
+ // term highlighting
149
+ if (!this.didRender && this.value) {
150
+ this.dispatchHighlightedTermChange();
151
+ }
152
+
153
+ this.didRender = true;
154
+ }
155
+
156
+ private initializeUserSession() {
157
+ const stringified = window.sessionStorage.getItem(SESSION_KEY);
158
+
159
+ if (!stringified) {
160
+ return;
161
+ }
162
+
163
+ try {
164
+ const json = JSON.parse(stringified);
165
+
166
+ const hasSameConfig = Object.entries(
167
+ json.coveoAdvancedQueryConfig
168
+ ).every(
169
+ ([key, value]: [string, any]) =>
170
+ this.coveoAdvancedQueryConfig[key] === value
171
+ );
172
+ const hasSameQuery = json?.state?.query?.q === this.value;
173
+
174
+ if (hasSameConfig && hasSameQuery) {
175
+ this.preloadedState = json?.state;
176
+ } else {
177
+ window.sessionStorage.removeItem(SESSION_KEY);
178
+ }
179
+ } catch (e) {
180
+ console.error(e);
181
+ window.sessionStorage.removeItem(SESSION_KEY);
182
+ }
183
+ }
184
+
185
+ private initializeCoveo = () => {
186
+ try {
187
+ this.engine = buildSearchEngine({
188
+ organizationId: this.coveoOrganizationId,
189
+ publicAccessToken: this.coveoPublicAccessToken,
190
+ searchHub: this.coveoSearchHub,
191
+ preloadedState: this.preloadedState
192
+ });
193
+ } catch (ex) {
194
+ console.error(`Coveo engine failed to initialize (${ex})`);
195
+ }
196
+
197
+ if (!this.engine) {
198
+ console.error("Coveo engine failed to initialize!");
199
+ return;
200
+ }
201
+
202
+ if (this.preloadedState) {
203
+ const actions = loadQueryActions(this.engine);
204
+ this.engine.dispatch(actions.updateQuery({ q: this.value || "" }));
205
+ }
206
+
207
+ this.resultList = buildResultList(this.engine, {
208
+ options: { fieldsToInclude: ["sfhtml_url__c"] }
209
+ });
210
+
211
+ this.resultsPerPage = buildResultsPerPage(this.engine, {
212
+ initialState: {
213
+ numberOfResults: DEFAULT_RESULT_COUNT
214
+ }
215
+ });
216
+
217
+ this.searchBox = buildSearchBox(this.engine, {
218
+ options: { numberOfSuggestions: 3 }
219
+ });
220
+
221
+ this.setAdvancedFilters(this.engine);
222
+
223
+ this.unsubscribeFromResultList = this.resultList?.subscribe(
224
+ this.onResultListChange
225
+ );
226
+
227
+ if (this.value) {
228
+ this.dispatchHighlightedTermChange();
229
+ }
230
+
231
+ if (!this.preloadedState) {
232
+ if (this.value) {
233
+ this.submitSearch();
234
+ } else {
235
+ this.dispatchOnLoading(false);
236
+ }
237
+ }
238
+ };
239
+
240
+ private onResultListChange = () => {
241
+ if (!this.resultList) {
242
+ return;
243
+ }
244
+
245
+ const { isLoading, firstSearchExecuted, results } =
246
+ this.resultList.state;
247
+
248
+ if ((!firstSearchExecuted && !isLoading) || !this.value) {
249
+ // coveo search is firing off some unwanted payloads on startup
250
+ return;
251
+ }
252
+
253
+ if (!isLoading) {
254
+ this.dispatchOnChangeEvent(results);
255
+ }
256
+
257
+ if (!this.fetchingMoreResults) {
258
+ this.dispatchOnLoading(isLoading);
259
+ }
260
+
261
+ if (!isLoading && this.fetchingMoreResults) {
262
+ this.fetchingMoreResults = false;
263
+ }
264
+ };
265
+
266
+ private setAdvancedFilters(engine: SearchEngine) {
267
+ const aq = Object.entries(this.coveoAdvancedQueryConfig).reduce(
268
+ (result, [key, value]) =>
269
+ `${result}(@${key}=="${normalizeCoveoAdvancedQueryValue(
270
+ value
271
+ )}")`,
272
+ ""
273
+ );
274
+
275
+ const registerSearchQueryAction = loadAdvancedSearchQueryActions(
276
+ engine
277
+ ).registerAdvancedSearchQueries({
278
+ aq: aq
279
+ });
280
+
281
+ engine.dispatch(registerSearchQueryAction);
282
+ }
283
+
284
+ private normalizeCoveoResult = ({
285
+ clickUri,
286
+ excerpt,
287
+ excerptHighlights,
288
+ raw: { sfhtml_url__c },
289
+ title,
290
+ titleHighlights,
291
+ uniqueId
292
+ }: Result): SidebarSearchResult => {
293
+ // discussion about this normalization here: https://salesforce-internal.slack.com/archives/C020S6784JX/p1639506238376600
294
+
295
+ let pathname;
296
+ if (sfhtml_url__c) {
297
+ pathname = `/docs/${sfhtml_url__c}`;
298
+ } else {
299
+ const isNestedGuide = clickUri.includes("/guide/");
300
+ const url = new URL(clickUri);
301
+ const extension =
302
+ isNestedGuide && !url.pathname?.endsWith(".html")
303
+ ? ".html"
304
+ : "";
305
+ pathname = `${url.pathname}${extension}`;
306
+ }
307
+
308
+ const href = `${pathname}?q=${this.value}`;
309
+
310
+ return {
311
+ title,
312
+ titleHighlights,
313
+ excerpt,
314
+ excerptHighlights,
315
+ uniqueId,
316
+ href,
317
+ selected: pathname === window.location.pathname
318
+ };
319
+ };
320
+
321
+ private updateSessionStorage() {
322
+ window.sessionStorage.setItem(
323
+ SESSION_KEY,
324
+ JSON.stringify({
325
+ coveoAdvancedQueryConfig: this.coveoAdvancedQueryConfig,
326
+ state: this.engine?.state
327
+ })
328
+ );
329
+ }
330
+
331
+ private dispatchOnChangeEvent(results: Result[]) {
332
+ this.updateSessionStorage();
333
+ this.dispatchEvent(
334
+ new CustomEvent("change", {
335
+ detail: {
336
+ results: results.map(this.normalizeCoveoResult),
337
+ value: this.value
338
+ }
339
+ })
340
+ );
341
+ }
342
+
343
+ private dispatchOnLoading(loading: boolean) {
344
+ this.dispatchEvent(new CustomEvent("loading", { detail: loading }));
345
+ }
346
+
347
+ private dispatchHighlightedTermChange() {
348
+ this.dispatchEvent(
349
+ new CustomEvent("highlightedtermchange", {
350
+ detail: this.value,
351
+ composed: true,
352
+ bubbles: true
353
+ })
354
+ );
355
+ }
356
+
357
+ private updateRecentSearches = () =>
358
+ (this.recentSearches = UserRecentSearches.get().map((item: string) => ({
359
+ id: item,
360
+ label: item
361
+ })));
362
+
363
+ private dispatchSidebarSearchChange(searchTerm: string | undefined): void {
364
+ this.dispatchEvent(
365
+ new CustomEvent("sidebarsearchchange", {
366
+ detail: searchTerm ?? "",
367
+ bubbles: true,
368
+ composed: true
369
+ })
370
+ );
371
+ }
372
+
373
+ private submitSearch = debounce((isSyncingSearchValue = false) => {
374
+ if (this.searchBox) {
375
+ UserRecentSearches.add(this.value);
376
+ this.updateRecentSearches();
377
+
378
+ // When `isSyncingSearchValue` is true, we are submitting in a case
379
+ // where the search box is already synced correctly.
380
+ if (!isSyncingSearchValue) {
381
+ this.dispatchSidebarSearchChange(this.value);
382
+ }
383
+
384
+ this.searchBox.updateText(this.value || "");
385
+ this.searchBox.submit();
386
+ }
387
+ }, SEARCH_DEBOUNCE_DELAY);
388
+
389
+ private onClickRecentSearch(e: CustomEvent) {
390
+ this.value = e.detail;
391
+ this.dispatchSidebarSearchChange(this.value);
392
+ this.submitSearch(true);
393
+ }
394
+
395
+ private onDropdownRequestClose(e: CustomEvent) {
396
+ switch (e.detail as PopoverRequestCloseType) {
397
+ case "interact-outside":
398
+ case "keypress-escape":
399
+ this.dropdownRequestedOpen = false;
400
+ break;
401
+ default:
402
+ break;
403
+ }
404
+ }
405
+
406
+ private onInputChange(e: CustomEvent) {
407
+ this.value = e.detail;
408
+
409
+ this.handleValueChange(false);
410
+ this.dispatchHighlightedTermChange();
411
+ }
412
+
413
+ private onInputFocus() {
414
+ this.dropdownRequestedOpen = true;
415
+ }
416
+
417
+ private onInputClear() {
418
+ this.dropdownRequestedOpen = false;
419
+ }
420
+
421
+ private handleValueChange(isSyncingSearchValue = false) {
422
+ if (this.value) {
423
+ this.dispatchOnLoading(true);
424
+ if (this.searchBox) {
425
+ this.submitSearch(isSyncingSearchValue);
426
+ }
427
+ } else {
428
+ // coveo's reaction to an empty value triggers a return of results
429
+ // bootlegging our own ux here`
430
+ this.dispatchOnLoading(false);
431
+ this.dispatchOnChangeEvent([]);
432
+ // Empty search values are not submitted for search, so we need to manually
433
+ // trigger a search change on our own here
434
+ this.dispatchSidebarSearchChange(this.value);
435
+ }
436
+ }
437
+ }
@@ -0,0 +1,36 @@
1
+ @import "helpers/reset";
2
+ @import "helpers/text";
3
+ @import "helpers/sidebar";
4
+
5
+ a {
6
+ display: flex;
7
+ flex-direction: column;
8
+ }
9
+
10
+ .sidebar-item {
11
+ padding: var(--dx-g-spacing-smd) var(--dx-g-spacing-md);
12
+ }
13
+
14
+ .search-text {
15
+ font-size: var(--dx-g-text-xs);
16
+ font-family: var(--dx-g-font-sans);
17
+ line-height: 18px;
18
+ overflow-wrap: break-word;
19
+ }
20
+
21
+ .description {
22
+ -webkit-line-clamp: 3;
23
+ overflow-wrap: break-word;
24
+ }
25
+
26
+ .title {
27
+ color: var(--dx-g-text-heading-color);
28
+ }
29
+
30
+ .bold {
31
+ font-weight: 700;
32
+ }
33
+
34
+ a > *:not(:last-child) {
35
+ margin-bottom: 2px;
36
+ }
@@ -0,0 +1,14 @@
1
+ <template>
2
+ <a class={className} href={href}>
3
+ <span class="title search-text">
4
+ <template for:each={titleChunks} for:item="chunk">
5
+ <span class={chunk.class} key={chunk.id}>{chunk.value}</span>
6
+ </template>
7
+ </span>
8
+ <span class="description dx-text-body-3 sidebar-item-truncate-text">
9
+ <template for:each={descriptionChunks} for:item="chunk">
10
+ <span class={chunk.class} key={chunk.id}>{chunk.value}</span>
11
+ </template>
12
+ </span>
13
+ </a>
14
+ </template>