@hashicorp/react-components 0.0.0-nightly.4494e70 → 0.0.0-nightly.47d1fb8

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 (170) hide show
  1. package/.eslintrc.js +1 -2
  2. package/.stylelintrc.js +1 -1
  3. package/README.md +1 -1
  4. package/package.json +8 -9
  5. package/postcss.config.js +1 -1
  6. package/src/components/nav-panel/components/flight-icon/index.tsx +51 -0
  7. package/src/components/nav-panel/components/flight-icon/style.module.css +3 -0
  8. package/src/components/nav-panel/components/link/index.tsx +127 -0
  9. package/src/components/nav-panel/components/link/style.module.css +64 -0
  10. package/src/components/nav-panel/components/link-list/index.tsx +13 -64
  11. package/src/components/nav-panel/components/link-list/style.module.css +1 -50
  12. package/src/components/nav-panel/components/panel/column/index.tsx +17 -2
  13. package/src/components/nav-panel/components/panel/column/style.module.css +13 -3
  14. package/src/components/nav-panel/components/panel/root/index.tsx +13 -2
  15. package/src/components/nav-panel/components/panel/root/style.module.css +20 -5
  16. package/src/components/nav-panel/components/promo/index.tsx +45 -18
  17. package/src/components/nav-panel/components/promo/style.module.css +59 -23
  18. package/src/components/nav-panel/components/text/index.tsx +34 -0
  19. package/src/components/nav-panel/product-panel/index.tsx +145 -31
  20. package/src/components/nav-panel/product-panel/style.module.css +321 -26
  21. package/src/components/nav-panel/standard-panel/index.tsx +4 -1
  22. package/src/components/nav-panel/standard-panel/style.module.css +2 -2
  23. package/src/lib/get-localized-link-props/index.test.ts +30 -0
  24. package/src/lib/get-localized-link-props/index.ts +45 -0
  25. package/src/lib/parse-url/index.test.ts +69 -0
  26. package/src/lib/parse-url/index.ts +97 -0
  27. package/src/lib/send-posthog-event/index.ts +22 -0
  28. package/src/lib/supported-locales/index.ts +10 -0
  29. package/src/lib/track-nav-click-event/index.ts +22 -0
  30. package/src/lib/v/index.ts +16 -0
  31. package/src/components/actions/index.tsx +0 -107
  32. package/src/components/actions/style.module.css +0 -28
  33. package/src/components/actions/types.ts +0 -73
  34. package/src/components/call-to-action/index.tsx +0 -205
  35. package/src/components/call-to-action/styles/variant-centered.module.css +0 -93
  36. package/src/components/call-to-action/styles/variant-compact-grid.module.css +0 -88
  37. package/src/components/call-to-action/styles/variant-compact.module.css +0 -91
  38. package/src/components/call-to-action/styles/variant-links.module.css +0 -85
  39. package/src/components/card/README.md +0 -11
  40. package/src/components/card/card.tsx +0 -45
  41. package/src/components/card/index.test.tsx +0 -69
  42. package/src/components/card/index.tsx +0 -14
  43. package/src/components/card/newsroom-card/index.test.tsx +0 -39
  44. package/src/components/card/newsroom-card/index.tsx +0 -37
  45. package/src/components/card/newsroom-card/style.module.css +0 -12
  46. package/src/components/card/partner-card/index.test.tsx +0 -57
  47. package/src/components/card/partner-card/index.tsx +0 -69
  48. package/src/components/card/partner-card/style.module.css +0 -24
  49. package/src/components/card/person-card/index.test.tsx +0 -71
  50. package/src/components/card/person-card/index.tsx +0 -93
  51. package/src/components/card/person-card/style.module.css +0 -33
  52. package/src/components/card/primitives.tsx +0 -176
  53. package/src/components/card/promo-card/index.tsx +0 -51
  54. package/src/components/card/resource-card/index.test.tsx +0 -48
  55. package/src/components/card/resource-card/index.tsx +0 -37
  56. package/src/components/card/style.module.css +0 -145
  57. package/src/components/card/types.ts +0 -66
  58. package/src/components/card/unified-card/index.tsx +0 -64
  59. package/src/components/consent-manager/README.md +0 -73
  60. package/src/components/consent-manager/components/banner/banner.module.css +0 -23
  61. package/src/components/consent-manager/components/banner/banner.test.tsx +0 -31
  62. package/src/components/consent-manager/components/banner/banner.tsx +0 -73
  63. package/src/components/consent-manager/components/dialog/dialog.module.css +0 -145
  64. package/src/components/consent-manager/components/dialog/dialog.test.tsx +0 -194
  65. package/src/components/consent-manager/components/dialog/dialog.tsx +0 -339
  66. package/src/components/consent-manager/img/icn_close.tsx +0 -19
  67. package/src/components/consent-manager/index.test.tsx +0 -334
  68. package/src/components/consent-manager/index.tsx +0 -186
  69. package/src/components/consent-manager/loader/README.md +0 -29
  70. package/src/components/consent-manager/loader/categories.ts +0 -22
  71. package/src/components/consent-manager/loader/index.tsx +0 -94
  72. package/src/components/consent-manager/loader/presets/enterprise.ts +0 -12
  73. package/src/components/consent-manager/loader/presets/oss.ts +0 -10
  74. package/src/components/consent-manager/loader/services.ts +0 -45
  75. package/src/components/consent-manager/scripts/custom.tsx +0 -59
  76. package/src/components/consent-manager/scripts/segment.tsx +0 -87
  77. package/src/components/consent-manager/style.module.css +0 -9
  78. package/src/components/consent-manager/types.ts +0 -55
  79. package/src/components/consent-manager/util/cookies.test.ts +0 -75
  80. package/src/components/consent-manager/util/cookies.ts +0 -70
  81. package/src/components/consent-manager/util/integrations.test.ts +0 -115
  82. package/src/components/consent-manager/util/integrations.ts +0 -110
  83. package/src/components/intro/index.tsx +0 -82
  84. package/src/components/intro/style.module.css +0 -67
  85. package/src/components/intro/types.ts +0 -44
  86. package/src/components/marketo-form/CHANGELOG.md +0 -122
  87. package/src/components/marketo-form/README.md +0 -1
  88. package/src/components/marketo-form/contexts/FormMetadata.ts +0 -11
  89. package/src/components/marketo-form/docs.mdx +0 -197
  90. package/src/components/marketo-form/fixtures/index.ts +0 -185
  91. package/src/components/marketo-form/form/index.tsx +0 -369
  92. package/src/components/marketo-form/index.test.tsx +0 -320
  93. package/src/components/marketo-form/index.ts +0 -11
  94. package/src/components/marketo-form/package.original.json +0 -30
  95. package/src/components/marketo-form/partials/error-message/index.tsx +0 -12
  96. package/src/components/marketo-form/partials/error-message/style.module.css +0 -13
  97. package/src/components/marketo-form/partials/field/index.tsx +0 -90
  98. package/src/components/marketo-form/partials/field-wrapper/index.tsx +0 -26
  99. package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +0 -32
  100. package/src/components/marketo-form/partials/fields/email-field/index.tsx +0 -35
  101. package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +0 -21
  102. package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +0 -37
  103. package/src/components/marketo-form/partials/fields/htmltext-field/index.tsx +0 -21
  104. package/src/components/marketo-form/partials/fields/htmltext-field/style.module.css +0 -18
  105. package/src/components/marketo-form/partials/fields/name-field/index.tsx +0 -19
  106. package/src/components/marketo-form/partials/fields/name-field/style.module.css +0 -13
  107. package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +0 -48
  108. package/src/components/marketo-form/partials/fields/select-field/index.tsx +0 -39
  109. package/src/components/marketo-form/partials/fields/select-field/style.module.css +0 -5
  110. package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +0 -30
  111. package/src/components/marketo-form/partials/fields/text-field/index.tsx +0 -30
  112. package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +0 -29
  113. package/src/components/marketo-form/partials/label/index.tsx +0 -24
  114. package/src/components/marketo-form/partials/label/style.module.css +0 -12
  115. package/src/components/marketo-form/partials/visibility-rule/index.tsx +0 -84
  116. package/src/components/marketo-form/props.js +0 -66
  117. package/src/components/marketo-form/server/api-routes.ts +0 -109
  118. package/src/components/marketo-form/server/client.ts +0 -98
  119. package/src/components/marketo-form/server/index.ts +0 -8
  120. package/src/components/marketo-form/types.ts +0 -268
  121. package/src/components/marketo-form/utils.test.tsx +0 -103
  122. package/src/components/marketo-form/utils.ts +0 -445
  123. package/src/components/next-steps/index.tsx +0 -137
  124. package/src/components/next-steps/style.module.css +0 -270
  125. package/src/components/next-steps/types.ts +0 -63
  126. package/src/components/product-badge/index.test.tsx +0 -11
  127. package/src/components/product-badge/index.tsx +0 -42
  128. package/src/components/product-badge/style.module.css +0 -76
  129. package/src/components/products-used/index.tsx +0 -84
  130. package/src/components/products-used/style.module.css +0 -87
  131. package/src/components/products-used/types.ts +0 -31
  132. package/src/components/related-content/index.test.tsx +0 -74
  133. package/src/components/related-content/index.tsx +0 -56
  134. package/src/components/related-content/style.module.css +0 -89
  135. package/src/components/related-content/types.ts +0 -21
  136. package/src/components/subnav/helpers/areBasePathsMatching.ts +0 -13
  137. package/src/components/subnav/helpers/traverse/index.ts +0 -42
  138. package/src/components/subnav/helpers/useHeightRef.ts +0 -42
  139. package/src/components/subnav/helpers/useNavRef.ts +0 -30
  140. package/src/components/subnav/helpers/useOverflowRef.ts +0 -85
  141. package/src/components/subnav/helpers/useStuckRef.ts +0 -51
  142. package/src/components/subnav/index.tsx +0 -199
  143. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.test.ts +0 -26
  144. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.ts +0 -22
  145. package/src/components/subnav/partials/CtaLinks/github-stars-link/index.tsx +0 -87
  146. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.test.ts +0 -29
  147. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.ts +0 -32
  148. package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +0 -85
  149. package/src/components/subnav/partials/CtaLinks/icons/github-logo.js +0 -20
  150. package/src/components/subnav/partials/CtaLinks/icons/github.svg.js +0 -7
  151. package/src/components/subnav/partials/CtaLinks/icons/star.js +0 -20
  152. package/src/components/subnav/partials/CtaLinks/index.tsx +0 -130
  153. package/src/components/subnav/partials/CtaLinks/style.module.css +0 -45
  154. package/src/components/subnav/partials/DropdownTrigger/index.tsx +0 -35
  155. package/src/components/subnav/partials/DropdownTrigger/style.module.css +0 -36
  156. package/src/components/subnav/partials/MenuItemsDefault/index.tsx +0 -151
  157. package/src/components/subnav/partials/MenuItemsDefault/style.module.css +0 -91
  158. package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +0 -139
  159. package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +0 -82
  160. package/src/components/subnav/partials/TitleLink/index.tsx +0 -113
  161. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +0 -9
  162. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +0 -9
  163. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-dark.ts +0 -23
  164. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-light.ts +0 -23
  165. package/src/components/subnav/partials/TitleLink/style.module.css +0 -43
  166. package/src/components/subnav/partials/nav-item-text/index.tsx +0 -37
  167. package/src/components/subnav/partials/nav-item-text/style.module.css +0 -15
  168. package/src/components/subnav/style.module.css +0 -68
  169. package/src/components/subnav/subnav-consts.ts +0 -1
  170. package/src/components/subnav/theme.module.css +0 -50
