@salesforcedevs/arch-components 1.20.17-alpha1

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 (363) hide show
  1. package/lwc.config.json +7 -0
  2. package/package.json +19 -0
  3. package/src/modules/common/context/context.html +1 -0
  4. package/src/modules/common/context/context.ts +137 -0
  5. package/src/modules/common/effectAdapter/__tests__/effectAdapter.test.ts +12 -0
  6. package/src/modules/common/effectAdapter/effectAdapter.html +1 -0
  7. package/src/modules/common/effectAdapter/effectAdapter.ts +18 -0
  8. package/src/modules/common/reflectedElement/__tests__/modules/test/select/select.html +3 -0
  9. package/src/modules/common/reflectedElement/__tests__/modules/test/select/select.ts +7 -0
  10. package/src/modules/common/reflectedElement/__tests__/modules/test/selectTransform/selectTransform.html +3 -0
  11. package/src/modules/common/reflectedElement/__tests__/modules/test/selectTransform/selectTransform.ts +18 -0
  12. package/src/modules/common/reflectedElement/__tests__/reflectedElement.test.ts +75 -0
  13. package/src/modules/common/reflectedElement/reflectedElement.ts +50 -0
  14. package/src/modules/common/slot/__tests__/slot.test.ts +96 -0
  15. package/src/modules/common/slot/slot.ts +20 -0
  16. package/src/modules/sa/coverage/coverage.css +35 -0
  17. package/src/modules/sa/coverage/coverage.html +15 -0
  18. package/src/modules/sa/coverage/coverage.ts +406 -0
  19. package/src/modules/sa/coverage/types.d.ts +26 -0
  20. package/src/modules/sa/expandableSection/expandableSection.css +24 -0
  21. package/src/modules/sa/expandableSection/expandableSection.html +20 -0
  22. package/src/modules/sa/expandableSection/expandableSection.stories.ts +37 -0
  23. package/src/modules/sa/expandableSection/expandableSection.ts +24 -0
  24. package/src/modules/sa/explorer/explorer.css +303 -0
  25. package/src/modules/sa/explorer/explorer.html +403 -0
  26. package/src/modules/sa/explorer/explorer.ts +664 -0
  27. package/src/modules/sa/explorer/types.d.ts +60 -0
  28. package/src/modules/sa/gallery/gallery.css +358 -0
  29. package/src/modules/sa/gallery/gallery.html +65 -0
  30. package/src/modules/sa/gallery/gallery.ts +300 -0
  31. package/src/modules/sa/gallery/types.d.ts +35 -0
  32. package/src/modules/sa/socialShare/socialShare.css +49 -0
  33. package/src/modules/sa/socialShare/socialShare.html +56 -0
  34. package/src/modules/sa/socialShare/socialShare.ts +29 -0
  35. package/src/modules/shared/a11y/a11y.ts +25 -0
  36. package/src/modules/shared/children/children.ts +29 -0
  37. package/src/modules/shared/color/color.ts +52 -0
  38. package/src/modules/shared/debounce/debounce.ts +32 -0
  39. package/src/modules/shared/dialog/dialog.ts +154 -0
  40. package/src/modules/shared/elements/__tests__/overflow.test.ts +39 -0
  41. package/src/modules/shared/elements/overflow.ts +71 -0
  42. package/src/modules/shared/fetch/fetch.ts +52 -0
  43. package/src/modules/shared/helpers/helpers.ts +141 -0
  44. package/src/modules/shared/i18n/i18n.ts +74 -0
  45. package/src/modules/shared/labels/__tests__/helpers.test.ts +107 -0
  46. package/src/modules/shared/labels/__tests__/pointHelpers.test.ts +33 -0
  47. package/src/modules/shared/labels/__tests__/timeHelpers.test.ts +89 -0
  48. package/src/modules/shared/labels/helpers.ts +23 -0
  49. package/src/modules/shared/labels/pointHelpers.ts +47 -0
  50. package/src/modules/shared/labels/timeHelpers.ts +182 -0
  51. package/src/modules/shared/labels/types.d.ts +5 -0
  52. package/src/modules/shared/logger/logger.ts +33 -0
  53. package/src/modules/shared/menu/menu.ts +239 -0
  54. package/src/modules/shared/overflow/__tests__/overflow.test.ts +39 -0
  55. package/src/modules/shared/overflow/overflow.ts +71 -0
  56. package/src/modules/shared/polling-request.ts +97 -0
  57. package/src/modules/shared/testutils.ts +118 -0
  58. package/src/modules/shared/track/track.ts +23 -0
  59. package/src/modules/shared/trailhead.ts +123 -0
  60. package/src/modules/shared/types.d.ts +1 -0
  61. package/src/modules/shared/useEffectAttr.ts +16 -0
  62. package/src/modules/shared/withState.ts +21 -0
  63. package/src/modules/tds/appLauncher/__fixtures__/index.ts +34 -0
  64. package/src/modules/tds/appLauncher/__tests__/appLauncher.test.ts +119 -0
  65. package/src/modules/tds/appLauncher/appLauncher.css +65 -0
  66. package/src/modules/tds/appLauncher/appLauncher.html +38 -0
  67. package/src/modules/tds/appLauncher/appLauncher.stories.ts +39 -0
  68. package/src/modules/tds/appLauncher/appLauncher.ts +79 -0
  69. package/src/modules/tds/appLauncher/types.ts +8 -0
  70. package/src/modules/tds/avatar/__tests__/avatar.test.ts +11 -0
  71. package/src/modules/tds/avatar/avatar.css +77 -0
  72. package/src/modules/tds/avatar/avatar.html +36 -0
  73. package/src/modules/tds/avatar/avatar.stories.ts +64 -0
  74. package/src/modules/tds/avatar/avatar.ts +50 -0
  75. package/src/modules/tds/badge/__tests__/badge.test.js +11 -0
  76. package/src/modules/tds/badge/badge.css +22 -0
  77. package/src/modules/tds/badge/badge.html +5 -0
  78. package/src/modules/tds/badge/badge.stories.ts +10 -0
  79. package/src/modules/tds/badge/badge.ts +9 -0
  80. package/src/modules/tds/button/__tests__/button.test.ts +52 -0
  81. package/src/modules/tds/button/button.css +1 -0
  82. package/src/modules/tds/button/button.html +20 -0
  83. package/src/modules/tds/button/button.stories.js +54 -0
  84. package/src/modules/tds/button/button.ts +59 -0
  85. package/src/modules/tds/buttonIcon/__tests__/buttonIcon.test.ts +17 -0
  86. package/src/modules/tds/buttonIcon/buttonIcon.css +1 -0
  87. package/src/modules/tds/buttonIcon/buttonIcon.html +12 -0
  88. package/src/modules/tds/buttonIcon/buttonIcon.stories.js +38 -0
  89. package/src/modules/tds/buttonIcon/buttonIcon.ts +6 -0
  90. package/src/modules/tds/buttonIconLink/buttonIconLink.css +1 -0
  91. package/src/modules/tds/buttonIconLink/buttonIconLink.html +14 -0
  92. package/src/modules/tds/buttonIconLink/buttonIconLink.stories.ts +32 -0
  93. package/src/modules/tds/buttonIconLink/buttonIconLink.ts +9 -0
  94. package/src/modules/tds/buttonLink/__tests__/buttonLink.test.ts +17 -0
  95. package/src/modules/tds/buttonLink/buttonLink.css +1 -0
  96. package/src/modules/tds/buttonLink/buttonLink.html +19 -0
  97. package/src/modules/tds/buttonLink/buttonLink.stories.js +24 -0
  98. package/src/modules/tds/buttonLink/buttonLink.ts +8 -0
  99. package/src/modules/tds/buttonStyles/buttonStyles.css +232 -0
  100. package/src/modules/tds/childSummary/__tests__/childSummary.test.js +99 -0
  101. package/src/modules/tds/childSummary/childSummary.css +74 -0
  102. package/src/modules/tds/childSummary/childSummary.html +38 -0
  103. package/src/modules/tds/childSummary/childSummary.stories.ts +40 -0
  104. package/src/modules/tds/childSummary/childSummary.ts +63 -0
  105. package/src/modules/tds/childSummary/types.d.ts +10 -0
  106. package/src/modules/tds/contentChildListItem/__tests__/contentChildListItem.test.ts +32 -0
  107. package/src/modules/tds/contentChildListItem/contentChildListItem.css +1 -0
  108. package/src/modules/tds/contentChildListItem/contentChildListItem.html +10 -0
  109. package/src/modules/tds/contentChildListItem/contentChildListItem.stories.ts +46 -0
  110. package/src/modules/tds/contentChildListItem/contentChildListItem.ts +34 -0
  111. package/src/modules/tds/contentIcon/contentIcon.css +47 -0
  112. package/src/modules/tds/contentIcon/contentIcon.html +15 -0
  113. package/src/modules/tds/contentIcon/contentIcon.stories.js +110 -0
  114. package/src/modules/tds/contentIcon/contentIcon.ts +66 -0
  115. package/src/modules/tds/contextAdapter/__tests__/contextAdapter.test.ts +76 -0
  116. package/src/modules/tds/contextAdapter/constants.ts +1 -0
  117. package/src/modules/tds/contextAdapter/contextAdapter.html +1 -0
  118. package/src/modules/tds/contextAdapter/contextAdapter.ts +54 -0
  119. package/src/modules/tds/dialogStyles/dialogStyles.css +90 -0
  120. package/src/modules/tds/footerLinks/__tests__/__snapshots__/footerLinks.test.ts.snap +3 -0
  121. package/src/modules/tds/footerLinks/__tests__/footerLinks.test.ts +142 -0
  122. package/src/modules/tds/footerLinks/footerLinks.css +80 -0
  123. package/src/modules/tds/footerLinks/footerLinks.html +30 -0
  124. package/src/modules/tds/footerLinks/footerLinks.ts +48 -0
  125. package/src/modules/tds/footerLinks/types.ts +11 -0
  126. package/src/modules/tds/footerMfe/footerMfe.html +3 -0
  127. package/src/modules/tds/footerMfe/footerMfe.ts +19 -0
  128. package/src/modules/tds/headerAvatar/__tests__/headerAvatar.test.ts +43 -0
  129. package/src/modules/tds/headerAvatar/headerAvatar.css +45 -0
  130. package/src/modules/tds/headerAvatar/headerAvatar.html +25 -0
  131. package/src/modules/tds/headerAvatar/headerAvatar.ts +15 -0
  132. package/src/modules/tds/headerHelpButton/__tests__/headerHelpButton.test.ts +32 -0
  133. package/src/modules/tds/headerHelpButton/headerHelpButton.css +14 -0
  134. package/src/modules/tds/headerHelpButton/headerHelpButton.html +19 -0
  135. package/src/modules/tds/headerHelpButton/headerHelpButton.ts +12 -0
  136. package/src/modules/tds/heading/__tests__/heading.test.ts +50 -0
  137. package/src/modules/tds/heading/heading.css +1 -0
  138. package/src/modules/tds/heading/heading.html +9 -0
  139. package/src/modules/tds/heading/heading.stories.ts +36 -0
  140. package/src/modules/tds/heading/heading.ts +36 -0
  141. package/src/modules/tds/icon/icon.css +28 -0
  142. package/src/modules/tds/icon/icon.html +17 -0
  143. package/src/modules/tds/icon/icon.stories.js +18 -0
  144. package/src/modules/tds/icon/icon.ts +79 -0
  145. package/src/modules/tds/input/__tests__/input.test.ts +41 -0
  146. package/src/modules/tds/input/input.css +34 -0
  147. package/src/modules/tds/input/input.html +12 -0
  148. package/src/modules/tds/input/input.stories.ts +25 -0
  149. package/src/modules/tds/input/input.ts +41 -0
  150. package/src/modules/tds/instrumentation/instrumentation.css +0 -0
  151. package/src/modules/tds/instrumentation/instrumentation.html +1 -0
  152. package/src/modules/tds/instrumentation/instrumentation.ts +113 -0
  153. package/src/modules/tds/pbCard/pbCard.css +28 -0
  154. package/src/modules/tds/pbCard/pbCard.html +21 -0
  155. package/src/modules/tds/pbCard/pbCard.ts +18 -0
  156. package/src/modules/tds/pill/__tests__/pill.test.ts +56 -0
  157. package/src/modules/tds/pill/pill.css +70 -0
  158. package/src/modules/tds/pill/pill.html +17 -0
  159. package/src/modules/tds/pill/pill.stories.ts +41 -0
  160. package/src/modules/tds/pill/pill.ts +34 -0
  161. package/src/modules/tds/progressBar/__tests__/progressBar.test.js +11 -0
  162. package/src/modules/tds/progressBar/progressBar.css +42 -0
  163. package/src/modules/tds/progressBar/progressBar.html +14 -0
  164. package/src/modules/tds/progressBar/progressBar.stories.ts +24 -0
  165. package/src/modules/tds/progressBar/progressBar.ts +14 -0
  166. package/src/modules/tds/radio/__tests__/radio.test.ts +29 -0
  167. package/src/modules/tds/radio/radio.css +89 -0
  168. package/src/modules/tds/radio/radio.html +17 -0
  169. package/src/modules/tds/radio/radio.stories.ts +31 -0
  170. package/src/modules/tds/radio/radio.ts +32 -0
  171. package/src/modules/tds/reset/reset.css +39 -0
  172. package/src/modules/tds/search/__fixtures__/index.ts +32 -0
  173. package/src/modules/tds/search/__tests__/search.test.ts +235 -0
  174. package/src/modules/tds/search/lib/__tests__/__snapshots__/listbox.test.ts.snap +115 -0
  175. package/src/modules/tds/search/lib/__tests__/listbox.test.ts +192 -0
  176. package/src/modules/tds/search/lib/listbox.ts +209 -0
  177. package/src/modules/tds/search/search.css +122 -0
  178. package/src/modules/tds/search/search.html +21 -0
  179. package/src/modules/tds/search/search.stories.ts +20 -0
  180. package/src/modules/tds/search/search.ts +107 -0
  181. package/src/modules/tds/search/types.d.ts +22 -0
  182. package/src/modules/tds/searchList/searchList.css +120 -0
  183. package/src/modules/tds/searchList/searchList.html +43 -0
  184. package/src/modules/tds/searchList/searchList.stories.ts +10 -0
  185. package/src/modules/tds/searchList/searchList.ts +53 -0
  186. package/src/modules/tds/select/__tests__/select.test.ts +150 -0
  187. package/src/modules/tds/select/select.css +42 -0
  188. package/src/modules/tds/select/select.html +24 -0
  189. package/src/modules/tds/select/select.stories.ts +59 -0
  190. package/src/modules/tds/select/select.ts +60 -0
  191. package/src/modules/tds/spinner/__tests__/spinner.test.ts +11 -0
  192. package/src/modules/tds/spinner/spinner.css +194 -0
  193. package/src/modules/tds/spinner/spinner.html +9 -0
  194. package/src/modules/tds/spinner/spinner.stories.ts +20 -0
  195. package/src/modules/tds/spinner/spinner.ts +15 -0
  196. package/src/modules/tds/styles/styles.css +24 -0
  197. package/src/modules/tds/summary/__tests__/summary.test.ts +135 -0
  198. package/src/modules/tds/summary/summary.css +135 -0
  199. package/src/modules/tds/summary/summary.html +69 -0
  200. package/src/modules/tds/summary/summary.stories.js +148 -0
  201. package/src/modules/tds/summary/summary.ts +95 -0
  202. package/src/modules/tds/tab/__tests__/tab.test.ts +25 -0
  203. package/src/modules/tds/tab/tab.css +3 -0
  204. package/src/modules/tds/tab/tab.html +5 -0
  205. package/src/modules/tds/tab/tab.ts +46 -0
  206. package/src/modules/tds/tabset/__tests__/tabset.test.ts +108 -0
  207. package/src/modules/tds/tabset/tabset.css +112 -0
  208. package/src/modules/tds/tabset/tabset.html +63 -0
  209. package/src/modules/tds/tabset/tabset.stories.ts +32 -0
  210. package/src/modules/tds/tabset/tabset.ts +232 -0
  211. package/src/modules/tds/themeProvider/themeProvider.css +502 -0
  212. package/src/modules/tds/themeProvider/themeProvider.html +3 -0
  213. package/src/modules/tds/themeProvider/themeProvider.ts +37 -0
  214. package/src/modules/tds/tile/tile.css +23 -0
  215. package/src/modules/tds/tile/tile.html +5 -0
  216. package/src/modules/tds/tile/tile.stories.js +14 -0
  217. package/src/modules/tds/tile/tile.ts +12 -0
  218. package/src/modules/tds/xsfMfeEvents/xsfMfeEvents.html +1 -0
  219. package/src/modules/tds/xsfMfeEvents/xsfMfeEvents.ts +47 -0
  220. package/src/modules/th/contextAdapter/__tests__/contextAdapter.test.ts +104 -0
  221. package/src/modules/th/contextAdapter/contextAdapter.html +1 -0
  222. package/src/modules/th/contextAdapter/contextAdapter.ts +49 -0
  223. package/src/modules/th/favoriteButton/__tests__/favoriteButton.test.ts +56 -0
  224. package/src/modules/th/favoriteButton/favoriteButton.css +3 -0
  225. package/src/modules/th/favoriteButton/favoriteButton.html +15 -0
  226. package/src/modules/th/favoriteButton/favoriteButton.stories.js +30 -0
  227. package/src/modules/th/favoriteButton/favoriteButton.ts +84 -0
  228. package/src/modules/th/favoriteButton/mocks/index.ts +12 -0
  229. package/src/modules/th/search/__fixtures__/index.ts +14 -0
  230. package/src/modules/th/search/__tests__/search.test.ts +233 -0
  231. package/src/modules/th/search/constants.ts +2 -0
  232. package/src/modules/th/search/mocks/index.ts +30 -0
  233. package/src/modules/th/search/mocks/responses.ts +54 -0
  234. package/src/modules/th/search/search.css +4 -0
  235. package/src/modules/th/search/search.html +12 -0
  236. package/src/modules/th/search/search.ts +172 -0
  237. package/src/modules/th/search/types.d.ts +29 -0
  238. package/src/modules/th/tbid/__tests__/__snapshots__/tbid.test.ts.snap +3 -0
  239. package/src/modules/th/tbid/__tests__/tbid.test.ts +242 -0
  240. package/src/modules/th/tbid/tbid.html +1 -0
  241. package/src/modules/th/tbid/tbid.stories.mdx +25 -0
  242. package/src/modules/th/tbid/tbid.ts +215 -0
  243. package/src/modules/tm/card/__tests__/card.test.ts +65 -0
  244. package/src/modules/tm/card/card.css +131 -0
  245. package/src/modules/tm/card/card.html +81 -0
  246. package/src/modules/tm/card/card.ts +269 -0
  247. package/src/modules/tm/cardBase/cardBase.css +11 -0
  248. package/src/modules/tm/cardGridA/cardGridA.css +11 -0
  249. package/src/modules/tm/cardGridA/cardGridA.html +21 -0
  250. package/src/modules/tm/cardGridA/cardGridA.stories.js +107 -0
  251. package/src/modules/tm/cardGridA/cardGridA.ts +24 -0
  252. package/src/modules/tm/cardGridB/cardGridB.css +88 -0
  253. package/src/modules/tm/cardGridB/cardGridB.html +20 -0
  254. package/src/modules/tm/cardGridB/cardGridB.stories.js +58 -0
  255. package/src/modules/tm/cardGridB/cardGridB.ts +19 -0
  256. package/src/modules/tm/cardGridC/cardGridC.css +24 -0
  257. package/src/modules/tm/cardGridC/cardGridC.html +22 -0
  258. package/src/modules/tm/cardGridC/cardGridC.stories.js +42 -0
  259. package/src/modules/tm/cardGridC/cardGridC.ts +11 -0
  260. package/src/modules/tm/cardGridD/cardGridD.css +17 -0
  261. package/src/modules/tm/cardGridD/cardGridD.html +20 -0
  262. package/src/modules/tm/cardGridD/cardGridD.stories.js +34 -0
  263. package/src/modules/tm/cardGridD/cardGridD.ts +7 -0
  264. package/src/modules/tm/cardNew/cardNew.css +31 -0
  265. package/src/modules/tm/cardNew/cardNew.html +29 -0
  266. package/src/modules/tm/cardNew/cardNew.ts +66 -0
  267. package/src/modules/tm/content/__fixtures__/index.ts +884 -0
  268. package/src/modules/tm/content/__tests__/content.test.ts +95 -0
  269. package/src/modules/tm/content/content.css +641 -0
  270. package/src/modules/tm/content/content.html +53 -0
  271. package/src/modules/tm/content/content.stories.js +14 -0
  272. package/src/modules/tm/content/content.ts +171 -0
  273. package/src/modules/tm/endCapA/__tests__/endCapA.test.ts +52 -0
  274. package/src/modules/tm/endCapA/endCapA.css +64 -0
  275. package/src/modules/tm/endCapA/endCapA.html +21 -0
  276. package/src/modules/tm/endCapA/endCapA.stories.js +37 -0
  277. package/src/modules/tm/endCapA/endCapA.ts +23 -0
  278. package/src/modules/tm/eventsA/eventsA.css +107 -0
  279. package/src/modules/tm/eventsA/eventsA.html +26 -0
  280. package/src/modules/tm/eventsA/eventsA.stories.js +51 -0
  281. package/src/modules/tm/eventsA/eventsA.ts +48 -0
  282. package/src/modules/tm/faqA/faqA.css +87 -0
  283. package/src/modules/tm/faqA/faqA.html +27 -0
  284. package/src/modules/tm/faqA/faqA.stories.js +25 -0
  285. package/src/modules/tm/faqA/faqA.ts +40 -0
  286. package/src/modules/tm/featureGridA/__tests__/featureGridA.test.ts +116 -0
  287. package/src/modules/tm/featureGridA/featureGridA.css +95 -0
  288. package/src/modules/tm/featureGridA/featureGridA.html +34 -0
  289. package/src/modules/tm/featureGridA/featureGridA.stories.js +45 -0
  290. package/src/modules/tm/featureGridA/featureGridA.ts +59 -0
  291. package/src/modules/tm/footnote/footnote.css +28 -0
  292. package/src/modules/tm/footnote/footnote.html +3 -0
  293. package/src/modules/tm/footnote/footnote.stories.js +29 -0
  294. package/src/modules/tm/footnote/footnote.ts +35 -0
  295. package/src/modules/tm/heroA/__tests__/heroA.test.ts +51 -0
  296. package/src/modules/tm/heroA/heroA.css +116 -0
  297. package/src/modules/tm/heroA/heroA.html +27 -0
  298. package/src/modules/tm/heroA/heroA.stories.js +49 -0
  299. package/src/modules/tm/heroA/heroA.ts +56 -0
  300. package/src/modules/tm/heroB/heroB.css +78 -0
  301. package/src/modules/tm/heroB/heroB.html +26 -0
  302. package/src/modules/tm/heroB/heroB.stories.js +44 -0
  303. package/src/modules/tm/heroB/heroB.ts +26 -0
  304. package/src/modules/tm/page/__tests__/page.test.ts +35 -0
  305. package/src/modules/tm/page/page.css +3 -0
  306. package/src/modules/tm/page/page.html +3 -0
  307. package/src/modules/tm/page/page.stories.js +10 -0
  308. package/src/modules/tm/page/page.ts +3 -0
  309. package/src/modules/tm/pageHeaderA/pageHeaderA.css +82 -0
  310. package/src/modules/tm/pageHeaderA/pageHeaderA.html +24 -0
  311. package/src/modules/tm/pageHeaderA/pageHeaderA.stories.js +18 -0
  312. package/src/modules/tm/pageHeaderA/pageHeaderA.ts +51 -0
  313. package/src/modules/tm/pageNavigationA/pageNavigationA.css +41 -0
  314. package/src/modules/tm/pageNavigationA/pageNavigationA.html +9 -0
  315. package/src/modules/tm/pageNavigationA/pageNavigationA.stories.js +34 -0
  316. package/src/modules/tm/pageNavigationA/pageNavigationA.ts +18 -0
  317. package/src/modules/tm/promoA/__tests__/promoA.test.ts +89 -0
  318. package/src/modules/tm/promoA/promoA.css +95 -0
  319. package/src/modules/tm/promoA/promoA.html +22 -0
  320. package/src/modules/tm/promoA/promoA.stories.js +38 -0
  321. package/src/modules/tm/promoA/promoA.ts +62 -0
  322. package/src/modules/tm/sectionA/sectionA.css +64 -0
  323. package/src/modules/tm/sectionA/sectionA.html +21 -0
  324. package/src/modules/tm/sectionA/sectionA.stories.js +18 -0
  325. package/src/modules/tm/sectionA/sectionA.ts +27 -0
  326. package/src/modules/tm/sectionSpacer/sectionSpacer.css +4 -0
  327. package/src/modules/tm/sectionSpacer/sectionSpacer.html +1 -0
  328. package/src/modules/tm/sectionSpacer/sectionSpacer.ts +3 -0
  329. package/src/modules/tm/skillsCardA/skillsCardA.css +73 -0
  330. package/src/modules/tm/skillsCardA/skillsCardA.html +37 -0
  331. package/src/modules/tm/skillsCardA/skillsCardA.ts +38 -0
  332. package/src/modules/tm/skillsGridA/skillsGridA.css +12 -0
  333. package/src/modules/tm/skillsGridA/skillsGridA.html +5 -0
  334. package/src/modules/tm/skillsGridA/skillsGridA.stories.ts +65 -0
  335. package/src/modules/tm/skillsGridA/skillsGridA.ts +3 -0
  336. package/src/modules/tm/statsA/statsA.css +26 -0
  337. package/src/modules/tm/statsA/statsA.html +10 -0
  338. package/src/modules/tm/statsA/statsA.stories.js +29 -0
  339. package/src/modules/tm/statsA/statsA.ts +20 -0
  340. package/src/modules/tm/textItem/textItem.css +53 -0
  341. package/src/modules/tm/textItem/textItem.html +18 -0
  342. package/src/modules/tm/textItem/textItem.ts +32 -0
  343. package/src/modules/tm/textItemGridA/textItemGridA.css +11 -0
  344. package/src/modules/tm/textItemGridA/textItemGridA.html +15 -0
  345. package/src/modules/tm/textItemGridA/textItemGridA.stories.js +67 -0
  346. package/src/modules/tm/textItemGridA/textItemGridA.ts +20 -0
  347. package/src/modules/tm/threeCardGrid/threeCardGrid.css +6 -0
  348. package/src/modules/tm/threeCardGrid/threeCardGrid.html +5 -0
  349. package/src/modules/tm/threeCardGrid/threeCardGrid.ts +3 -0
  350. package/src/modules/tm/trailblazersA/trailblazersA.css +70 -0
  351. package/src/modules/tm/trailblazersA/trailblazersA.html +42 -0
  352. package/src/modules/tm/trailblazersA/trailblazersA.stories.js +52 -0
  353. package/src/modules/tm/trailblazersA/trailblazersA.ts +43 -0
  354. package/src/modules/tm/utils/utils.ts +18 -0
  355. package/src/modules/tm/youtube/youtube.css +7 -0
  356. package/src/modules/tm/youtube/youtube.html +10 -0
  357. package/src/modules/tm/youtube/youtube.stories.js +15 -0
  358. package/src/modules/tm/youtube/youtube.ts +27 -0
  359. package/src/modules/ui/focusTrap/focusTrap.html +5 -0
  360. package/src/modules/ui/focusTrap/focusTrap.ts +104 -0
  361. package/src/modules/ui/focusVisible/__tests__/focusVisible.test.ts +95 -0
  362. package/src/modules/ui/focusVisible/focusVisible.html +3 -0
  363. package/src/modules/ui/focusVisible/focusVisible.ts +46 -0
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @file Utilities for dealing with element overflows (execeeding container width)
3
+ * Based on https://sfdc.co/uOYl6
4
+ */
5
+
6
+ export type CalculateOverflowItem = {
7
+ active: boolean;
8
+ value?: string;
9
+ width: number;
10
+ };
11
+
12
+ export function calculateOverflow(
13
+ items: CalculateOverflowItem[],
14
+ containerWidth: number = 0,
15
+ overflowWidth: number = 0
16
+ ) {
17
+ const visibleItems: CalculateOverflowItem[] = [];
18
+ const overflowItems: CalculateOverflowItem[] = [];
19
+
20
+ const allItemsWidth = items.reduce(
21
+ (totalWidth, item) => totalWidth + item.width,
22
+ 0
23
+ );
24
+
25
+ // If total items width is less than containerwidth or if the containerwidth is
26
+ // less than zero in cases where container is not yet rendered and we subtract the threshold
27
+ // return all items as visibleItems and overflowItems empty
28
+ if (allItemsWidth <= containerWidth || containerWidth <= 0) {
29
+ return { visibleItems: items, overflowItems };
30
+ }
31
+
32
+ // Not all items fit, an overflow is needed
33
+ let totalWidth = overflowWidth;
34
+
35
+ // Find the active item if it exists
36
+ const activeItem = items.find((i) => i.active);
37
+
38
+ // The active item is always shown, so reserve space for it
39
+ if (activeItem) {
40
+ totalWidth += activeItem.width;
41
+ }
42
+
43
+ let activeItemFitsWithoutRearrangement = false;
44
+
45
+ items.forEach((item) => {
46
+ if (item.active) {
47
+ activeItemFitsWithoutRearrangement = overflowItems.length === 0;
48
+ if (activeItemFitsWithoutRearrangement) {
49
+ visibleItems.push(item);
50
+ }
51
+ } else {
52
+ const itemFits = item.width + totalWidth <= containerWidth;
53
+ if (itemFits && overflowItems.length === 0) {
54
+ totalWidth += item.width;
55
+ visibleItems.push(item);
56
+ } else {
57
+ overflowItems.push(item);
58
+ }
59
+ }
60
+ });
61
+
62
+ // Place the active item at the end
63
+ if (activeItem && !activeItemFitsWithoutRearrangement) {
64
+ visibleItems.push(activeItem);
65
+ }
66
+
67
+ return {
68
+ visibleItems,
69
+ overflowItems
70
+ };
71
+ }
@@ -0,0 +1,97 @@
1
+ const DEFAULT_INTERVAL = 3000;
2
+ const DEFAULT_RETRIES = 10;
3
+
4
+ export type PollingRequestInit<T> = {
5
+ request: () => Promise<T>;
6
+ done?: (res: T) => boolean;
7
+ interval?: number;
8
+ retries?: number;
9
+ };
10
+
11
+ /**
12
+ * Creates a Promise-like polling request
13
+ * @class PollingRequest
14
+ * @example
15
+ * const res = await new PollingRequest({ ... });
16
+ */
17
+ export class PollingRequest<T> {
18
+ // Internals
19
+ private resolve: (value: T | PromiseLike<T>) => void = () => {};
20
+ private reject: (reason?: any) => void = () => {};
21
+ private readonly promise: Promise<T>;
22
+ private timer: ReturnType<typeof setTimeout> | null = null;
23
+ private attempt: number = 0;
24
+
25
+ // Arguments
26
+ private request: () => Promise<T>;
27
+ private done: (res: T) => boolean;
28
+ private interval: number;
29
+ private retries: number;
30
+
31
+ constructor({ request, done, interval, retries }: PollingRequestInit<T>) {
32
+ this.promise = new Promise<T>((resolve, reject) => {
33
+ this.resolve = resolve;
34
+ this.reject = reject;
35
+ });
36
+
37
+ this.request = request;
38
+ this.done = done || (() => true);
39
+ this.interval = interval || DEFAULT_INTERVAL;
40
+ this.retries = retries || DEFAULT_RETRIES;
41
+
42
+ this.start();
43
+ }
44
+
45
+ async then(
46
+ onfulfilled?: (value: T) => T | PromiseLike<T>,
47
+ onrejected?: (reason: any) => PromiseLike<never>
48
+ ): Promise<T> {
49
+ return this.promise.then(onfulfilled, onrejected);
50
+ }
51
+
52
+ async catch(onRejected?: (reason: any) => PromiseLike<never>): Promise<T> {
53
+ return this.promise.catch(onRejected);
54
+ }
55
+
56
+ private start() {
57
+ this.poll();
58
+ }
59
+
60
+ private stop() {
61
+ if (this.timer) {
62
+ clearTimeout(this.timer);
63
+ }
64
+
65
+ this.retries = 0;
66
+ this.attempt = 0;
67
+ this.timer = null;
68
+ }
69
+
70
+ private async poll() {
71
+ const currentAttempt = (this.attempt = this.attempt + 1);
72
+
73
+ try {
74
+ const res = await this.request();
75
+
76
+ // If polling was stopped before the request could complete
77
+ if (currentAttempt !== this.attempt) return;
78
+
79
+ if (this.done(res)) {
80
+ this.stop();
81
+ this.resolve(res);
82
+ }
83
+
84
+ if (this.attempt < this.retries) {
85
+ this.timer = setTimeout(this.poll.bind(this), this.interval);
86
+ } else {
87
+ throw new Error('timeout');
88
+ }
89
+ } catch (err) {
90
+ // If polling was stopped before the request could complete
91
+ if (currentAttempt !== this.attempt) return;
92
+
93
+ this.stop();
94
+ this.reject(err);
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,118 @@
1
+ import { html, render, TemplateResult } from 'lit-html';
2
+ import { querySelectorAll, querySelector } from 'kagekiri';
3
+ // @ts-ignore we are using a beta feature "setFeatureFlagForTest" that tsc doesn't like
4
+ import { createElement, LightningElement, setFeatureFlagForTest } from 'lwc';
5
+
6
+ export { html, render };
7
+
8
+ export function nextTick() {
9
+ return new Promise((resolve) => {
10
+ process.nextTick(resolve);
11
+ });
12
+ }
13
+
14
+ export function $(selector: string, element: HTMLElement) {
15
+ return element.shadowRoot!.querySelectorAll(selector);
16
+ }
17
+
18
+ export function $testid(value: string, element: HTMLElement) {
19
+ return $(`[data-testid="${value}"]`, element);
20
+ }
21
+
22
+ export function renderIntoBody(template: TemplateResult) {
23
+ let element = document.createElement('div');
24
+ document.body.append(element);
25
+ render(template, element);
26
+ return element.children[0] as HTMLElement;
27
+ }
28
+
29
+ export async function renderIntoBodyAndWait(
30
+ template: TemplateResult,
31
+ ready:
32
+ | ((params: {
33
+ querySelector: typeof querySelector;
34
+ querySelectorAll: typeof querySelectorAll;
35
+ }) => boolean)
36
+ | string
37
+ ) {
38
+ let element = renderIntoBody(template);
39
+ await new Promise((resolve) => {
40
+ let check = () => {
41
+ let isReady =
42
+ typeof ready === 'string'
43
+ ? querySelector(ready, element) !== null
44
+ : ready({ querySelector, querySelectorAll });
45
+ if (isReady) {
46
+ resolve(undefined);
47
+ } else {
48
+ requestAnimationFrame(check);
49
+ }
50
+ };
51
+ requestAnimationFrame(check);
52
+ });
53
+ return element;
54
+ }
55
+
56
+ // LWC Component Testing Utilities
57
+ export const renderLightningElement = (
58
+ element: LightningElement,
59
+ properties = {}
60
+ ) => {
61
+ Object.assign(element, properties);
62
+ document.body.appendChild(element as unknown as Node);
63
+ return element;
64
+ };
65
+
66
+ export const createRenderComponent = (
67
+ tag: string,
68
+ LWC: new () => LightningElement
69
+ ) => {
70
+ setFeatureFlagForTest('ENABLE_LIGHT_DOM_COMPONENTS', true);
71
+ return (properties = {}) => {
72
+ const component = createElement(tag, {
73
+ is: LWC
74
+ });
75
+
76
+ renderLightningElement(component, properties);
77
+ return component;
78
+ };
79
+ };
80
+
81
+ export const mockSlottedElement = <T extends HTMLElement>(
82
+ element: any,
83
+ elementType = 'button',
84
+ slotName?: string
85
+ ): { slottedElement: T; slot: HTMLSlotElement } => {
86
+ const slot: HTMLSlotElement = element.shadowRoot.querySelector(
87
+ `slot${slotName ? `[name='${slotName}']` : ''}`
88
+ );
89
+ expect(slot).not.toBeNull();
90
+
91
+ const slottedElement = document.createElement(elementType) as T;
92
+ slot.assignedElements = jest.fn(() => [slottedElement]);
93
+ slot.dispatchEvent(new Event('slotchange'));
94
+
95
+ return { slottedElement, slot };
96
+ };
97
+
98
+ const wait = () => new Promise((res) => setTimeout(res, 0));
99
+
100
+ const renderAllShadowDoms = (element: {
101
+ shadowRoot: { children: HTMLElement };
102
+ }) => {
103
+ if (element.shadowRoot) {
104
+ return element.shadowRoot.children;
105
+ }
106
+
107
+ return element;
108
+ };
109
+
110
+ export const toSnapshot = async <T extends Object>(
111
+ render: Function,
112
+ props?: T
113
+ ) => {
114
+ const element = render(props);
115
+ await wait();
116
+ const doc = renderAllShadowDoms(element);
117
+ return expect(doc).toMatchSnapshot();
118
+ };
@@ -0,0 +1,23 @@
1
+ type TrackingPayload = {
2
+ label?: string;
3
+ ctaType?: string;
4
+ };
5
+
6
+ export const track = (
7
+ element: HTMLElement,
8
+ eventName: string,
9
+ payload: TrackingPayload
10
+ ) => {
11
+ const trackEvent = new CustomEvent('trailhead_track', {
12
+ bubbles: true,
13
+ composed: true,
14
+ detail: {
15
+ eventName,
16
+ payload: {
17
+ ...payload,
18
+ ...{ pageLocation: element.tagName }
19
+ }
20
+ }
21
+ });
22
+ element.dispatchEvent(trackEvent);
23
+ };
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @file Utilites for interacting with the Trailhead platform.
3
+ */
4
+ import { fetch, fetchJSON, postJSON, csrfHeader } from './fetch/fetch';
5
+ import { PollingRequest, PollingRequestInit } from './polling-request';
6
+ import logger from './logger/logger';
7
+ // Org type definition (orgPicker/types module not found)
8
+ type Org = {
9
+ [key: string]: any;
10
+ };
11
+
12
+ const CSRF_WARNING =
13
+ 'A CSRF token required for this request. Set it using fromTrailhead.configure().';
14
+
15
+ const DEFAULT_BASE_URL = '';
16
+
17
+ type TrailheadAPIClientInit = {
18
+ baseUrl?: string;
19
+ csrfToken?: string;
20
+ };
21
+
22
+ /**
23
+ * Client for interacting with Trailhead via API requests
24
+ * @example
25
+ * const fromTrailhead = new TrailheadAPIClient({ csrfToken: "XXX" });
26
+ * fromTrailhead.get("/user_orgs");
27
+ */
28
+ export class TrailheadAPIClient {
29
+ baseUrl: string = DEFAULT_BASE_URL;
30
+ csrfToken: string | undefined;
31
+
32
+ constructor(args: TrailheadAPIClientInit = {}) {
33
+ this.configure(args);
34
+ }
35
+
36
+ configure({
37
+ baseUrl = process.env.API_HOST,
38
+ csrfToken
39
+ }: TrailheadAPIClientInit) {
40
+ this.baseUrl = baseUrl || DEFAULT_BASE_URL;
41
+ this.csrfToken = csrfToken;
42
+ }
43
+
44
+ async get<T>(path: string) {
45
+ return fetchJSON<T>(this.makeUrl(path));
46
+ }
47
+
48
+ async post<T>(path: string, body?: object) {
49
+ this.checkRequest();
50
+ return postJSON<T>(this.makeUrl(path), body, {
51
+ headers: { ...csrfHeader(this.csrfToken) }
52
+ });
53
+ }
54
+
55
+ async patch<T>(path: string, body?: object) {
56
+ this.checkRequest();
57
+ return postJSON<T>(this.makeUrl(path), body, {
58
+ method: 'PATCH',
59
+ headers: {
60
+ ...csrfHeader(this.csrfToken)
61
+ }
62
+ });
63
+ }
64
+
65
+ async delete<T>(path: string) {
66
+ this.checkRequest();
67
+ return fetchJSON<T>(this.makeUrl(path), {
68
+ method: 'DELETE',
69
+ headers: { ...csrfHeader(this.csrfToken) }
70
+ });
71
+ }
72
+
73
+ async poll<T>(args: PollingRequestInit<T>) {
74
+ return new PollingRequest<T>(args);
75
+ }
76
+
77
+ makeUrl(path: string) {
78
+ return [this.baseUrl, path]
79
+ .map((s) => s.replace(/^\/|\/$/g, ''))
80
+ .join('/');
81
+ }
82
+
83
+ private checkRequest() {
84
+ if (!this.csrfToken) {
85
+ logger.warn(CSRF_WARNING);
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Determine if an org is reachable (after creation) by
92
+ * requesting open endpoints. The org is reachable if the
93
+ * user's client resolves the freshly propagated DNS entries.
94
+ */
95
+ export async function isOrgReachable(org: Org): Promise<boolean> {
96
+ const subdomain = org.instance_url.split('.')[0];
97
+
98
+ const responses = await Promise.all([
99
+ fetch(
100
+ `${subdomain}.my.salesforce.com/.well-known/openid-configuration`
101
+ ),
102
+ fetch(
103
+ `${subdomain}--c.documentforce.com/.well-known/openid-configuration`,
104
+ {
105
+ mode: 'no-cors'
106
+ }
107
+ ),
108
+ fetch(
109
+ `${subdomain}--th-con-app.visualforce.com/.well-known/openid-configuration`,
110
+ {
111
+ mode: 'no-cors'
112
+ }
113
+ ),
114
+ fetch(
115
+ `${subdomain}.lightning.force.com/.well-known/openid-configuration`,
116
+ {
117
+ mode: 'no-cors'
118
+ }
119
+ )
120
+ ]).catch(() => Promise.resolve([{ status: 404 }]));
121
+
122
+ return responses.every((r) => r.status === 200 || r.status === 0);
123
+ }
@@ -0,0 +1 @@
1
+ export type BooleanAttr = boolean | string | null;
@@ -0,0 +1,16 @@
1
+ export function useEffectAttr(fn: Function, deps: Array<string>, context: any) {
2
+ let prevValues = new Map<string, any>();
3
+ return () => {
4
+ let prev = deps.map((key) => prevValues.get(key));
5
+ let next = deps.map((key) => context[key]);
6
+ for (let i in prev) {
7
+ if (next[i] !== prev[i]) {
8
+ fn.call(context);
9
+ break;
10
+ }
11
+ }
12
+ for (let k of deps) {
13
+ prevValues.set(k, context[k]);
14
+ }
15
+ };
16
+ }
@@ -0,0 +1,21 @@
1
+ import { directive, NodePart } from 'lit-html';
2
+
3
+ export type WithStateState = any;
4
+ export type WithStateSetState = (state: any) => void;
5
+
6
+ /**
7
+ * lit-html directive for creating thin, stateful renderings
8
+ * @example
9
+ * html`${withState((state, setState) => html`state.msg`, { msg: 'hello!' })}`
10
+ */
11
+ export default directive((render, initialState = {}) => (part: NodePart) => {
12
+ let prevState = initialState;
13
+
14
+ function setState(nextState: WithStateState) {
15
+ part.setValue(render({ ...prevState, ...nextState }, setState));
16
+ part.commit();
17
+ prevState = { ...prevState, ...nextState };
18
+ }
19
+
20
+ part.setValue(render(initialState, setState));
21
+ });
@@ -0,0 +1,34 @@
1
+ import { App } from '../types';
2
+
3
+ export const apps: App[] = [
4
+ {
5
+ link: { href: '/#a' },
6
+ imageUrl: '/images/app-trailhead.svg',
7
+ label: 'Trailhead'
8
+ },
9
+ {
10
+ link: { href: '/#b' },
11
+ imageUrl: '/images/app-trailhead.svg',
12
+ label: 'Trailblazer Community'
13
+ },
14
+ {
15
+ link: { href: '/#c' },
16
+ imageUrl: '/images/app-trailhead.svg',
17
+ label: 'AppExchange'
18
+ },
19
+ {
20
+ link: { href: '/#d' },
21
+ imageUrl: '/images/app-trailhead.svg',
22
+ label: 'IdeaExchange'
23
+ },
24
+ {
25
+ link: { href: '/#e' },
26
+ imageUrl: '/images/app-trailhead.svg',
27
+ label: 'Events'
28
+ },
29
+ {
30
+ link: { href: '/#f' },
31
+ imageUrl: '/images/app-trailhead.svg',
32
+ label: 'Salesforce Help'
33
+ }
34
+ ];
@@ -0,0 +1,119 @@
1
+ import { querySelector } from 'kagekiri';
2
+
3
+ import { html, renderIntoBody, nextTick } from 'shared/testutils';
4
+
5
+ import { apps, apps as mockApps } from '../__fixtures__';
6
+ import { App } from '../types';
7
+
8
+ import AppLauncher from '../appLauncher';
9
+
10
+ customElements.define('tds-app-launcher', AppLauncher.CustomElementConstructor);
11
+
12
+ interface ElementOptions {
13
+ open?: boolean;
14
+ label?: string;
15
+ apps?: App[];
16
+ }
17
+
18
+ describe('tds-app-launcher', () => {
19
+ let element: HTMLElement;
20
+ let shadow: ShadowRoot;
21
+
22
+ const renderElement = (options?: ElementOptions) => {
23
+ const { label, apps, open } = {
24
+ label: 'App Launcher',
25
+ apps: mockApps,
26
+ open: false,
27
+ ...options
28
+ };
29
+ return renderIntoBody(html`
30
+ <tds-app-launcher
31
+ open=${open}
32
+ label=${label}
33
+ .apps=${apps}
34
+ ></tds-user-menu>
35
+ `);
36
+ };
37
+
38
+ beforeEach(() => {
39
+ element = renderElement();
40
+ shadow = element.shadowRoot!;
41
+ });
42
+
43
+ it('opens the menu when the container is clicked', async () => {
44
+ let clickEvent = new MouseEvent('click', {
45
+ bubbles: false,
46
+ cancelable: true
47
+ });
48
+ expect(shadow.querySelector('.menu')).toHaveAttribute(
49
+ 'aria-hidden',
50
+ 'true'
51
+ );
52
+ shadow
53
+ .querySelector('[data-menu="trigger"]')!
54
+ .dispatchEvent(clickEvent);
55
+ await nextTick();
56
+ expect(shadow.querySelector('.menu')).toHaveAttribute(
57
+ 'aria-hidden',
58
+ 'false'
59
+ );
60
+ });
61
+
62
+ it('render the label', () => {
63
+ let $button = querySelector(
64
+ 'tds-button-icon button',
65
+ renderElement({ label: 'Fancy Apps' })
66
+ )!;
67
+ expect($button.getAttribute('aria-label')).toBe('Fancy Apps');
68
+ });
69
+
70
+ it('renders each app', async () => {
71
+ let apps = [...mockApps];
72
+ let $items = shadow.querySelectorAll('.menu__item')!;
73
+ apps.forEach((app, index) => {
74
+ expect($items[index].getAttribute('href')).toBe(app.link.href);
75
+ expect($items[index].textContent).toBe(app.label);
76
+ expect(
77
+ ($items[index].firstChild! as HTMLElement).getAttribute('src')
78
+ ).toBe(app.imageUrl);
79
+ });
80
+ });
81
+
82
+ describe('tracking', () => {
83
+ it('app_launcher_clicked', async () => {
84
+ let clickEvent = new MouseEvent('click', {
85
+ bubbles: false,
86
+ cancelable: true
87
+ });
88
+ let handler = jest.fn();
89
+ document.addEventListener('trailhead_track', handler);
90
+ shadow
91
+ .querySelector('[data-menu="trigger"]')!
92
+ .dispatchEvent(clickEvent);
93
+ await nextTick();
94
+ expect(handler.mock.calls[0][0].detail).toEqual(
95
+ expect.objectContaining({
96
+ eventName: 'app_launcher_clicked'
97
+ })
98
+ );
99
+ });
100
+ it('app_launcher_link_clicked', async () => {
101
+ let clickEvent = new MouseEvent('click', {
102
+ bubbles: false,
103
+ cancelable: true
104
+ });
105
+ let handler = jest.fn();
106
+ document.addEventListener('trailhead_track', handler);
107
+ shadow
108
+ .querySelector('[data-menu="item"]')!
109
+ .dispatchEvent(clickEvent);
110
+ await nextTick();
111
+ expect(handler.mock.calls[0][0].detail).toEqual(
112
+ expect.objectContaining({
113
+ eventName: 'app_launcher_link_clicked',
114
+ payload: expect.objectContaining({ label: apps[0].label })
115
+ })
116
+ );
117
+ });
118
+ });
119
+ });
@@ -0,0 +1,65 @@
1
+ @import 'tds/reset';
2
+
3
+ a,
4
+ a:active,
5
+ a:visited {
6
+ text-decoration: none;
7
+ }
8
+
9
+ .root {
10
+ position: relative;
11
+ }
12
+
13
+ .menu {
14
+ --item-size: 7.5rem;
15
+ background-color: var(--tds-color-white);
16
+ border-radius: var(--tds-radius-lg);
17
+ box-shadow: var(--tds-shadow-lg);
18
+ box-sizing: border-box;
19
+ margin-top: var(--tds-spacing-2);
20
+ padding: var(--tds-spacing-4);
21
+ position: absolute;
22
+ top: 100%;
23
+ right: 0;
24
+ width: var(
25
+ --tds-app-launcher_menu-width,
26
+ calc((var(--item-size) * 3) + (var(--tds-spacing-4) * 2))
27
+ );
28
+ z-index: 9999;
29
+ }
30
+
31
+ .menu[aria-hidden='true'] {
32
+ display: none;
33
+ }
34
+
35
+ .menu__items {
36
+ display: grid;
37
+ grid-template-columns: repeat(auto-fit, minmax(var(--item-size), 1fr));
38
+ }
39
+
40
+ .menu__item {
41
+ align-items: center;
42
+ border: 1px solid var(--tds-color-white);
43
+ border-radius: var(--tds-radius-lg);
44
+ color: var(--tds-color-black);
45
+ display: flex;
46
+ flex-direction: column;
47
+ justify-content: flex-start;
48
+ font-size: var(--tds-font-size-sm);
49
+ padding: var(--tds-spacing-4);
50
+ text-align: center;
51
+ text-decoration: none;
52
+ }
53
+
54
+ [data-focus-visible='true'] .menu__item[data-active='true'],
55
+ .menu__item:hover {
56
+ border-color: var(--tds-color-fog);
57
+ }
58
+
59
+ .menu__item img {
60
+ margin-bottom: var(--tds-spacing-2);
61
+ }
62
+
63
+ [data-focus-visible='false'] .menu {
64
+ outline: none;
65
+ }