@hashicorp/react-components 0.0.0 → 1.0.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 (572) hide show
  1. package/.eslintrc.js +4 -0
  2. package/.stylelintrc.js +3 -0
  3. package/.test/setup-vitest.js +1 -0
  4. package/README.md +2 -78
  5. package/global.d.ts +6 -0
  6. package/package.json +29 -29
  7. package/postcss.config.js +21 -0
  8. package/src/components/actions/index.tsx +107 -0
  9. package/src/components/actions/style.module.css +28 -0
  10. package/src/components/actions/types.ts +73 -0
  11. package/src/components/call-to-action/index.tsx +205 -0
  12. package/src/components/call-to-action/styles/variant-centered.module.css +93 -0
  13. package/src/components/call-to-action/styles/variant-compact-grid.module.css +88 -0
  14. package/src/components/call-to-action/styles/variant-compact.module.css +91 -0
  15. package/src/components/call-to-action/styles/variant-links.module.css +85 -0
  16. package/src/components/card/README.md +11 -0
  17. package/src/components/card/card.tsx +45 -0
  18. package/src/components/card/index.test.tsx +69 -0
  19. package/src/components/card/index.tsx +14 -0
  20. package/src/components/card/newsroom-card/index.test.tsx +39 -0
  21. package/src/components/card/newsroom-card/index.tsx +37 -0
  22. package/src/components/card/newsroom-card/style.module.css +12 -0
  23. package/src/components/card/partner-card/index.test.tsx +57 -0
  24. package/src/components/card/partner-card/index.tsx +69 -0
  25. package/src/components/card/partner-card/style.module.css +24 -0
  26. package/src/components/card/person-card/index.test.tsx +71 -0
  27. package/src/components/card/person-card/index.tsx +93 -0
  28. package/src/components/card/person-card/style.module.css +33 -0
  29. package/src/components/card/primitives.tsx +176 -0
  30. package/src/components/card/promo-card/index.tsx +51 -0
  31. package/src/components/card/resource-card/index.test.tsx +48 -0
  32. package/src/components/card/resource-card/index.tsx +37 -0
  33. package/src/components/card/style.module.css +145 -0
  34. package/src/components/card/types.ts +66 -0
  35. package/src/components/card/unified-card/index.tsx +64 -0
  36. package/{packages → src/components}/consent-manager/README.md +44 -1
  37. package/src/components/consent-manager/components/banner/banner.module.css +23 -0
  38. package/src/components/consent-manager/components/banner/banner.test.tsx +31 -0
  39. package/src/components/consent-manager/components/banner/banner.tsx +73 -0
  40. package/src/components/consent-manager/components/dialog/dialog.module.css +145 -0
  41. package/src/components/consent-manager/components/dialog/dialog.test.tsx +194 -0
  42. package/src/components/consent-manager/components/dialog/dialog.tsx +339 -0
  43. package/src/components/consent-manager/img/icn_close.tsx +19 -0
  44. package/src/components/consent-manager/index.test.tsx +334 -0
  45. package/src/components/consent-manager/index.tsx +186 -0
  46. package/src/components/consent-manager/loader/README.md +29 -0
  47. package/src/components/consent-manager/loader/categories.ts +22 -0
  48. package/src/components/consent-manager/loader/index.tsx +94 -0
  49. package/src/components/consent-manager/loader/presets/enterprise.ts +12 -0
  50. package/src/components/consent-manager/loader/presets/oss.ts +10 -0
  51. package/src/components/consent-manager/loader/services.ts +45 -0
  52. package/src/components/consent-manager/scripts/custom.tsx +59 -0
  53. package/src/components/consent-manager/scripts/segment.tsx +87 -0
  54. package/src/components/consent-manager/style.module.css +9 -0
  55. package/src/components/consent-manager/types.ts +55 -0
  56. package/src/components/consent-manager/util/cookies.test.ts +75 -0
  57. package/src/components/consent-manager/util/cookies.ts +70 -0
  58. package/src/components/consent-manager/util/integrations.test.ts +115 -0
  59. package/src/components/consent-manager/util/integrations.ts +110 -0
  60. package/src/components/intro/index.tsx +82 -0
  61. package/src/components/intro/style.module.css +67 -0
  62. package/src/components/intro/types.ts +44 -0
  63. package/src/components/marketo-form/CHANGELOG.md +122 -0
  64. package/src/components/marketo-form/README.md +1 -0
  65. package/src/components/marketo-form/contexts/FormMetadata.ts +11 -0
  66. package/src/components/marketo-form/docs.mdx +197 -0
  67. package/src/components/marketo-form/fixtures/index.ts +185 -0
  68. package/src/components/marketo-form/form/index.tsx +369 -0
  69. package/src/components/marketo-form/index.test.tsx +320 -0
  70. package/src/components/marketo-form/index.ts +11 -0
  71. package/src/components/marketo-form/package.original.json +30 -0
  72. package/src/components/marketo-form/partials/error-message/index.tsx +12 -0
  73. package/src/components/marketo-form/partials/error-message/style.module.css +13 -0
  74. package/src/components/marketo-form/partials/field/index.tsx +90 -0
  75. package/src/components/marketo-form/partials/field-wrapper/index.tsx +26 -0
  76. package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +32 -0
  77. package/src/components/marketo-form/partials/fields/email-field/index.tsx +35 -0
  78. package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +21 -0
  79. package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +37 -0
  80. package/src/components/marketo-form/partials/fields/htmltext-field/index.tsx +21 -0
  81. package/src/components/marketo-form/partials/fields/htmltext-field/style.module.css +6 -0
  82. package/src/components/marketo-form/partials/fields/name-field/index.tsx +19 -0
  83. package/src/components/marketo-form/partials/fields/name-field/style.module.css +13 -0
  84. package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +48 -0
  85. package/src/components/marketo-form/partials/fields/select-field/index.tsx +39 -0
  86. package/src/components/marketo-form/partials/fields/select-field/style.module.css +5 -0
  87. package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +30 -0
  88. package/src/components/marketo-form/partials/fields/text-field/index.tsx +30 -0
  89. package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +29 -0
  90. package/src/components/marketo-form/partials/label/index.tsx +24 -0
  91. package/src/components/marketo-form/partials/label/style.module.css +12 -0
  92. package/src/components/marketo-form/partials/visibility-rule/index.tsx +84 -0
  93. package/src/components/marketo-form/props.js +66 -0
  94. package/src/components/marketo-form/server/api-routes.ts +109 -0
  95. package/src/components/marketo-form/server/client.ts +98 -0
  96. package/src/components/marketo-form/server/index.ts +8 -0
  97. package/src/components/marketo-form/types.ts +268 -0
  98. package/src/components/marketo-form/utils.test.tsx +103 -0
  99. package/src/components/marketo-form/utils.ts +445 -0
  100. package/src/components/next-steps/index.tsx +143 -0
  101. package/src/components/next-steps/style.module.css +270 -0
  102. package/src/components/next-steps/types.ts +63 -0
  103. package/src/components/product-badge/index.test.tsx +11 -0
  104. package/src/components/product-badge/index.tsx +42 -0
  105. package/src/components/product-badge/style.module.css +76 -0
  106. package/src/components/products-used/index.tsx +84 -0
  107. package/src/components/products-used/style.module.css +87 -0
  108. package/src/components/products-used/types.ts +31 -0
  109. package/src/components/related-content/index.test.tsx +74 -0
  110. package/src/components/related-content/index.tsx +56 -0
  111. package/src/components/related-content/style.module.css +89 -0
  112. package/src/components/related-content/types.ts +21 -0
  113. package/src/components/subnav/helpers/areBasePathsMatching.ts +13 -0
  114. package/src/components/subnav/helpers/traverse/index.ts +42 -0
  115. package/src/components/subnav/helpers/useHeightRef.ts +42 -0
  116. package/src/components/subnav/helpers/useNavRef.ts +30 -0
  117. package/src/components/subnav/helpers/useOverflowRef.ts +85 -0
  118. package/src/components/subnav/helpers/useStuckRef.ts +51 -0
  119. package/src/components/subnav/index.tsx +199 -0
  120. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.test.ts +26 -0
  121. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.ts +22 -0
  122. package/src/components/subnav/partials/CtaLinks/github-stars-link/index.tsx +87 -0
  123. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.test.ts +29 -0
  124. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.ts +32 -0
  125. package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +85 -0
  126. package/src/components/subnav/partials/CtaLinks/icons/github-logo.js +20 -0
  127. package/{packages → src/components}/subnav/partials/CtaLinks/icons/github.svg.js +5 -0
  128. package/src/components/subnav/partials/CtaLinks/icons/star.js +20 -0
  129. package/src/components/subnav/partials/CtaLinks/index.tsx +131 -0
  130. package/src/components/subnav/partials/CtaLinks/style.module.css +45 -0
  131. package/src/components/subnav/partials/DropdownTrigger/index.tsx +35 -0
  132. package/src/components/subnav/partials/DropdownTrigger/style.module.css +36 -0
  133. package/src/components/subnav/partials/MenuItemsDefault/index.tsx +151 -0
  134. package/src/components/subnav/partials/MenuItemsDefault/style.module.css +91 -0
  135. package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +139 -0
  136. package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +82 -0
  137. package/src/components/subnav/partials/TitleLink/index.tsx +113 -0
  138. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +9 -0
  139. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +9 -0
  140. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-dark.ts +23 -0
  141. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-light.ts +23 -0
  142. package/src/components/subnav/partials/TitleLink/style.module.css +43 -0
  143. package/src/components/subnav/partials/nav-item-text/index.tsx +37 -0
  144. package/src/components/subnav/partials/nav-item-text/style.module.css +15 -0
  145. package/src/components/subnav/style.module.css +68 -0
  146. package/src/components/subnav/subnav-consts.ts +1 -0
  147. package/src/components/subnav/theme.module.css +50 -0
  148. package/tsconfig.json +14 -0
  149. package/vitest.config.mts +12 -0
  150. package/.circleci/config.yml +0 -8
  151. package/.github/pull_request_template.md +0 -36
  152. package/.github/workflows/publish.yml +0 -181
  153. package/__test-helpers/expect-throw.js +0 -6
  154. package/__test-helpers/extend-expect.js +0 -1
  155. package/__test-helpers/mocks/css-module-mock.js +0 -1
  156. package/__test-helpers/mocks/graphql-fragment-mock.js +0 -1
  157. package/__test-helpers/mocks/svg-mock.js +0 -1
  158. package/babel.config.js +0 -5
  159. package/jest.config.js +0 -13
  160. package/lerna.json +0 -16
  161. package/next.config.js +0 -14
  162. package/packages/accordion/LICENSE +0 -373
  163. package/packages/accordion/README.md +0 -5
  164. package/packages/accordion/index.js +0 -21
  165. package/packages/accordion/package-lock.json +0 -13
  166. package/packages/accordion/package.json +0 -20
  167. package/packages/accordion/partials/AccordionItems/fixtures/default.json +0 -12
  168. package/packages/accordion/partials/AccordionItems/icons/arrow-down.svg +0 -1
  169. package/packages/accordion/partials/AccordionItems/index.js +0 -64
  170. package/packages/accordion/partials/AccordionItems/style.css +0 -2
  171. package/packages/accordion/partials/AccordionItems/styles/content.css +0 -47
  172. package/packages/accordion/partials/AccordionItems/styles/index.css +0 -72
  173. package/packages/accordion/partials/Collapsible/index.js +0 -87
  174. package/packages/accordion/partials/Collapsible/style.css +0 -10
  175. package/packages/accordion/style.css +0 -3
  176. package/packages/accordion/styles/index.css +0 -14
  177. package/packages/alert/LICENSE +0 -373
  178. package/packages/alert/README.md +0 -9
  179. package/packages/alert/fragment.graphql +0 -8
  180. package/packages/alert/index.js +0 -44
  181. package/packages/alert/package.json +0 -22
  182. package/packages/alert/style.css +0 -138
  183. package/packages/alert-banner/LICENSE +0 -373
  184. package/packages/alert-banner/README.md +0 -3
  185. package/packages/alert-banner/close-icon.js +0 -35
  186. package/packages/alert-banner/fragment.graphql +0 -8
  187. package/packages/alert-banner/index.jsx +0 -97
  188. package/packages/alert-banner/package-lock.json +0 -18
  189. package/packages/alert-banner/package.json +0 -26
  190. package/packages/alert-banner/style.css +0 -151
  191. package/packages/button/LICENSE +0 -373
  192. package/packages/button/README.md +0 -19
  193. package/packages/button/fragment.graphql +0 -6
  194. package/packages/button/helpers/normalizeButtonTheme.js +0 -49
  195. package/packages/button/icons/arrow-right.svg.js +0 -1
  196. package/packages/button/icons/chevron-down.svg.js +0 -1
  197. package/packages/button/icons/download.svg.js +0 -1
  198. package/packages/button/icons/external-link.svg.js +0 -1
  199. package/packages/button/index.js +0 -86
  200. package/packages/button/package-lock.json +0 -18
  201. package/packages/button/package.json +0 -21
  202. package/packages/button/styles/index.css +0 -122
  203. package/packages/button/styles/variant-primary.css +0 -232
  204. package/packages/button/styles/variant-secondary.css +0 -179
  205. package/packages/button/styles/variant-tertiary-neutral.css +0 -65
  206. package/packages/button/styles/variant-tertiary.css +0 -182
  207. package/packages/call-to-action/LICENSE +0 -373
  208. package/packages/call-to-action/README.md +0 -3
  209. package/packages/call-to-action/index.js +0 -67
  210. package/packages/call-to-action/package-lock.json +0 -27
  211. package/packages/call-to-action/package.json +0 -21
  212. package/packages/call-to-action/style.css +0 -1
  213. package/packages/call-to-action/styles/_temp-spacing-tokens.css +0 -33
  214. package/packages/call-to-action/styles/common.css +0 -27
  215. package/packages/call-to-action/styles/index.css +0 -4
  216. package/packages/call-to-action/styles/variant-centered.css +0 -44
  217. package/packages/call-to-action/styles/variant-compact.css +0 -46
  218. package/packages/call-to-action/styles/variant-links.css +0 -32
  219. package/packages/callouts/LICENSE +0 -373
  220. package/packages/callouts/README.md +0 -8
  221. package/packages/callouts/index.js +0 -67
  222. package/packages/callouts/package-lock.json +0 -33
  223. package/packages/callouts/package.json +0 -20
  224. package/packages/callouts/partials/callout-item/fixtures/default.json +0 -9
  225. package/packages/callouts/partials/callout-item/index.js +0 -71
  226. package/packages/callouts/partials/callout-item/style.css +0 -76
  227. package/packages/callouts/style.css +0 -1
  228. package/packages/callouts/styles/_temp-reset.css +0 -11
  229. package/packages/callouts/styles/_temp-spacing-tokens.css +0 -41
  230. package/packages/callouts/styles/index.css +0 -124
  231. package/packages/case-study-slider/LICENSE +0 -373
  232. package/packages/case-study-slider/Logo.js +0 -6
  233. package/packages/case-study-slider/StatusBar.js +0 -14
  234. package/packages/case-study-slider/StatusBar.test.js +0 -32
  235. package/packages/case-study-slider/docs.mdx +0 -144
  236. package/packages/case-study-slider/fragment.graphql +0 -33
  237. package/packages/case-study-slider/index.js +0 -229
  238. package/packages/case-study-slider/index.test.js +0 -279
  239. package/packages/case-study-slider/package-lock.json +0 -72
  240. package/packages/case-study-slider/package.json +0 -20
  241. package/packages/case-study-slider/props.js +0 -182
  242. package/packages/case-study-slider/readme.md +0 -7
  243. package/packages/case-study-slider/style.css +0 -176
  244. package/packages/checkbox-input/LICENSE +0 -373
  245. package/packages/checkbox-input/index.js +0 -55
  246. package/packages/checkbox-input/package-lock.json +0 -13
  247. package/packages/checkbox-input/package.json +0 -20
  248. package/packages/checkbox-input/readme.md +0 -19
  249. package/packages/checkbox-input/style.css +0 -110
  250. package/packages/code-block/LICENSE +0 -373
  251. package/packages/code-block/README.md +0 -9
  252. package/packages/code-block/fragment.graphql +0 -10
  253. package/packages/code-block/img/clipboard.svg +0 -1
  254. package/packages/code-block/index.js +0 -85
  255. package/packages/code-block/languages/sentinel.js +0 -71
  256. package/packages/code-block/package-lock.json +0 -68
  257. package/packages/code-block/package.json +0 -22
  258. package/packages/code-block/style.css +0 -162
  259. package/packages/consent-manager/LICENSE +0 -373
  260. package/packages/consent-manager/banner.js +0 -39
  261. package/packages/consent-manager/cookies.js +0 -53
  262. package/packages/consent-manager/dialog.js +0 -286
  263. package/packages/consent-manager/icn_close.js +0 -19
  264. package/packages/consent-manager/index.js +0 -119
  265. package/packages/consent-manager/integrations.js +0 -92
  266. package/packages/consent-manager/load.js +0 -139
  267. package/packages/consent-manager/package-lock.json +0 -45
  268. package/packages/consent-manager/package.json +0 -24
  269. package/packages/consent-manager/style.css +0 -209
  270. package/packages/content/LICENSE +0 -373
  271. package/packages/content/README.md +0 -8
  272. package/packages/content/index.js +0 -9
  273. package/packages/content/package.json +0 -17
  274. package/packages/content/style.css +0 -322
  275. package/packages/content-cta/LICENSE +0 -373
  276. package/packages/content-cta/README.md +0 -3
  277. package/packages/content-cta/docs.mdx +0 -25
  278. package/packages/content-cta/index.js +0 -49
  279. package/packages/content-cta/index.test.js +0 -78
  280. package/packages/content-cta/package-lock.json +0 -27
  281. package/packages/content-cta/package.json +0 -20
  282. package/packages/content-cta/props.js +0 -41
  283. package/packages/content-cta/stories/docs.mdx +0 -0
  284. package/packages/content-cta/stories/examples.stories.js +0 -51
  285. package/packages/content-cta/stories/with-knobs.stories.js +0 -58
  286. package/packages/content-cta/style.css +0 -80
  287. package/packages/docs-page/LICENSE +0 -373
  288. package/packages/docs-page/README.md +0 -51
  289. package/packages/docs-page/components.js +0 -11
  290. package/packages/docs-page/docs.mdx +0 -71
  291. package/packages/docs-page/img/github-logo.svg +0 -1
  292. package/packages/docs-page/index.js +0 -75
  293. package/packages/docs-page/index.test.js +0 -18
  294. package/packages/docs-page/package-lock.json +0 -138
  295. package/packages/docs-page/package.json +0 -28
  296. package/packages/docs-page/props.js +0 -59
  297. package/packages/docs-page/server.js +0 -137
  298. package/packages/docs-page/style.css +0 -120
  299. package/packages/docs-page/temporary_jump-to-section.js +0 -64
  300. package/packages/docs-sidenav/LICENSE +0 -373
  301. package/packages/docs-sidenav/README.md +0 -7
  302. package/packages/docs-sidenav/chevron-icon.js +0 -18
  303. package/packages/docs-sidenav/img/external.svg +0 -7
  304. package/packages/docs-sidenav/index.js +0 -457
  305. package/packages/docs-sidenav/menu-icon.js +0 -14
  306. package/packages/docs-sidenav/package-lock.json +0 -26
  307. package/packages/docs-sidenav/package.json +0 -21
  308. package/packages/docs-sidenav/style.css +0 -302
  309. package/packages/enterprise-alert/LICENSE +0 -373
  310. package/packages/enterprise-alert/README.md +0 -9
  311. package/packages/enterprise-alert/index.js +0 -28
  312. package/packages/enterprise-alert/package-lock.json +0 -13
  313. package/packages/enterprise-alert/package.json +0 -23
  314. package/packages/enterprise-alert/style.css +0 -91
  315. package/packages/featured-slider/LICENSE +0 -373
  316. package/packages/featured-slider/README.md +0 -3
  317. package/packages/featured-slider/StatusBar.js +0 -14
  318. package/packages/featured-slider/docs.mdx +0 -60
  319. package/packages/featured-slider/index.js +0 -231
  320. package/packages/featured-slider/index.test.js +0 -59
  321. package/packages/featured-slider/package-lock.json +0 -66
  322. package/packages/featured-slider/package.json +0 -22
  323. package/packages/featured-slider/props.js +0 -82
  324. package/packages/featured-slider/style.css +0 -204
  325. package/packages/hashi-stack-menu/LICENSE +0 -373
  326. package/packages/hashi-stack-menu/README.md +0 -3
  327. package/packages/hashi-stack-menu/assets/icon-dropdown.svg +0 -1
  328. package/packages/hashi-stack-menu/assets/logo.svg +0 -1
  329. package/packages/hashi-stack-menu/assets/product-icons/boundary-icon-color.svg +0 -1
  330. package/packages/hashi-stack-menu/assets/product-icons/consul-icon-color.svg +0 -1
  331. package/packages/hashi-stack-menu/assets/product-icons/nomad-icon-color.svg +0 -1
  332. package/packages/hashi-stack-menu/assets/product-icons/packer-icon-color.svg +0 -1
  333. package/packages/hashi-stack-menu/assets/product-icons/terraform-icon-color.svg +0 -1
  334. package/packages/hashi-stack-menu/assets/product-icons/vagrant-icon-color.svg +0 -1
  335. package/packages/hashi-stack-menu/assets/product-icons/vault-icon-color.svg +0 -1
  336. package/packages/hashi-stack-menu/assets/product-icons/waypoint-icon-color.svg +0 -1
  337. package/packages/hashi-stack-menu/browse-panel/browse-panel.module.css +0 -33
  338. package/packages/hashi-stack-menu/browse-panel/index.jsx +0 -9
  339. package/packages/hashi-stack-menu/data/index.js +0 -125
  340. package/packages/hashi-stack-menu/hashi-stack-menu.module.css +0 -41
  341. package/packages/hashi-stack-menu/index.jsx +0 -51
  342. package/packages/hashi-stack-menu/nav-item/index.jsx +0 -100
  343. package/packages/hashi-stack-menu/nav-item/nav-item.module.css +0 -64
  344. package/packages/hashi-stack-menu/package-lock.json +0 -18
  345. package/packages/hashi-stack-menu/package.json +0 -17
  346. package/packages/hashi-stack-menu/stack-group/index.jsx +0 -16
  347. package/packages/hashi-stack-menu/stack-group/stack-group.module.css +0 -29
  348. package/packages/hashi-stack-menu/stack-item/index.jsx +0 -35
  349. package/packages/hashi-stack-menu/stack-item/stack-item.module.css +0 -58
  350. package/packages/hashi-stack-menu/stack-menu-section/index.jsx +0 -18
  351. package/packages/hashi-stack-menu/stack-menu-section/stack-menu-section.module.css +0 -26
  352. package/packages/hashi-stack-menu/use-on-click-outside-dropdown.js +0 -22
  353. package/packages/head/LICENSE +0 -373
  354. package/packages/head/README.md +0 -236
  355. package/packages/head/index.d.ts +0 -107
  356. package/packages/head/index.js +0 -66
  357. package/packages/head/package.json +0 -17
  358. package/packages/hero/LICENSE +0 -373
  359. package/packages/hero/README.md +0 -31
  360. package/packages/hero/arrow-icon.js +0 -24
  361. package/packages/hero/carousel.js +0 -153
  362. package/packages/hero/fragment.graphql +0 -55
  363. package/packages/hero/heroLeadForm.js +0 -107
  364. package/packages/hero/index.js +0 -129
  365. package/packages/hero/package-lock.json +0 -273
  366. package/packages/hero/package.json +0 -28
  367. package/packages/hero/style.css +0 -501
  368. package/packages/image/LICENSE +0 -373
  369. package/packages/image/fragment.graphql +0 -5
  370. package/packages/image/index.js +0 -81
  371. package/packages/image/package-lock.json +0 -33
  372. package/packages/image/package.json +0 -21
  373. package/packages/image/readme.md +0 -27
  374. package/packages/inline-svg/LICENSE +0 -373
  375. package/packages/inline-svg/README.md +0 -9
  376. package/packages/inline-svg/docs.mdx +0 -15
  377. package/packages/inline-svg/index.js +0 -23
  378. package/packages/inline-svg/index.test.js +0 -50
  379. package/packages/inline-svg/package.json +0 -30
  380. package/packages/inline-svg/props.js +0 -10
  381. package/packages/learn-callout/LICENSE +0 -373
  382. package/packages/learn-callout/README.md +0 -9
  383. package/packages/learn-callout/docs.mdx +0 -31
  384. package/packages/learn-callout/index.js +0 -57
  385. package/packages/learn-callout/index.test.js +0 -49
  386. package/packages/learn-callout/props.js +0 -47
  387. package/packages/learn-callout/style.css +0 -207
  388. package/packages/link-wrap/LICENSE +0 -373
  389. package/packages/link-wrap/README.md +0 -44
  390. package/packages/link-wrap/index.js +0 -40
  391. package/packages/link-wrap/package-lock.json +0 -5
  392. package/packages/link-wrap/package.json +0 -17
  393. package/packages/logo-grid/LICENSE +0 -373
  394. package/packages/logo-grid/README.md +0 -26
  395. package/packages/logo-grid/fragment.graphql +0 -17
  396. package/packages/logo-grid/index.js +0 -157
  397. package/packages/logo-grid/package-lock.json +0 -111
  398. package/packages/logo-grid/package.json +0 -21
  399. package/packages/logo-grid/style.css +0 -148
  400. package/packages/product-downloader/LICENSE +0 -373
  401. package/packages/product-downloader/README.md +0 -9
  402. package/packages/product-downloader/index.js +0 -102
  403. package/packages/product-downloader/package-lock.json +0 -103
  404. package/packages/product-downloader/package.json +0 -18
  405. package/packages/product-downloader/partials/download-cards/index.jsx +0 -125
  406. package/packages/product-downloader/partials/download-cards/style.module.css +0 -152
  407. package/packages/product-downloader/partials/dropdown/index.jsx +0 -58
  408. package/packages/product-downloader/partials/dropdown/style.module.css +0 -28
  409. package/packages/product-downloader/partials/logos/fastly.svg +0 -7
  410. package/packages/product-downloader/partials/release-information/index.jsx +0 -148
  411. package/packages/product-downloader/partials/release-information/style.module.css +0 -101
  412. package/packages/product-downloader/style.module.css +0 -100
  413. package/packages/product-downloader/utils/downloader.js +0 -136
  414. package/packages/product-features-list/LICENSE +0 -373
  415. package/packages/product-features-list/README.md +0 -3
  416. package/packages/product-features-list/index.js +0 -30
  417. package/packages/product-features-list/package-lock.json +0 -42
  418. package/packages/product-features-list/package.json +0 -20
  419. package/packages/product-features-list/style.css +0 -90
  420. package/packages/search/LICENSE +0 -373
  421. package/packages/search/README.md +0 -188
  422. package/packages/search/hits.js +0 -196
  423. package/packages/search/img/return.svg.js +0 -1
  424. package/packages/search/img/search-legend-enter.svg.js +0 -1
  425. package/packages/search/img/search-legend-escape.svg.js +0 -1
  426. package/packages/search/img/search-legend-page.svg.js +0 -1
  427. package/packages/search/img/search-x.svg.js +0 -1
  428. package/packages/search/img/search.svg.js +0 -1
  429. package/packages/search/img/slash-search-toggle.js +0 -17
  430. package/packages/search/index.js +0 -60
  431. package/packages/search/legend.js +0 -32
  432. package/packages/search/package-lock.json +0 -931
  433. package/packages/search/package.json +0 -29
  434. package/packages/search/provider.js +0 -81
  435. package/packages/search/search-box.js +0 -139
  436. package/packages/search/style.css +0 -366
  437. package/packages/search/tools.js +0 -166
  438. package/packages/section-header/LICENSE +0 -373
  439. package/packages/section-header/README.md +0 -13
  440. package/packages/section-header/fragment.graphql +0 -5
  441. package/packages/section-header/index.js +0 -42
  442. package/packages/section-header/package-lock.json +0 -18
  443. package/packages/section-header/package.json +0 -20
  444. package/packages/section-header/style.css +0 -18
  445. package/packages/select-input/LICENSE +0 -373
  446. package/packages/select-input/README.md +0 -1
  447. package/packages/select-input/img/dropdown-arrow.svg +0 -1
  448. package/packages/select-input/index.js +0 -80
  449. package/packages/select-input/package-lock.json +0 -70
  450. package/packages/select-input/package.json +0 -19
  451. package/packages/select-input/style.css +0 -88
  452. package/packages/subnav/LICENSE +0 -373
  453. package/packages/subnav/README.md +0 -85
  454. package/packages/subnav/helpers/globalThis.js +0 -9
  455. package/packages/subnav/helpers/traverse/index.js +0 -34
  456. package/packages/subnav/helpers/useNavRef.js +0 -16
  457. package/packages/subnav/helpers/useOverflowRef.js +0 -76
  458. package/packages/subnav/helpers/useStuckRef.js +0 -43
  459. package/packages/subnav/icons/boundary-logo-color.svgr.js +0 -32
  460. package/packages/subnav/icons/chevron-down.svg.js +0 -3
  461. package/packages/subnav/icons/consul-logo-color.svgr.js +0 -44
  462. package/packages/subnav/icons/hcp-logo-black-white.svgr.js +0 -29
  463. package/packages/subnav/icons/nomad-logo-color.svgr.js +0 -50
  464. package/packages/subnav/icons/packer-logo-color.svgr.js +0 -40
  465. package/packages/subnav/icons/terraform-logo-color.svgr.js +0 -44
  466. package/packages/subnav/icons/vagrant-logo-color.svgr.js +0 -38
  467. package/packages/subnav/icons/vault-logo-color.svgr.js +0 -32
  468. package/packages/subnav/icons/waypoint-logo-color.svgr.js +0 -28
  469. package/packages/subnav/index.js +0 -107
  470. package/packages/subnav/package-lock.json +0 -56
  471. package/packages/subnav/package.json +0 -25
  472. package/packages/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.js +0 -17
  473. package/packages/subnav/partials/CtaLinks/github-stars-link/index.js +0 -71
  474. package/packages/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.js +0 -25
  475. package/packages/subnav/partials/CtaLinks/github-stars-link/style.css +0 -78
  476. package/packages/subnav/partials/CtaLinks/icons/github-logo.js +0 -14
  477. package/packages/subnav/partials/CtaLinks/icons/star.js +0 -14
  478. package/packages/subnav/partials/CtaLinks/index.js +0 -48
  479. package/packages/subnav/partials/CtaLinks/style.css +0 -32
  480. package/packages/subnav/partials/DropdownTrigger/index.js +0 -20
  481. package/packages/subnav/partials/DropdownTrigger/style.css +0 -27
  482. package/packages/subnav/partials/MenuItemsDefault/index.js +0 -131
  483. package/packages/subnav/partials/MenuItemsDefault/style.css +0 -63
  484. package/packages/subnav/partials/MenuItemsOverflow/index.js +0 -117
  485. package/packages/subnav/partials/MenuItemsOverflow/style.css +0 -38
  486. package/packages/subnav/partials/TitleLink/index.js +0 -40
  487. package/packages/subnav/partials/TitleLink/style.css +0 -21
  488. package/packages/subnav/style.css +0 -6
  489. package/packages/subnav/styles/_temp-g-svg.css +0 -22
  490. package/packages/subnav/styles/_temp-resets.css +0 -15
  491. package/packages/subnav/styles/index.css +0 -103
  492. package/packages/tabbed-accordion/LICENSE +0 -373
  493. package/packages/tabbed-accordion/README.md +0 -3
  494. package/packages/tabbed-accordion/fixtures/base.json +0 -44
  495. package/packages/tabbed-accordion/index.js +0 -27
  496. package/packages/tabbed-accordion/package-lock.json +0 -27
  497. package/packages/tabbed-accordion/package.json +0 -19
  498. package/packages/tabbed-accordion/style/_temp-spacing-tokens.css +0 -36
  499. package/packages/tabbed-accordion/style/index.css +0 -22
  500. package/packages/tabbed-accordion/style.css +0 -1
  501. package/packages/tabs/LICENSE +0 -373
  502. package/packages/tabs/README.md +0 -31
  503. package/packages/tabs/index.js +0 -41
  504. package/packages/tabs/package-lock.json +0 -73
  505. package/packages/tabs/package.json +0 -18
  506. package/packages/tabs/partials/TabTriggers/helpers/smoothScroll.js +0 -77
  507. package/packages/tabs/partials/TabTriggers/icons/chevron-right_black.svg.js +0 -1
  508. package/packages/tabs/partials/TabTriggers/index.js +0 -143
  509. package/packages/tabs/partials/TabTriggers/partials/TabTrigger/icons/tooltip.svg.js +0 -1
  510. package/packages/tabs/partials/TabTriggers/partials/TabTrigger/index.js +0 -37
  511. package/packages/tabs/partials/TabTriggers/partials/TabTrigger/style.css +0 -75
  512. package/packages/tabs/partials/TabTriggers/style.css +0 -152
  513. package/packages/tabs/style.css +0 -67
  514. package/packages/terminal/LICENSE +0 -373
  515. package/packages/terminal/README.md +0 -9
  516. package/packages/terminal/Terminal.module.css +0 -146
  517. package/packages/terminal/index.jsx +0 -46
  518. package/packages/terminal/package.json +0 -17
  519. package/packages/text-input/LICENSE +0 -373
  520. package/packages/text-input/README.md +0 -24
  521. package/packages/text-input/index.js +0 -42
  522. package/packages/text-input/package-lock.json +0 -13
  523. package/packages/text-input/package.json +0 -19
  524. package/packages/text-input/style.css +0 -68
  525. package/packages/text-split/LICENSE +0 -373
  526. package/packages/text-split/README.md +0 -3
  527. package/packages/text-split/index.js +0 -66
  528. package/packages/text-split/package-lock.json +0 -35
  529. package/packages/text-split/package.json +0 -20
  530. package/packages/text-split/partials/button-group/index.js +0 -40
  531. package/packages/text-split/partials/button-group/style.css +0 -28
  532. package/packages/text-split/partials/checkbox-list/icons/check-circle.svg.jsx +0 -39
  533. package/packages/text-split/partials/checkbox-list/index.js +0 -28
  534. package/packages/text-split/partials/checkbox-list/style.css +0 -59
  535. package/packages/text-split/style.css +0 -1
  536. package/packages/text-split/styles/_temp-spacing-tokens.css +0 -37
  537. package/packages/text-split/styles/index.css +0 -86
  538. package/packages/text-split-with-code/LICENSE +0 -373
  539. package/packages/text-split-with-code/README.md +0 -13
  540. package/packages/text-split-with-code/index.js +0 -29
  541. package/packages/text-split-with-code/package-lock.json +0 -117
  542. package/packages/text-split-with-code/package.json +0 -21
  543. package/packages/text-split-with-code/style.css +0 -42
  544. package/packages/text-split-with-image/LICENSE +0 -373
  545. package/packages/text-split-with-image/README.md +0 -12
  546. package/packages/text-split-with-image/index.js +0 -11
  547. package/packages/text-split-with-image/package-lock.json +0 -75
  548. package/packages/text-split-with-image/package.json +0 -17
  549. package/packages/text-split-with-logo-grid/LICENSE +0 -373
  550. package/packages/text-split-with-logo-grid/README.md +0 -8
  551. package/packages/text-split-with-logo-grid/index.js +0 -63
  552. package/packages/text-split-with-logo-grid/package-lock.json +0 -90
  553. package/packages/text-split-with-logo-grid/package.json +0 -18
  554. package/packages/text-split-with-logo-grid/style.css +0 -88
  555. package/packages/toggle/LICENSE +0 -373
  556. package/packages/toggle/index.js +0 -22
  557. package/packages/toggle/package-lock.json +0 -5
  558. package/packages/toggle/package.json +0 -17
  559. package/packages/toggle/readme.md +0 -7
  560. package/packages/toggle/style.css +0 -35
  561. package/packages/vertical-text-block-list/LICENSE +0 -373
  562. package/packages/vertical-text-block-list/README.md +0 -15
  563. package/packages/vertical-text-block-list/index.js +0 -54
  564. package/packages/vertical-text-block-list/package-lock.json +0 -60
  565. package/packages/vertical-text-block-list/package.json +0 -22
  566. package/packages/vertical-text-block-list/style.css +0 -104
  567. package/pages/_app.jsx +0 -5
  568. package/pages/global.css +0 -43
  569. package/pages/index.jsx +0 -16
  570. package/prettier.config.js +0 -4
  571. package/scripts/release-check-branch.sh +0 -15
  572. package/scripts/release-check-npm-auth.sh +0 -39