@@ -1,31 +1,39 @@
1
1
  import { useCallback } from 'react'
2
- import { trackNavClickEvent } from '../../../../../../../apps/www/layouts/standard/nav'
3
- import { v } from '@web/cms'
4
- import Link from 'next/link'
5
2
  import classNames from 'classnames'
6
- import { parseUrl } from '../../../../../../../apps/www/lib/parseUrl'
7
- import FlightIcon from '@hashicorp/react-design-system-components/src/components/flight-icon'
3
+ import { vercelSplit } from '../../../../lib/v'
4
+ import Link from 'next/link'
5
+ import { getLocalizedLinkProps } from '../../../../lib/get-localized-link-props'
6
+ import { trackNavClickEvent } from '../../../../lib/track-nav-click-event'
7
+ import FlightIcon from '../flight-icon'
8
8
  import * as NavigationMenu from '@radix-ui/react-navigation-menu'
9
9
  import s from './style.module.css'
10
10
 
11
11
  export interface PromoProps {
12
+ locale?: string
12
13
  title: string
14
+ titleLinkUrl?: string
13
15
  description: string
14
16
  linkUrl: string
15
17
  linkTitle: string
16
18
  slug?: string
17
19
  icon?: string
18
20
  theme: string
21
+ hasSidePanel?: boolean
22
+ isPromoOnTop?: boolean
19
23
  }