@@ -0,0 +1,334 @@
1
+ import { fireEvent, render, screen, act } from '@testing-library/react'
2
+
3
+ const defaultProps = {
4
+ version: 0,
5
+ showDialog: false,
6
+ segmentWriteKey: 'iyi06c432UL7SB1r3fQReec4bNwFyzkW',
7
+ privacyPolicyLink: 'https://www.hashicorp.com/privacy',
8
+ companyName: 'HashiCorp',
9
+ segmentServices: [
10
+ {
11
+ name: 'Example Name',
12
+ category: 'Example Category',
13
+ description:
14
+ 'A short description of what the service is and how your company uses the data.',
15
+ },
16
+ ],
17
+ additionalServices: [
18
+ {
19
+ name: 'Name of the service',
20
+ category: 'Example Category',
21
+ description:
22
+ 'A short description of what the service is and how your company uses the data.',
23
+ body: '',
24
+ url: 'http://www.an-optional-url-for-a-script-to-add-to-the-page.com',
25
+ async: true,
26
+ },
27
+ {
28
+ name: 'Name of the service 2',
29
+ category: 'Example Category',
30
+ description: 'A script with additional elements to be injected',
31
+ body: '',
32
+ url: 'https://source-url-of-script.com',
33
+ async: true,
34
+ addToBody: true,
35
+ dataAttrs: [
36
+ {
37
+ name: 'test',
38
+ value: 'foobar',
39
+ },
40
+ ],
41
+ },
42
+ {
43
+ name: 'Name of the service 3',
44
+ category: 'Example Category',
45
+ description: 'A script with additional elements to be injected',
46
+ body: 'window.foo = "bar"',
47
+ async: true,
48
+ dataAttrs: [
49
+ {
50
+ name: 'test',
51
+ value: 'foobar',
52
+ },
53
+ ],
54
+ },
55
+ {
56
+ name: 'Name of the conditionally loaded service',
57
+ category: 'Example Category with conditionally loaded service',
58
+ description: 'A script with additional elements to be injected',
59
+ body: 'window.foo = "bar"',
60
+ url: 'https://source-of-conditionally-loaded-script.com',
61
+ async: true,
62
+ dataAttrs: [
63
+ {
64
+ name: 'test',
65
+ value: 'foobar',
66
+ },
67
+ ],
68
+ shouldLoad: () => false,
69
+ },
70
+ ],
71
+ categories: [
72
+ {
73
+ name: 'Example Category',
74
+ description: 'A short description of the category',
75
+ },
76
+ ],
77
+ container: '#consent-manager',
78
+ }
79
+
80
+ beforeAll(() => {
81
+ HTMLDialogElement.prototype.show = vi.fn()
82
+ HTMLDialogElement.prototype.showModal = vi.fn()
83
+ HTMLDialogElement.prototype.close = vi.fn()
84
+ })
85
+
86
+ describe('ConsentManager', () => {
87
+ afterEach(() => {
88
+ vi.resetModules()
89
+ })
90
+
91
+ test('shows the banner if the forceShow prop is true', async () => {
92
+ const { default: ConsentManager } = await import('./')
93
+ render(<ConsentManager {...defaultProps} forceShow={true} />)
94
+ expect(screen.getByTestId('consent-banner')).toBeInTheDocument()
95
+ })
96
+
97
+ test('sets existing preferences and does not show the banner if preferences are already set', async () => {
98
+ await runWithMockedImport(
99
+ './util/cookies',
100
+ {
101
+ loadPreferences: () => {
102
+ return { loadAll: false, segment: false, version: 0 }
103
+ },
104
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
105
+ savePreferences: () => {},
106
+ },
107
+ (MockedConsentManager) => {
108
+ render(<MockedConsentManager {...defaultProps} forceShow={false} />)
109
+ expect(screen.queryByTestId('consent-banner')).not.toBeInTheDocument()
110
+ }
111
+ )
112
+ })
113
+
114
+ test('shows the banner if preferences are set but version has increased', async () => {
115
+ await runWithMockedImport(
116
+ './util/cookies',
117
+ {
118
+ loadPreferences: () => {
119
+ return { loadAll: false, segment: false, version: 1 }
120
+ },
121
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
122
+ savePreferences: () => {},
123
+ },
124
+ (MockedConsentManager) => {
125
+ render(
126
+ <MockedConsentManager
127
+ {...defaultProps}
128
+ forceShow={false}
129
+ version={2}
130
+ />
131
+ )
132
+ expect(screen.queryByTestId('consent-banner')).toBeInTheDocument()
133
+ }
134
+ )
135
+ })
136
+
137
+ test('if the manage preferences button is clicked, opens the dialog and makes body un-scrollable', async () => {
138
+ const { default: ConsentManager } = await import('./')
139
+
140
+ render(<ConsentManager {...defaultProps} forceShow={true} />)
141
+ fireEvent.click(screen.getByTestId('manage-preferences'))
142
+ expect(screen.getByTestId('consent-mgr-dialog')).toBeInTheDocument()
143
+ expect(document.body.className).toBe('g-noscroll')
144
+ })
145
+
146
+ test('opens the dialog when the open function is called', async () => {
147
+ const { default: ConsentManager, open } = await import('./')
148
+ render(<ConsentManager {...defaultProps} />)
149
+ act(() => open())
150
+ expect(screen.getByTestId('consent-mgr-dialog')).toBeInTheDocument()
151
+ })
152
+
153
+ test('if accept all button is clicked, any open dialogs are closed and all analytics are loaded', async () => {
154
+ let prefs
155
+ await runWithMockedImport(
156
+ './util/cookies',
157
+ {
158
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
159
+ loadPreferences: () => {},
160
+ savePreferences: (preferences) => {
161
+ prefs = preferences
162
+ },
163
+ },
164
+ (MockedConsentManager) => {
165
+ render(<MockedConsentManager {...defaultProps} forceShow={true} />)
166
+ fireEvent.click(screen.getByTestId('accept'))
167
+ }
168
+ )
169
+ expect(prefs.loadAll).toBe(true)
170
+ })
171
+
172
+ test('loads segment and additional services if loadAll is passed', async () => {
173
+ await runWithMockedImport(
174
+ './util/cookies',
175
+ {
176
+ loadPreferences: () => {
177
+ return { loadAll: true, segment: { foo: 'bar' } }
178
+ },
179
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
180
+ savePreferences: () => {},
181
+ },
182
+ (MockedConsentManager) => {
183
+ render(
184
+ <MockedConsentManager
185
+ {...defaultProps}
186
+ forceShow={false}
187
+ version={2}
188
+ />
189
+ )
190
+ const html = document.body.innerHTML
191
+ // script was injected
192
+ expect(html).toMatch(
193
+ /<script type="text\/javascript" src="https:\/\/artemis.hashicorp.com\/script/
194
+ )
195
+ // all services loaded, as well as custom segment
196
+ expect(html).toMatch(
197
+ /analytics\.load\("iyi06c432UL7SB1r3fQReec4bNwFyzkW", {"integrations":{"All":true,"Segment\.io":true,"foo":"bar"}}\);/
198
+ )
199
+
200
+ // custom service loaded
201
+ expect(html).toMatch(
202
+ /src="http:\/\/www.an-optional-url-for-a-script-to-add-to-the-page\.com"/
203
+ )
204
+
205
+ // conditionally loaded service not loaded
206
+ expect(html).not.toMatch(
207
+ /src="https:\/\/source-of-conditionally-loaded-script\.com"/
208
+ )
209
+
210
+ // custom inline script
211
+ expect(html).toMatch(/window\.foo = "bar"/)
212
+ }
213
+ )
214
+ })
215
+
216
+ describe('handles custom events', () => {
217
+ test('manage preferences callback', async () => {
218
+ const fn = vi.fn()
219
+ await runWithMockedImport(
220
+ './components/dialog',
221
+ {
222
+ default: () => {
223
+ return <p data-testid="mocked-dialog">test</p>
224
+ },
225
+ },
226
+ (MockedConsentManager) => {
227
+ render(
228
+ <MockedConsentManager
229
+ {...defaultProps}
230
+ forceShow={true}
231
+ onManagePreferences={fn}
232
+ />
233
+ )
234
+ fireEvent.click(screen.getByTestId('manage-preferences'))
235
+ expect(fn).toHaveBeenCalled()
236
+ }
237
+ )
238
+ })
239
+
240
+ test('accept all callback', async () => {
241
+ const fn = vi.fn()
242
+ await runWithMockedImport(
243
+ './components/dialog',
244
+ {
245
+ default: () => {
246
+ return <p data-testid="mocked-dialog">test</p>
247
+ },
248
+ },
249
+ (MockedConsentManager) => {
250
+ render(
251
+ <MockedConsentManager
252
+ {...defaultProps}
253
+ forceShow={true}
254
+ onAcceptAll={fn}
255
+ />
256
+ )
257
+ fireEvent.click(screen.getByTestId('accept'))
258
+ expect(fn).toHaveBeenCalled()
259
+ }
260
+ )
261
+ })
262
+ })
263
+
264
+ describe('handles conditionally loaded services in dialog', () => {
265
+ test('additional services category is not in dialog when shouldLoad() is false in all category services', async () => {
266
+ const { default: ConsentManager, open } = await import('./')
267
+ render(<ConsentManager {...defaultProps} />)
268
+ act(() => open())
269
+
270
+ const shownCategory = await screen.findByText('Example Category')
271
+ const hiddenCategory = screen.queryByText(
272
+ 'Example Category with conditionally loaded service'
273
+ )
274
+ expect(shownCategory).toBeInTheDocument()
275
+ expect(hiddenCategory).not.toBeInTheDocument()
276
+ })
277
+
278
+ test('additional services category is in dialog when shouldLoad() is false in some category services but service is not in dialog', async () => {
279
+ const newService = {
280
+ name: 'Name of the new service',
281
+ category: 'Example Category with conditionally loaded service',
282
+ description: 'A script with additional elements to be injected',
283
+ body: 'window.foo = "bar"',
284
+ async: true,
285
+ dataAttrs: [
286
+ {
287
+ name: 'test',
288
+ value: 'foobar',
289
+ },
290
+ ],
291
+ }
292
+
293
+ const { default: ConsentManager, open } = await import('./')
294
+ render(
295
+ <ConsentManager
296
+ {...{
297
+ ...defaultProps,
298
+ additionalServices: [
299
+ ...defaultProps.additionalServices,
300
+ newService,
301
+ ],
302
+ }}
303
+ />
304
+ )
305
+ act(() => open())
306
+ const category = await screen.findByText(
307
+ 'Example Category with conditionally loaded service'
308
+ )
309
+
310
+ expect(category).toBeInTheDocument()
311
+ const showMoreButton = category.nextSibling!.nextSibling!
312
+ // Open category accordion item to make services visible
313
+ fireEvent.click(showMoreButton)
314
+ const shouldLoadService = await screen.findByText(
315
+ 'Name of the new service'
316
+ )
317
+ const shouldNotLoadService = screen.queryByText(
318
+ 'Name of the conditionally loaded service'
319
+ )
320
+ expect(shouldLoadService).toBeInTheDocument()
321
+ expect(shouldNotLoadService).not.toBeInTheDocument()
322
+ })
323
+ })
324
+ })
325
+
326
+ // Given an internal module name and mock implementation, mocks the given module and returns a version
327
+ // of the component with the module mocked.
328
+ async function runWithMockedImport(module, mock, cb) {
329
+ vi.doMock(module, () => mock)
330
+ return import('./').then(({ default: ConsentManager, open }) => {
331
+ cb(ConsentManager, open)
332
+ vi.doUnmock(module)
333
+ })
334
+ }
@@ -0,0 +1,186 @@
1
+ import { useState, useEffect, useCallback } from 'react'
2
+ import { EventEmitter } from 'events'
3
+ import classNames from 'classnames'
4
+ import { isInUS } from '@hashicorp/platform-util/geo'
5
+ import { loadPreferences, savePreferences } from './util/cookies'
6
+ import ConsentBanner from './components/banner/banner'
7
+ import ConsentPreferences from './components/dialog/dialog'
8
+ import SegmentScript from './scripts/segment'
9
+ import CustomScripts from './scripts/custom'
10
+ import s from './style.module.css'
11
+ import {
12
+ ConsentManagerCategory,
13
+ ConsentManagerService,
14
+ ConsentManagerPreferences,
15
+ } from './types'
16
+
17
+ interface ConsentManagerProps {
18
+ additionalServices?: ConsentManagerService[]
19
+ categories?: ConsentManagerCategory[]
20
+ className?: string
21
+ cookiePolicyLink?: string
22
+ forceShow?: boolean
23
+ privacyPolicyLink?: string
24
+ segmentServices?: ConsentManagerService[]
25
+ segmentWriteKey?: string
26
+ showDialog?: boolean
27
+ version?: number
28
+ onManagePreferences?: () => void
29
+ onAcceptAll?: () => void
30
+ }
31
+
32
+ const emitter = new EventEmitter()
33
+
34
+ export function open() {
35
+ emitter.emit('openDialog')
36
+ }
37
+
38
+ export function saveAndLoadAnalytics(preferences: ConsentManagerPreferences) {
39
+ emitter.emit('saveAndLoadAnalytics', preferences)
40
+ }
41
+
42
+ export default function ConsentManager(props: ConsentManagerProps) {
43
+ const [preferences, setPreferences] = useState<{
44
+ loadAll?: boolean
45
+ version?: number
46
+ }>(loadPreferences() ?? {})
47
+ const [showDialog, setShowDialog] = useState(props.showDialog ?? false)
48
+ const [showBanner, setShowBanner] = useState(() => {
49
+ // 1. If prop override is set, always show the consent bar.
50
+ if (props.forceShow) return true
51
+ })
52
+
53
+ const hasEmptyPreferencesOrVersionMismatch =
54
+ Object.keys(preferences).length === 0 ||
55
+ preferences.version !== props.version
56
+
57
+ const closeDialog = () => {
58
+ document.body.classList.remove('g-noscroll')
59
+ setShowDialog(false)
60
+ setShowBanner(false)
61
+ setPreferences(loadPreferences() ?? {})
62
+ }
63
+
64
+ const saveAndLoadAnalytics = useCallback(
65
+ (preferences) => {
66
+ if (typeof preferences === 'undefined') {
67
+ preferences = { loadAll: false, segment: false }
68
+ }
69
+ savePreferences(preferences, props.version)
70
+
71
+ // If analytics have already been added to page, it's likely you're updating your preferences
72
+ // We reload the page to re-initiate the script with the updated integrations
73
+ if (window.analytics && window.analytics.initialized) {
74
+ window.location.reload()
75
+ return
76
+ }
77
+
78
+ closeDialog()
79
+ },
80
+ [props.version]
81
+ )
82
+
83
+ const openDialog = useCallback(() => {
84
+ document.body.classList.add('g-noscroll')
85
+ setShowBanner(false)
86
+ setShowDialog(true)
87
+ }, [])
88
+
89
+ // Setup the event handler to open the dialog imperatively
90
+ useEffect(() => {
91
+ emitter.on('openDialog', openDialog)
92
+ return () => {
93
+ emitter.off('openDialog', openDialog)
94
+ }
95
+ }, [openDialog])
96
+
97
+ // Setup the event handler to save and load analytics imperatively
98
+ useEffect(() => {
99
+ emitter.on('saveAndLoadAnalytics', saveAndLoadAnalytics)
100
+ return () => {
101
+ emitter.off('saveAndLoadAnalytics', saveAndLoadAnalytics)
102
+ }
103
+ }, [saveAndLoadAnalytics])
104
+
105
+ // Show banner if there are no preferences or the version mismatches
106
+ useEffect(() => {
107
+ setShowBanner(hasEmptyPreferencesOrVersionMismatch)
108
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- We only want to run this check once
109
+ }, [])
110
+
111
+ useEffect(() => {
112
+ if (hasEmptyPreferencesOrVersionMismatch && isInUS()) {
113
+ saveAndLoadAnalytics({ loadAll: true })
114
+ setShowBanner(true)
115
+ }
116
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- We only want to run this check once
117
+ }, [])
118
+
119
+ const escFunction = useCallback(
120
+ (event) => {
121
+ if (showDialog && event.key === 'Escape') {
122
+ closeDialog()
123
+ }
124
+ },
125
+ [showDialog]
126
+ )
127
+
128
+ useEffect(() => {
129
+ document.addEventListener('keydown', escFunction, false)
130
+
131
+ return () => {
132
+ document.removeEventListener('keydown', escFunction, false)
133
+ }
134
+ }, [escFunction])
135
+
136
+ const filteredAdditionalServices = props.additionalServices?.filter(
137
+ (service) => service.shouldLoad === undefined || service.shouldLoad()
138
+ )
139
+
140
+ return (
141
+ <div className={classNames(s.root, props.className)}>
142
+ {/* Consent banner at the bottom */}
143
+ {showBanner && (
144
+ <ConsentBanner
145
+ preferences={preferences}
146
+ privacyPolicyLink={props.privacyPolicyLink}
147
+ cookiePolicyLink={props.cookiePolicyLink}
148
+ onManagePreferences={() => {
149
+ openDialog()
150
+ if (props.onManagePreferences) {
151
+ props.onManagePreferences()
152
+ }
153
+ }}
154
+ onAccept={() => {
155
+ saveAndLoadAnalytics({ loadAll: true })
156
+ if (props.onAcceptAll) {
157
+ props.onAcceptAll()
158
+ }
159
+ }}
160
+ />
161
+ )}
162
+ {/* Consent manager preferences dialog */}
163
+ <ConsentPreferences
164
+ version={props.version}
165
+ segmentWriteKey={props.segmentWriteKey}
166
+ segmentServices={props.segmentServices}
167
+ additionalServices={filteredAdditionalServices}
168
+ preferences={preferences}
169
+ categories={props.categories || []}
170
+ privacyPolicyLink={props.privacyPolicyLink}
171
+ cookiePolicyLink={props.cookiePolicyLink}
172
+ saveAndLoadAnalytics={saveAndLoadAnalytics}
173
+ showDialog={showDialog}
174
+ />
175
+
176
+ <SegmentScript
177
+ preferences={preferences}
178
+ writeKey={props.segmentWriteKey}
179
+ />
180
+ <CustomScripts
181
+ preferences={preferences}
182
+ services={filteredAdditionalServices}
183
+ />
184
+ </div>
185
+ )
186
+ }
@@ -0,0 +1,29 @@
1
+ # Consent Manager Loader
2
+
3
+ The consent manager component is large and complex, with many configurable options. The consent manager loader interface makes a bunch of assumptions and strips down the number of configurable options to very few, which is enough to do the trick for most of our web properties.
4
+
5
+ The loader also ships with a couple **presets**, which load in standard sets of tracking scripts that we tend to adhere towards. Currently, the available options are `oss` and `enterprise`.
6
+
7
+ ## Usage
8
+
9
+ Code block below shows basic usage:
10
+
11
+ ```js
12
+ import createConsentManager from '@hashicorp/react-consent-manager/loader'
13
+
14
+ const { ConsentManager, openConsentManager } = createConsentManager({
15
+ preset: 'oss',
16
+ })
17
+
18
+ // sample implementation
19
+ export default function SomePage() {
20
+ return (
21
+ <>
22
+ <p>my page content</p>
23
+ <ConsentManager />
24
+ </>
25
+ )
26
+ }
27
+ ```
28
+
29
+ Check out the [types](types.ts) to get an overview of the full options that can be passed in!
@@ -0,0 +1,22 @@
1
+ export default [
2
+ {
3
+ name: 'Functional',
4
+ description:
5
+ 'Functional services provide a utility to the website, such as the ability to log in, or to get live support. Disabling any of these scripts will cause that utility to be missing from the site.',
6
+ },
7
+ {
8
+ name: 'Analytics',
9
+ description:
10
+ 'Analytics services keep track of page traffic and user behavior while browsing the site. We use this data internally to improve the usability and performance of the site. Disabling any of these scripts makes it more difficult for us to understand how our site is being used, and slower to improve it.',
11
+ },
12
+ {
13
+ name: 'Email Marketing',
14
+ description:
15
+ 'Email Marketing services track user behavior while browsing the site. We use this data internally in our marketing efforts to provide users contextually relevant information based off of their behaviors. Disabling any of these scripts makes it more difficult for us to provide you contextually relevant information.',
16
+ },
17
+ {
18
+ name: 'Advertising',
19
+ description:
20
+ "Advertising services allow us to keep track of whether our company advertising campaigns have been successful or not. We absolutely never display any third party advertisements on our own websites, or sell any user data to third parties. Disabling any of these scripts makes it more difficult for us to gauge whether our company's advertisements are resonating with current and potential future customers.",
21
+ },
22
+ ]
@@ -0,0 +1,94 @@
1
+ import React from 'react'
2
+ import ConsentManagerComponent, { open, saveAndLoadAnalytics } from '../'
3
+ import defaultCategories from './categories'
4
+ import ossPreset from './presets/oss'
5
+ import enterprisePreset from './presets/enterprise'
6
+ import {
7
+ ConsentManagerCategory,
8
+ ConsentManagerPreferences,
9
+ ConsentManagerProps,
10
+ ConsentManagerService,
11
+ } from '../types'
12
+
13
+ const VERSION = 4
14
+ const COMPANY_NAME = 'HashiCorp'
15
+ const PRIVACY_LINK = 'https://www.hashicorp.com/privacy'
16
+ const COOKIES_LINK = 'https://www.hashicorp.com/cookies'
17
+
18
+ export default function createConsentManager({
19
+ segmentWriteKey = process.env.SEGMENT_WRITE_KEY,
20
+ preset,
21
+ segmentServices,
22
+ otherServices,
23
+ categories,
24
+ forceShow = false,
25
+ onAcceptAll,
26
+ onManagePreferences,
27
+ }: {
28
+ segmentWriteKey?: string
29
+ preset?: 'oss' | 'enterprise'
30
+ segmentServices?: ConsentManagerService[]
31
+ otherServices?: ConsentManagerService[]
32
+ categories?: ConsentManagerCategory[]
33
+ forceShow?: boolean
34
+ onAcceptAll?: () => void
35
+ onManagePreferences?: () => void
36
+ }): {
37
+ ConsentManager: typeof ConsentManagerComponent
38
+ openConsentManager: () => void
39
+ saveAndLoadAnalytics: (preferences: ConsentManagerPreferences) => void
40
+ } {
41
+ // if hashi env is present, check against it. if not, fall back to checking node env
42
+ const isProd = process.env.HASHI_ENV
43
+ ? process.env.HASHI_ENV === 'production'
44
+ : process.env.NODE_ENV === 'production'
45
+
46
+ if (!process.env.HASHI_ENV)
47
+ console.warn(
48
+ 'Consent manager expects the "HASHI_ENV" environment variable to be set in order to ensure proper analytics tracking. Please make sure "HASHI_ENV" is set appropriately within your app.'
49
+ )
50
+
51
+ // set the correct segment key based on environment
52
+ const segmentKey = isProd
53
+ ? segmentWriteKey
54
+ : '0EXTgkNx0Ydje2PGXVbRhpKKoe5wtzcE'
55
+
56
+ // next we build the config objct, kicking it off with the default values
57
+ let config: ConsentManagerProps = {
58
+ version: VERSION,
59
+ companyName: COMPANY_NAME,
60
+ privacyPolicyLink: PRIVACY_LINK,
61
+ cookiePolicyLink: COOKIES_LINK,
62
+ segmentWriteKey: segmentKey,
63
+ categories: defaultCategories,
64
+ forceShow,
65
+ onAcceptAll,
66
+ onManagePreferences,
67
+ }
68
+
69
+ // add preset values if present
70
+ if (preset === 'oss') config = { ...config, ...ossPreset }
71
+ if (preset === 'enterprise') config = { ...config, ...enterprisePreset }
72
+
73
+ // add any other custom values nondestructively if present
74
+ if (segmentServices) {
75
+ if (!config.segmentServices) config.segmentServices = []
76
+ config.segmentServices.push(...segmentServices)
77
+ }
78
+ if (otherServices) {
79
+ if (!config.additionalServices) config.additionalServices = []
80
+ config.additionalServices.push(...otherServices)
81
+ }
82
+ if (categories) config.categories!.push(...categories)
83
+
84
+ // finally, we return a HOC that will render the fully configured consent manager
85
+ return {
86
+ ConsentManager: function ConsentManagerWrapper() {
87
+ return (
88
+ <ConsentManagerComponent {...config} categories={config.categories!} />
89
+ )
90
+ },
91
+ openConsentManager: open,
92
+ saveAndLoadAnalytics,
93
+ }
94
+ }
@@ -0,0 +1,12 @@
1
+ import services from '../services'
2
+
3
+ export default {
4
+ segmentServices: [
5
+ services.googleAnalytics,
6
+ services.googleTagManager,
7
+ services.linkedIn,
8
+ services.heap,
9
+ services.marketo,
10
+ services.googleAds,
11
+ ],
12
+ }
@@ -0,0 +1,10 @@
1
+ import services from '../services'
2
+
3
+ export default {
4
+ segmentServices: [
5
+ services.googleAnalytics,
6
+ services.googleAds,
7
+ services.linkedIn,
8
+ services.marketo,
9
+ ],
10
+ }