20
24
 
21
25
  export default function Promo({
26
+ locale,
22
27
  title,
28
+ titleLinkUrl,
23
29
  description,
24
30
  linkUrl,
25
31
  linkTitle,
26
32
  slug,
27
33
  icon,
28
34
  theme,
35
+ hasSidePanel,
36
+ isPromoOnTop = false,
29
37
  }: PromoProps) {
30
38
  const handleClick = useCallback((title, linkUrl, linkTitle, slug) => {
31
39
  if (window && window.analytics) {
@@ -40,32 +48,51 @@ export default function Promo({
40
48
  }, [])
41
49
 
42
50
  return (
43
- <div className={s.promo}>
51
+ <div
52
+ className={classNames(s.promo, {
53
+ [s.hasSide]: hasSidePanel,
54
+ [s.noSide]: !hasSidePanel,
55
+ [s.topPromo]: isPromoOnTop,
56
+ })}
57
+ >
44
58
  {icon && (
45
59
  <div
46
60
  className={classNames(s.icon, {
47
- [s.hashidays]: v(theme) === 'hashidays',
48
- [s.hashiconf]: v(theme) === 'hashiconf',
61
+ [s.hashidays]: vercelSplit(theme) === 'hashidays',
62
+ [s.hashiconf]: vercelSplit(theme) === 'hashiconf',
49
63
  })}
50
64
  >
51
- <FlightIcon name={v(icon)} />
65
+ <FlightIcon name={vercelSplit(icon)} />
52
66
  </div>
53
67
  )}
54
68
  <div className={s.rightContent}>
55
69
  <div>
56
- <div
57
- className={classNames(s.title, {
58
- [s.hashidays]: v(theme) === 'hashidays',
59
- [s.hashiconf]: v(theme) === 'hashiconf',
60
- })}
61
- >
62
- {title}
63
- </div>
70
+ {titleLinkUrl ? (
71
+ <a
72
+ className={classNames(s.title, s.link, {
73
+ [s.hashidays]: vercelSplit(theme) === 'hashidays',
74
+ [s.hashiconf]: vercelSplit(theme) === 'hashiconf',
75
+ })}
76
+ href={titleLinkUrl}
77
+ >
78
+ {title}
79
+ </a>
80
+ ) : (
81
+ <div
82
+ className={classNames(s.title, {
83
+ [s.hashidays]: vercelSplit(theme) === 'hashidays',
84
+ [s.hashiconf]: vercelSplit(theme) === 'hashiconf',
85
+ })}
86
+ >
87
+ {title}
88
+ </div>
89
+ )}
64
90
  <div className={s.description}>{description}</div>
65
91
  </div>
66
92
  <NavigationMenu.Link asChild>
67
93
  <Link
68
- href={parseUrl(linkUrl).href}
94
+ locale={locale ? locale : undefined}
95
+ {...getLocalizedLinkProps(linkUrl, locale)}
69
96
  className={s.link}
70
97
  onClickCapture={() => handleClick(title, linkUrl, linkTitle, slug)}
71
98
  >
@@ -1,61 +1,97 @@
1
+ @custom-media --dev-dot-viewport (min-width: 924px);
2
+
1
3
  .promo {
2
4
  display: flex;
3
- border-radius: var(--hdsplus-spacing-01);
4
- border: 1px solid var(--token-color-border-faint);
5
- background-color: var(--token-color-surface-faint);
6
- padding: var(--hdsplus-spacing-05) var(--hdsplus-spacing-08)
7
- var(--hdsplus-spacing-06) var(--hdsplus-spacing-08);
5
+ border-radius: var(--mds-spacing-01);
6
+ border: 1px solid var(--mds-color-border-faint);
7
+ background-color: var(--mds-color-surface-faint);
8
+ padding: var(--mds-spacing-05) var(--mds-spacing-08) var(--mds-spacing-06)
9
+ var(--mds-spacing-08);
8
10
  flex-direction: row;
9
- gap: var(--hdsplus-spacing-04);
10
- margin: var(--hdsplus-spacing-05);
11
+ gap: var(--mds-spacing-04);
12
+ margin: var(--mds-spacing-07);
13
+ margin-bottom: var(--mds-spacing-09);
11
14
 
12
15
  @media (--large) {
13
- margin: 0;
14
- width: min-content;
15
- min-width: 100%;
16
+ &.topPromo {
17
+ margin-bottom: var(--mds-spacing-05);
18
+ }
19
+ &.noSide {
20
+ margin: 0;
21
+ width: min-content;
22
+ min-width: 100%;
23
+ }
24
+ }
25
+
26
+ @media (--dev-dot-viewport) {
27
+ &.topPromo {
28
+ margin-bottom: var(--mds-spacing-05);
29
+ }
30
+ &.hasSide {
31
+ &.topPromo {
32
+ margin-bottom: var(--mds-spacing-05);
33
+ }
34
+
35
+ margin: 0;
36
+ width: min-content;
37
+ min-width: 100%;
38
+ }
16
39
  }
17
40
  }
18
41
 
42
+ .topPromo {
43
+ margin-bottom: 0;
44
+ }
45
+
19
46
  .rightContent {
20
47
  display: flex;
21
48
  flex-wrap: wrap;
22
- gap: var(--hdsplus-spacing-03);
49
+ gap: var(--mds-spacing-03);
23
50
  width: 100%;
24
51
  justify-content: space-between;
25
52
  }
26
53
 
27
54
  .title {
28
- font-weight: var(--font-weight-semi-bold);
55
+ font-weight: var(--mds-typography-font-weight-semibold);
29
56
  }
30
57
 
31
58
  .description {
32
- font-size: var(--hdsplus-typography-body-200-font-size);
33
- font-weight: var(--token-typography-font-weight-regular);
34
- margin-top: var(--hdsplus-spacing-01);
59
+ font-size: var(--mds-typography-body-200-font-size);
60
+ font-weight: var(--mds-typography-font-weight-regular);
61
+ margin-top: var(--mds-spacing-01);
35
62
  }
36
63
 
37
64
  .icon {
38
65
  display: none;
39
66
 
40
67
  @media (--large) {
41
- display: block;
42
- margin-top: 3px;
68
+ @nest .noSide & {
69
+ display: block;
70
+ margin-top: 3px;
71
+ }
72
+ }
73
+
74
+ @media (--dev-dot-viewport) {
75
+ @nest .hasSide & {
76
+ display: block;
77
+ margin-top: 3px;
78
+ }
43
79
  }
44
80
  }
45
81
 
46
82
  .link {
47
- color: var(--token-color-foreground-strong);
83
+ color: var(--mds-color-foreground-strong);
48
84
  display: flex;
49
85
  flex-direction: row;
50
86
  align-items: center;
51
- gap: var(--hdsplus-spacing-02);
87
+ gap: var(--mds-spacing-02);
52
88
 
53
89
  &:hover {
54
90
  text-decoration: underline;
55
91
  }
56
92
 
57
93
  &:focus {
58
- outline: 2px solid var(--token-color-focus-action-internal);
94
+ outline: 2px solid var(--mds-color-focus-action-internal);
59
95
  outline-style: auto;
60
96
  }
61
97
  }
@@ -79,14 +115,14 @@
79
115
  .hashiconf {
80
116
  background: linear-gradient(
81
117
  to right,
82
- var(--token-color-terraform-foreground),
83
- var(--token-color-vagrant-foreground)
118
+ var(--mds-color-terraform-foreground),
119
+ var(--mds-color-vagrant-foreground)
84
120
  );
85
121
  -webkit-background-clip: text;
86
122
  -webkit-text-fill-color: transparent;
87
123
  max-width: fit-content;
88
124
 
89
125
  & svg {
90
- color: var(--token-color-terraform-foreground);
126
+ color: var(--mds-color-terraform-foreground);
91
127
  }
92
128
  }
@@ -0,0 +1,34 @@
1
+ import classNames from 'classnames'
2
+ import { type ReactNode, type HTMLAttributes } from 'react'
3
+
4
+ type TextSize = '200' | '300' | '400'
5
+ type TextWeight = 'regular' | 'medium' | 'semibold' | 'bold'
6
+
7
+ interface TextProps extends HTMLAttributes<HTMLSpanElement> {
8
+ size?: TextSize
9
+ weight?: TextWeight
10
+ children: ReactNode
11
+ }
12
+
13
+ const Text = ({
14
+ size = '300',
15
+ weight,
16
+ children,
17
+ className,
18
+ ...rest
19
+ }: TextProps) => {
20
+ return (
21
+ <span
22
+ className={classNames(
23
+ `mds-typography-body-${size}`,
24
+ weight && `mds-typography-font-weight-${weight}`,
25
+ className
26
+ )}
27
+ {...rest}
28
+ >
29
+ {children}
30
+ </span>
31
+ )
32
+ }
33
+
34
+ export { Text }
@@ -1,16 +1,19 @@
1
+ import classNames from 'classnames'
1
2
  import Link from 'next/link'
2
3
  import * as NavPanel from '../components/panel'
3
4
  import Promo, { type PromoProps } from '../components/promo'
5
+ import { getLocalizedLinkProps } from '../../../lib/get-localized-link-props'
4
6
  import { Products } from '@hashicorp/platform-product-meta'
5
- import FlightIcon from '@hashicorp/react-design-system-components/src/components/flight-icon'
6
- import { TextPlus } from '@hashicorp/react-design-system-components/src/components/text'
7
- import { parseUrl } from '../../../../../../apps/www/lib/parseUrl'
8
- import { trackNavClickEvent } from '../../../../../../apps/www/layouts/standard/nav'
7
+ import FlightIcon from '../components/flight-icon'
8
+ import { Text } from '../components/text'
9
+ import { trackNavClickEvent } from '../../../lib/track-nav-click-event'
9
10
  import * as NavigationMenu from '@radix-ui/react-navigation-menu'
11
+ import { LinkListProps } from '../components/link-list'
12
+ import NavLink from '../components/link'
10
13
  import s from './style.module.css'
11
14
 
12
15
  const PRODUCT_LOGO_MAP = new Map([
13
- ['Terraform', 'terraform-fill-color'],
16
+ ['Terraform', 'terraform-fill'],
14
17
  ['Packer', 'packer-fill-color'],
15
18
  ['Vault', 'vault-fill-color'],
16
19
  ['Boundary', 'boundary-fill-color'],
@@ -18,52 +21,158 @@ const PRODUCT_LOGO_MAP = new Map([
18
21
  ['Nomad', 'nomad-fill-color'],
19
22
  ['Waypoint', 'waypoint-fill-color'],
20
23
  ['Vagrant', 'vagrant-fill-color'],
24
+ ['HCP Vault Secrets', 'vault-secrets'],
25
+ ['HCP Vault Radar', 'vault-radar'],
21
26
  ])
22
27
 
23
- interface ProductsPanelProps {
24
- productCategories: any
28
+ const PRODUCT_LOGO_EXCEPTION_CLASSNAMES = {
29
+ Terraform: 'terraform',
30
+ 'HCP Vault Secrets': 'hcpVaultSecrets',
31
+ 'HCP Vault Radar': 'hcpVaultRadar',
32
+ }
33
+
34
+ export type ProductCategoriesProps = Array<{
35
+ title: string
36
+ group?: LinkListProps['links'][0]
37
+ products: NavProductProps[]
38
+ }>
39
+
40
+ export interface ProductsPanelProps {
41
+ locale?: string
42
+ productCategories: ProductCategoriesProps
25
43
  promo?: PromoProps
44
+ sidePanel?: {
45
+ label: string
46
+ navItems: {
47
+ icon: string
48
+ title: string
49
+ description: string
50
+ url: string
51
+ }[]
52
+ }
53
+ isPromoOnTop?: boolean
26
54
  }
27
55
 
28
- const ProductPanel = ({ productCategories, promo }: ProductsPanelProps) => {
56
+ const ProductPanel = ({
57
+ locale,
58
+ productCategories,
59
+ promo,
60
+ sidePanel,
61
+ isPromoOnTop = false,
62
+ }: ProductsPanelProps) => {
29
63
  return (
30
- <NavPanel.Root>
31
- <NavPanel.Column>
32
- <ul className={s.productCategories}>
33
- {productCategories.map(({ title, products }) => {
34
- return (
35
- <li key={title} className={s.productCategory}>
36
- <TextPlus.Body className={s.eyebrow}>{title}</TextPlus.Body>
37
- <ul className={s.productList}>
38
- {products.map((product) => {
39
- return (
40
- <li key={product.url}>
41
- <NavProduct {...product} />
42
- </li>
43
- )
64
+ <NavPanel.Root
65
+ className={classNames(s.productPanel, {
66
+ [s.hasSide]: sidePanel,
67
+ [s.noSide]: !sidePanel,
68
+ [s.topPromo]: isPromoOnTop,
69
+ })}
70
+ hasSidePanel={Boolean(sidePanel)}
71
+ >
72
+ <div className={s.mainPanel}>
73
+ {promo && isPromoOnTop ? (
74
+ <Promo
75
+ {...promo}
76
+ hasSidePanel={Boolean(sidePanel)}
77
+ isPromoOnTop={isPromoOnTop}
78
+ />
79
+ ) : null}
80
+ <NavPanel.Column hasSidePanel={Boolean(sidePanel)}>
81
+ <ul className={s.productCategories}>
82
+ {productCategories.map(({ group, title, products }) => {
83
+ return (
84
+ <li
85
+ key={title}
86
+ className={classNames(s.productCategory, {
87
+ [s.productCategoryHasGroup]: group,
44
88
  })}
45
- </ul>
46
- </li>
47
- )
48
- })}
49
- </ul>
50
- </NavPanel.Column>
51
- {promo ? <Promo {...promo} /> : null}
89
+ >
90
+ {group ? (
91
+ <NavLink {...group} className={s.productGroupLink} />
92
+ ) : (
93
+ <Text className={s.eyebrow}>{title}</Text>
94
+ )}
95
+ <ul className={s.productList}>
96
+ {products.map((product) => {
97
+ return (
98
+ <li key={product.url}>
99
+ <NavProduct locale={locale} {...product} />
100
+ </li>
101
+ )
102
+ })}
103
+ </ul>
104
+ </li>
105
+ )
106
+ })}
107
+ </ul>
108
+ </NavPanel.Column>
109
+ {promo && !isPromoOnTop ? (
110
+ <Promo {...promo} hasSidePanel={Boolean(sidePanel)} />
111
+ ) : null}
112
+ </div>
113
+
114
+ {sidePanel ? (
115
+ <NavPanel.Column className={s.sidePanel}>
116
+ <Text size="200" weight="semibold" className={s.sidePanelText}>
117
+ {sidePanel.label}
118
+ </Text>
119
+
120
+ {/* ! TODO Replace the below list with the <LinkList /> component,
121
+ That component will require a refactor to support greater customization
122
+ Ticket:
123
+ https://app.asana.com/0/1206176289707208/1208162145034615/f
124
+ */}
125
+ <ul className={s.sidePanelItems}>
126
+ {sidePanel.navItems.map(({ icon, title, description, url }) => {
127
+ return (
128
+ <li key={title}>
129
+ <Link
130
+ aria-label={`${title} - ${description}`}
131
+ {...getLocalizedLinkProps(url, locale)}
132
+ locale={locale ? locale : undefined}
133
+ className={classNames(s.sidePanelItem, s.focusIndicator)}
134
+ >
135
+ <div className={s.iconBackground}>
136
+ <FlightIcon
137
+ name={icon}
138
+ color="var(--mds-color-foreground-faint)"
139
+ />
140
+ </div>
141
+ <div className={s.sidePanelItemContent}>
142
+ <Text
143
+ size="200"
144
+ weight="semibold"
145
+ className={s.sidePanelText}
146
+ >
147
+ {title}
148
+ </Text>
149
+ <span className={s.sidePanelItemDesc}>{description}</span>
150
+ </div>
151
+ </Link>
152
+ </li>
153
+ )
154
+ })}
155
+ </ul>
156
+ </NavPanel.Column>
157
+ ) : null}
52
158
  </NavPanel.Root>
53
159
  )
54
160
  }
55
161
 
56
162
  export interface NavProductProps {
163
+ locale?: string
57
164
  url: string
58
165
  product: Products | string
59
166
  description: string
60
167
  }
61
168
 
62
- function NavProduct({ url, product, description }: NavProductProps) {
169
+ function NavProduct({ locale, url, product, description }: NavProductProps) {
63
170
  return (
64
171
  <NavigationMenu.Link asChild>
65
172
  <Link
66
- href={parseUrl(url).href}
173
+ aria-label={`${product} - ${description}`}
174
+ {...getLocalizedLinkProps(url, locale)}
175
+ locale={locale ? locale : undefined}
67
176
  onClickCapture={() => {
68
177
  trackNavClickEvent(product, url, 'products')
69
178
  }}
@@ -73,6 +182,11 @@ function NavProduct({ url, product, description }: NavProductProps) {
73
182
  <div className={s.productLogo}>
74
183
  <FlightIcon
75
184
  name={PRODUCT_LOGO_MAP.get(product) ?? 'hashicorp-fill-color'}
185
+ className={
186
+ PRODUCT_LOGO_EXCEPTION_CLASSNAMES[product]
187
+ ? s[PRODUCT_LOGO_EXCEPTION_CLASSNAMES[product]]
188
+ : undefined
189
+ }
76
190
  />
77
191
  </div>
78
192
  <div className={s.productTextContent}>