@hashicorp/react-components 0.0.0-nightly.ad81ac2 → 0.0.0-nightly.b154bf4

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 (142) hide show
  1. package/.eslintrc.js +1 -2
  2. package/.stylelintrc.js +1 -1
  3. package/README.md +1 -1
  4. package/package.json +3 -8
  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 -65
  11. package/src/components/nav-panel/components/link-list/style.module.css +1 -50
  12. package/src/components/nav-panel/components/panel/column/style.module.css +2 -2
  13. package/src/components/nav-panel/components/panel/root/style.module.css +5 -5
  14. package/src/components/nav-panel/components/promo/index.tsx +31 -11
  15. package/src/components/nav-panel/components/promo/style.module.css +26 -12
  16. package/src/components/nav-panel/components/text/index.tsx +34 -0
  17. package/src/components/nav-panel/product-panel/index.tsx +54 -17
  18. package/src/components/nav-panel/product-panel/style.module.css +116 -36
  19. package/src/components/nav-panel/standard-panel/index.tsx +3 -0
  20. package/src/components/nav-panel/standard-panel/style.module.css +2 -2
  21. package/src/lib/get-localized-link-props/index.test.ts +30 -0
  22. package/src/lib/get-localized-link-props/index.ts +45 -0
  23. package/src/lib/parse-url/index.ts +0 -2
  24. package/src/lib/send-posthog-event/index.ts +22 -0
  25. package/src/lib/supported-locales/index.ts +10 -0
  26. package/src/lib/track-nav-click-event/index.ts +4 -4
  27. package/src/components/actions/index.tsx +0 -107
  28. package/src/components/actions/style.module.css +0 -28
  29. package/src/components/actions/types.ts +0 -73
  30. package/src/components/call-to-action/index.tsx +0 -205
  31. package/src/components/call-to-action/styles/variant-centered.module.css +0 -93
  32. package/src/components/call-to-action/styles/variant-compact-grid.module.css +0 -88
  33. package/src/components/call-to-action/styles/variant-compact.module.css +0 -91
  34. package/src/components/call-to-action/styles/variant-links.module.css +0 -85
  35. package/src/components/card/README.md +0 -11
  36. package/src/components/card/card.tsx +0 -45
  37. package/src/components/card/index.test.tsx +0 -69
  38. package/src/components/card/index.tsx +0 -14
  39. package/src/components/card/newsroom-card/index.test.tsx +0 -39
  40. package/src/components/card/newsroom-card/index.tsx +0 -37
  41. package/src/components/card/newsroom-card/style.module.css +0 -12
  42. package/src/components/card/partner-card/index.test.tsx +0 -57
  43. package/src/components/card/partner-card/index.tsx +0 -69
  44. package/src/components/card/partner-card/style.module.css +0 -24
  45. package/src/components/card/person-card/index.test.tsx +0 -71
  46. package/src/components/card/person-card/index.tsx +0 -93
  47. package/src/components/card/person-card/style.module.css +0 -33
  48. package/src/components/card/primitives.tsx +0 -177
  49. package/src/components/card/promo-card/index.tsx +0 -51
  50. package/src/components/card/resource-card/index.test.tsx +0 -48
  51. package/src/components/card/resource-card/index.tsx +0 -40
  52. package/src/components/card/style.module.css +0 -145
  53. package/src/components/card/types.ts +0 -66
  54. package/src/components/card/unified-card/index.spec.tsx +0 -40
  55. package/src/components/card/unified-card/index.tsx +0 -58
  56. package/src/components/intro/index.tsx +0 -82
  57. package/src/components/intro/style.module.css +0 -67
  58. package/src/components/intro/types.ts +0 -44
  59. package/src/components/marketo-form/CHANGELOG.md +0 -122
  60. package/src/components/marketo-form/README.md +0 -1
  61. package/src/components/marketo-form/contexts/FormMetadata.ts +0 -13
  62. package/src/components/marketo-form/docs.mdx +0 -197
  63. package/src/components/marketo-form/fixtures/index.ts +0 -185
  64. package/src/components/marketo-form/form/index.tsx +0 -371
  65. package/src/components/marketo-form/index.test.tsx +0 -320
  66. package/src/components/marketo-form/index.ts +0 -11
  67. package/src/components/marketo-form/package.original.json +0 -30
  68. package/src/components/marketo-form/partials/error-message/index.tsx +0 -12
  69. package/src/components/marketo-form/partials/error-message/style.module.css +0 -13
  70. package/src/components/marketo-form/partials/field/index.tsx +0 -90
  71. package/src/components/marketo-form/partials/field-wrapper/index.tsx +0 -26
  72. package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +0 -32
  73. package/src/components/marketo-form/partials/fields/email-field/index.tsx +0 -35
  74. package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +0 -23
  75. package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +0 -38
  76. package/src/components/marketo-form/partials/fields/htmltext-field/index.tsx +0 -21
  77. package/src/components/marketo-form/partials/fields/htmltext-field/style.module.css +0 -18
  78. package/src/components/marketo-form/partials/fields/name-field/index.tsx +0 -19
  79. package/src/components/marketo-form/partials/fields/name-field/style.module.css +0 -13
  80. package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +0 -48
  81. package/src/components/marketo-form/partials/fields/select-field/index.tsx +0 -39
  82. package/src/components/marketo-form/partials/fields/select-field/style.module.css +0 -5
  83. package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +0 -30
  84. package/src/components/marketo-form/partials/fields/text-field/index.tsx +0 -30
  85. package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +0 -29
  86. package/src/components/marketo-form/partials/label/index.tsx +0 -24
  87. package/src/components/marketo-form/partials/label/style.module.css +0 -12
  88. package/src/components/marketo-form/partials/visibility-rule/index.tsx +0 -84
  89. package/src/components/marketo-form/props.js +0 -66
  90. package/src/components/marketo-form/server/api-routes.ts +0 -109
  91. package/src/components/marketo-form/server/client.ts +0 -98
  92. package/src/components/marketo-form/server/index.ts +0 -8
  93. package/src/components/marketo-form/types.ts +0 -267
  94. package/src/components/marketo-form/utils.test.tsx +0 -103
  95. package/src/components/marketo-form/utils.ts +0 -449
  96. package/src/components/next-steps/index.tsx +0 -138
  97. package/src/components/next-steps/style.module.css +0 -270
  98. package/src/components/next-steps/types.ts +0 -63
  99. package/src/components/product-badge/index.test.tsx +0 -11
  100. package/src/components/product-badge/index.tsx +0 -42
  101. package/src/components/product-badge/style.module.css +0 -76
  102. package/src/components/products-used/index.tsx +0 -84
  103. package/src/components/products-used/style.module.css +0 -87
  104. package/src/components/products-used/types.ts +0 -31
  105. package/src/components/related-content/index.test.tsx +0 -74
  106. package/src/components/related-content/index.tsx +0 -56
  107. package/src/components/related-content/style.module.css +0 -89
  108. package/src/components/related-content/types.ts +0 -21
  109. package/src/components/subnav/helpers/areBasePathsMatching.ts +0 -13
  110. package/src/components/subnav/helpers/traverse/index.ts +0 -42
  111. package/src/components/subnav/helpers/useHeightRef.ts +0 -42
  112. package/src/components/subnav/helpers/useNavRef.ts +0 -30
  113. package/src/components/subnav/helpers/useOverflowRef.ts +0 -85
  114. package/src/components/subnav/helpers/useStuckRef.ts +0 -51
  115. package/src/components/subnav/index.tsx +0 -204
  116. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.test.ts +0 -26
  117. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.ts +0 -22
  118. package/src/components/subnav/partials/CtaLinks/github-stars-link/index.tsx +0 -87
  119. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.test.ts +0 -29
  120. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.ts +0 -32
  121. package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +0 -81
  122. package/src/components/subnav/partials/CtaLinks/icons/github-logo.js +0 -20
  123. package/src/components/subnav/partials/CtaLinks/icons/github.svg.js +0 -7
  124. package/src/components/subnav/partials/CtaLinks/icons/star.js +0 -20
  125. package/src/components/subnav/partials/CtaLinks/index.tsx +0 -131
  126. package/src/components/subnav/partials/CtaLinks/style.module.css +0 -45
  127. package/src/components/subnav/partials/DropdownTrigger/index.tsx +0 -35
  128. package/src/components/subnav/partials/DropdownTrigger/style.module.css +0 -39
  129. package/src/components/subnav/partials/MenuItemsDefault/index.tsx +0 -158
  130. package/src/components/subnav/partials/MenuItemsDefault/style.module.css +0 -104
  131. package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +0 -143
  132. package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +0 -88
  133. package/src/components/subnav/partials/TitleLink/index.tsx +0 -113
  134. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +0 -10
  135. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +0 -10
  136. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-dark.ts +0 -23
  137. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-light.ts +0 -23
  138. package/src/components/subnav/partials/TitleLink/style.module.css +0 -43
  139. package/src/components/subnav/partials/nav-item-text/index.tsx +0 -37
  140. package/src/components/subnav/partials/nav-item-text/style.module.css +0 -13
  141. package/src/components/subnav/style.module.css +0 -66
  142. package/src/components/subnav/subnav-consts.ts +0 -1
@@ -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 }
@@ -2,12 +2,14 @@ import classNames from 'classnames'
2
2
  import Link from 'next/link'
3
3
  import * as NavPanel from '../components/panel'
4
4
  import Promo, { type PromoProps } from '../components/promo'
5
+ import { getLocalizedLinkProps } from '../../../lib/get-localized-link-props'
5
6
  import { Products } from '@hashicorp/platform-product-meta'
6
- import FlightIcon from '@hashicorp/react-hds/src/components/flight-icon'
7
- import { TextPlus } from '@hashicorp/react-hds/src/components/text'
8
- import { parseUrl } from '../../../lib/parse-url'
7
+ import FlightIcon from '../components/flight-icon'
8
+ import { Text } from '../components/text'
9
9
  import { trackNavClickEvent } from '../../../lib/track-nav-click-event'
10
10
  import * as NavigationMenu from '@radix-ui/react-navigation-menu'
11
+ import { LinkListProps } from '../components/link-list'
12
+ import NavLink from '../components/link'
11
13
  import s from './style.module.css'
12
14
 
13
15
  const PRODUCT_LOGO_MAP = new Map([
@@ -29,8 +31,15 @@ const PRODUCT_LOGO_EXCEPTION_CLASSNAMES = {
29
31
  'HCP Vault Radar': 'hcpVaultRadar',
30
32
  }
31
33
 
34
+ export type ProductCategoriesProps = Array<{
35
+ title: string
36
+ group?: LinkListProps['links'][0]
37
+ products: NavProductProps[]
38
+ }>
39
+
32
40
  export interface ProductsPanelProps {
33
- productCategories: any
41
+ locale?: string
42
+ productCategories: ProductCategoriesProps
34
43
  promo?: PromoProps
35
44
  sidePanel?: {
36
45
  label: string
@@ -41,33 +50,53 @@ export interface ProductsPanelProps {
41
50
  url: string
42
51
  }[]
43
52
  }
53
+ isPromoOnTop?: boolean
44
54
  }
45
55
 
46
56
  const ProductPanel = ({
57
+ locale,
47
58
  productCategories,
48
59
  promo,
49
60
  sidePanel,
61
+ isPromoOnTop = false,
50
62
  }: ProductsPanelProps) => {
51
63
  return (
52
64
  <NavPanel.Root
53
65
  className={classNames(s.productPanel, {
54
66
  [s.hasSide]: sidePanel,
55
67
  [s.noSide]: !sidePanel,
68
+ [s.topPromo]: isPromoOnTop,
56
69
  })}
57
70
  hasSidePanel={Boolean(sidePanel)}
58
71
  >
59
72
  <div className={s.mainPanel}>
73
+ {promo && isPromoOnTop ? (
74
+ <Promo
75
+ {...promo}
76
+ hasSidePanel={Boolean(sidePanel)}
77
+ isPromoOnTop={isPromoOnTop}
78
+ />
79
+ ) : null}
60
80
  <NavPanel.Column hasSidePanel={Boolean(sidePanel)}>
61
81
  <ul className={s.productCategories}>
62
- {productCategories.map(({ title, products }) => {
82
+ {productCategories.map(({ group, title, products }) => {
63
83
  return (
64
- <li key={title} className={s.productCategory}>
65
- <TextPlus.Body className={s.eyebrow}>{title}</TextPlus.Body>
84
+ <li
85
+ key={title}
86
+ className={classNames(s.productCategory, {
87
+ [s.productCategoryHasGroup]: group,
88
+ })}
89
+ >
90
+ {group ? (
91
+ <NavLink {...group} className={s.productGroupLink} />
92
+ ) : (
93
+ <Text className={s.eyebrow}>{title}</Text>
94
+ )}
66
95
  <ul className={s.productList}>
67
96
  {products.map((product) => {
68
97
  return (
69
98
  <li key={product.url}>
70
- <NavProduct {...product} />
99
+ <NavProduct locale={locale} {...product} />
71
100
  </li>
72
101
  )
73
102
  })}
@@ -77,14 +106,16 @@ const ProductPanel = ({
77
106
  })}
78
107
  </ul>
79
108
  </NavPanel.Column>
80
- {promo ? <Promo {...promo} hasSidePanel={Boolean(sidePanel)} /> : null}
109
+ {promo && !isPromoOnTop ? (
110
+ <Promo {...promo} hasSidePanel={Boolean(sidePanel)} />
111
+ ) : null}
81
112
  </div>
82
113
 
83
114
  {sidePanel ? (
84
115
  <NavPanel.Column className={s.sidePanel}>
85
- <TextPlus.Body size="200" weight="semibold">
116
+ <Text size="200" weight="semibold" className={s.sidePanelText}>
86
117
  {sidePanel.label}
87
- </TextPlus.Body>
118
+ </Text>
88
119
 
89
120
  {/* ! TODO Replace the below list with the <LinkList /> component,
90
121
  That component will require a refactor to support greater customization
@@ -97,20 +128,24 @@ const ProductPanel = ({
97
128
  <li key={title}>
98
129
  <Link
99
130
  aria-label={`${title} - ${description}`}
100
- href={parseUrl(url).href}
131
+ {...getLocalizedLinkProps(url, locale)}
132
+ locale={locale ? locale : undefined}
101
133
  className={classNames(s.sidePanelItem, s.focusIndicator)}
102
134
  >
103
135
  <div className={s.iconBackground}>
104
136
  <FlightIcon
105
- size={16}
106
137
  name={icon}
107
138
  color="var(--token-color-foreground-faint)"
108
139
  />
109
140
  </div>
110
141
  <div className={s.sidePanelItemContent}>
111
- <TextPlus.Body size="200" weight="semibold" tag="span">
142
+ <Text
143
+ size="200"
144
+ weight="semibold"
145
+ className={s.sidePanelText}
146
+ >
112
147
  {title}
113
- </TextPlus.Body>
148
+ </Text>
114
149
  <span className={s.sidePanelItemDesc}>{description}</span>
115
150
  </div>
116
151
  </Link>
@@ -125,17 +160,19 @@ const ProductPanel = ({
125
160
  }
126
161
 
127
162
  export interface NavProductProps {
163
+ locale?: string
128
164
  url: string
129
165
  product: Products | string
130
166
  description: string
131
167
  }
132
168
 
133
- function NavProduct({ url, product, description }: NavProductProps) {
169
+ function NavProduct({ locale, url, product, description }: NavProductProps) {
134
170
  return (
135
171
  <NavigationMenu.Link asChild>
136
172
  <Link
137
173
  aria-label={`${product} - ${description}`}
138
- href={parseUrl(url).href}
174
+ {...getLocalizedLinkProps(url, locale)}
175
+ locale={locale ? locale : undefined}
139
176
  onClickCapture={() => {
140
177
  trackNavClickEvent(product, url, 'products')
141
178
  }}
@@ -3,6 +3,29 @@
3
3
  .productPanel {
4
4
  height: 100%;
5
5
 
6
+ /* Temporarily included for devdot compatability
7
+ https://app.asana.com/1/90955849329269/project/1209320521286316/task/1210514680913728?focus=true */
8
+ --mds-spacing-01: 0.25rem;
9
+ --mds-spacing-02: 0.375rem;
10
+ --mds-spacing-03: 0.5rem;
11
+ --mds-spacing-04: 0.75rem;
12
+ --mds-spacing-05: 1rem;
13
+ --mds-spacing-06: 1.25rem;
14
+ --mds-spacing-07: 1.5rem;
15
+ --mds-spacing-08: 2rem;
16
+ --mds-spacing-09: 2.5rem;
17
+ --mds-spacing-10: 3rem;
18
+ --mds-spacing-11: 3.5rem;
19
+ --mds-spacing-12: 4rem;
20
+ --mds-spacing-13: 4.5rem;
21
+ --mds-spacing-14: 5.5rem;
22
+ --mds-spacing-15: 6rem;
23
+ --mds-spacing-16: 8rem;
24
+ --mds-spacing-17: 8.5rem;
25
+ --mds-typography-body-200-font-size: 0.875rem;
26
+ --mds-typography-font-weight-regular: 400;
27
+ --mds-typography-font-weight-semibold: 600;
28
+
6
29
  @media (--large) {
7
30
  &.noSide {
8
31
  display: grid;
@@ -26,7 +49,11 @@
26
49
  list-style: none;
27
50
  padding: 0;
28
51
  display: grid;
29
- margin: var(--hdsplus-spacing-07) 0 0;
52
+ margin: var(--mds-spacing-07) 0 0;
53
+
54
+ @nest .topPromo & {
55
+ margin-bottom: var(--mds-spacing-07);
56
+ }
30
57
 
31
58
  @media (--large) {
32
59
  @nest .noSide & {
@@ -48,27 +75,27 @@
48
75
 
49
76
  &:first-child {
50
77
  border-bottom: 1px solid var(--token-color-border-primary);
51
- margin-bottom: var(--hdsplus-spacing-05);
52
- padding-bottom: var(--hdsplus-spacing-05);
78
+ margin-bottom: var(--mds-spacing-05);
79
+ padding-bottom: var(--mds-spacing-05);
53
80
  }
54
81
  }
55
82
 
56
83
  .eyebrow {
57
- padding-bottom: var(--hdsplus-spacing-04);
84
+ padding-bottom: var(--mds-spacing-04);
58
85
  color: var(--token-color-foreground-strong);
59
- font-weight: var(--font-weight-semi-bold);
86
+ font-weight: var(--mds-typography-font-weight-semibold);
60
87
 
61
88
  @media (--large) {
62
89
  @nest .noSide & {
63
90
  padding-bottom: 0;
64
- padding-left: var(--hdsplus-spacing-06);
91
+ padding-left: var(--mds-spacing-06);
65
92
  }
66
93
  }
67
94
 
68
95
  @media (--dev-dot-viewport) {
69
96
  @nest .hasSide & {
70
97
  padding-bottom: 0;
71
- padding-left: var(--hdsplus-spacing-06);
98
+ padding-left: var(--mds-spacing-06);
72
99
  }
73
100
  }
74
101
  }
@@ -82,8 +109,7 @@
82
109
 
83
110
  @media (--large) {
84
111
  @nest .noSide & {
85
- padding: var(--hdsplus-spacing-06) var(--hdsplus-spacing-05)
86
- var(--hdsplus-spacing-04);
112
+ padding: var(--mds-spacing-06) var(--mds-spacing-05) var(--mds-spacing-04);
87
113
  grid-auto-flow: row;
88
114
  grid-template-columns: repeat(2, 300px);
89
115
  grid-template-rows: repeat(2, max-content);
@@ -93,8 +119,7 @@
93
119
 
94
120
  @media (--dev-dot-viewport) {
95
121
  @nest .hasSide & {
96
- padding: var(--hdsplus-spacing-06) var(--hdsplus-spacing-05)
97
- var(--hdsplus-spacing-04);
122
+ padding: var(--mds-spacing-06) var(--mds-spacing-05) var(--mds-spacing-04);
98
123
  grid-auto-flow: row;
99
124
  grid-template-columns: repeat(2, 300px);
100
125
  grid-template-rows: repeat(2, max-content);
@@ -113,29 +138,29 @@
113
138
 
114
139
  .productWrapper {
115
140
  display: flex;
116
- margin-bottom: var(--hdsplus-spacing-05);
117
- gap: var(--hdsplus-spacing-05);
141
+ margin-bottom: var(--mds-spacing-05);
142
+ gap: var(--mds-spacing-05);
118
143
 
119
144
  @media (--large) {
120
145
  @nest .noSide & {
121
- padding: var(--hdsplus-spacing-03) var(--hdsplus-spacing-05);
146
+ padding: var(--mds-spacing-03) var(--mds-spacing-05);
122
147
  margin-bottom: 0;
123
148
 
124
149
  &:hover {
125
150
  background-color: var(--token-color-surface-interactive-hover);
126
- border-radius: var(--hdsplus-spacing-01);
151
+ border-radius: var(--mds-spacing-01);
127
152
  }
128
153
  }
129
154
  }
130
155
 
131
156
  @media (--dev-dot-viewport) {
132
157
  @nest .hasSide & {
133
- padding: var(--hdsplus-spacing-03) var(--hdsplus-spacing-05);
158
+ padding: var(--mds-spacing-03) var(--mds-spacing-05);
134
159
  margin-bottom: 0;
135
160
 
136
161
  &:hover {
137
162
  background-color: var(--token-color-surface-interactive-hover);
138
- border-radius: var(--hdsplus-spacing-01);
163
+ border-radius: var(--mds-spacing-01);
139
164
  }
140
165
  }
141
166
  }
@@ -152,8 +177,8 @@
152
177
  @nest .noSide & {
153
178
  & svg {
154
179
  @media (--large) {
155
- height: var(--hdsplus-spacing-08);
156
- width: var(--hdsplus-spacing-08);
180
+ height: var(--mds-spacing-08);
181
+ width: var(--mds-spacing-08);
157
182
  }
158
183
  }
159
184
  }
@@ -161,8 +186,8 @@
161
186
  @nest .hasSide & {
162
187
  & svg {
163
188
  @media (--dev-dot-viewport) {
164
- height: var(--hdsplus-spacing-08);
165
- width: var(--hdsplus-spacing-08);
189
+ height: var(--mds-spacing-08);
190
+ width: var(--mds-spacing-08);
166
191
  }
167
192
  }
168
193
  }
@@ -195,17 +220,29 @@
195
220
  justify-content: space-between;
196
221
  flex-direction: column;
197
222
 
223
+ @nest .topPromo & {
224
+ justify-content: flex-start;
225
+ }
226
+
198
227
  @media (--large) {
199
228
  @nest .noSide & {
200
- padding: var(--hdsplus-spacing-07) 0 var(--hdsplus-spacing-09)
201
- var(--hdsplus-spacing-04);
229
+ padding: var(--mds-spacing-07) 0 var(--mds-spacing-09)
230
+ var(--mds-spacing-04);
231
+ }
232
+
233
+ @nest .topPromo & {
234
+ padding-bottom: var(--mds-spacing-04);
202
235
  }
203
236
  }
204
237
 
205
238
  @media (--dev-dot-viewport) {
206
239
  @nest .hasSide & {
207
- padding: var(--hdsplus-spacing-07) 0 var(--hdsplus-spacing-09)
208
- var(--hdsplus-spacing-04);
240
+ padding: var(--mds-spacing-07) 0 var(--mds-spacing-09)
241
+ var(--mds-spacing-04);
242
+ }
243
+
244
+ @nest .topPromo & {
245
+ padding-bottom: var(--mds-spacing-04);
209
246
  }
210
247
  }
211
248
  }
@@ -215,10 +252,10 @@
215
252
  background: var(--token-color-surface-faint);
216
253
  display: flex;
217
254
  flex-direction: column;
218
- gap: var(--hdsplus-spacing-05);
255
+ gap: var(--mds-spacing-05);
219
256
  margin: 0;
220
- padding: var(--hdsplus-spacing-07) var(--hdsplus-spacing-04)
221
- var(--hdsplus-spacing-09) var(--hdsplus-spacing-07);
257
+ padding: var(--mds-spacing-07) var(--mds-spacing-04) var(--mds-spacing-09)
258
+ var(--mds-spacing-07);
222
259
  }
223
260
 
224
261
  .sidePanelItems {
@@ -227,24 +264,24 @@
227
264
  padding: 0;
228
265
  display: grid;
229
266
  grid-template-columns: 1fr;
230
- gap: var(--hdsplus-spacing-07);
267
+ gap: var(--mds-spacing-07);
231
268
 
232
269
  @media (--dev-dot-viewport) {
233
- gap: var(--hdsplus-spacing-05);
270
+ gap: var(--mds-spacing-05);
234
271
  }
235
272
  }
236
273
 
237
274
  /* Lifted from .productWrapper */
238
275
  .sidePanelItem {
239
276
  display: flex;
240
- gap: var(--hdsplus-spacing-05);
277
+ gap: var(--mds-spacing-05);
241
278
 
242
279
  @media (--dev-dot-viewport) {
243
- padding: var(--hdsplus-spacing-03) var(--hdsplus-spacing-05);
280
+ padding: var(--mds-spacing-03) var(--mds-spacing-05);
244
281
 
245
282
  &:hover {
246
283
  background-color: var(--token-color-surface-interactive-hover);
247
- border-radius: var(--hdsplus-spacing-01);
284
+ border-radius: var(--mds-spacing-01);
248
285
  }
249
286
  }
250
287
  }
@@ -253,8 +290,8 @@
253
290
  packages/react-components/src/components/nav-panel/components/link-list/style.module.css */
254
291
  .iconBackground {
255
292
  background: var(--token-color-foreground-high-contrast);
256
- height: var(--hdsplus-spacing-08);
257
- width: var(--hdsplus-spacing-08);
293
+ height: var(--mds-spacing-08);
294
+ width: var(--mds-spacing-08);
258
295
  display: flex;
259
296
  align-items: center;
260
297
  justify-content: center;
@@ -301,7 +338,7 @@ packages/react-components/src/components/nav-panel/components/link-list/style.mo
301
338
  */
302
339
  .hcpVaultSecrets,
303
340
  .hcpVaultRadar {
304
- padding: var(--hdsplus-spacing-01);
341
+ padding: var(--mds-spacing-01);
305
342
  border: 2px solid var(--token-color-vault-brand);
306
343
  border-radius: 3px;
307
344
 
@@ -313,3 +350,46 @@ packages/react-components/src/components/nav-panel/components/link-list/style.mo
313
350
  fill: inherit;
314
351
  }
315
352
  }
353
+
354
+ .sidePanelText {
355
+ font-weight: var(--mds-typography-font-weight-semibold);
356
+ }
357
+
358
+ .productCategoryHasGroup {
359
+ & .productList {
360
+ padding-left: 0;
361
+ padding-right: 0;
362
+ padding-top: 0;
363
+ }
364
+
365
+ & .productWrapper {
366
+ gap: var(--mds-spacing-04);
367
+
368
+ @media (--small) {
369
+ padding: var(--mds-spacing-03) var(--mds-spacing-05);
370
+ }
371
+ }
372
+
373
+ & .productLogo {
374
+ margin-top: 3px;
375
+ height: 32px;
376
+ width: 32px;
377
+ min-width: 32px;
378
+
379
+ & svg {
380
+ width: 100%;
381
+ height: 100%;
382
+ }
383
+ }
384
+
385
+ & .terraform {
386
+ width: 100%;
387
+ height: 100%;
388
+ }
389
+ }
390
+
391
+ .productGroupLink {
392
+ min-width: 100%;
393
+ max-width: 100%;
394
+ margin-bottom: var(--mds-spacing-03);
395
+ }
@@ -12,12 +12,14 @@ interface StandardPanelProps {
12
12
  navData: NavItem[]
13
13
  promo?: PromoProps
14
14
  sectionName?: string
15
+ locale?: any
15
16
  }
16
17
 
17
18
  const StandardPanel = ({
18
19
  navData,
19
20
  promo,
20
21
  sectionName = '',
22
+ locale,
21
23
  }: StandardPanelProps) => {
22
24
  return (
23
25
  <NavPanel.Root>
@@ -26,6 +28,7 @@ const StandardPanel = ({
26
28
  return (
27
29
  <NavPanel.Column key={stableIdx}>
28
30
  <LinkList
31
+ locale={locale}
29
32
  links={navItems}
30
33
  linkClickHandler={(text, href) => {
31
34
  trackNavClickEvent(text, href, sectionName)
@@ -1,8 +1,8 @@
1
1
  .columns {
2
2
  display: flex;
3
- gap: var(--hdsplus-spacing-03);
3
+ gap: var(--mds-spacing-03);
4
4
  flex-direction: column;
5
- margin-top: var(--hdsplus-spacing-07);
5
+ margin-top: var(--mds-spacing-07);
6
6
 
7
7
  @media (--large) {
8
8
  flex-direction: row;
@@ -0,0 +1,30 @@
1
+ import { getLocalizedLinkProps } from '.'
2
+
3
+ describe('getLocalizedLinkProps', () => {
4
+ it('does not format localized homepage', () => {
5
+ const localizedLinkProps = getLocalizedLinkProps('/en', 'ja')
6
+ expect(localizedLinkProps.href).toBe('/en')
7
+ expect(localizedLinkProps.hrefLang).toBe('en')
8
+ })
9
+
10
+ it('does not format localized path hrefs', () => {
11
+ const localizedLinkProps = getLocalizedLinkProps('/ja/solutions', 'de')
12
+ expect(localizedLinkProps.href).toBe('/ja/solutions')
13
+ expect(localizedLinkProps.hrefLang).toBe('ja')
14
+ })
15
+
16
+ it('does format paths that start with a locale string', () => {
17
+ const localizedLinkProps = getLocalizedLinkProps(
18
+ '/deconstructing-cloud',
19
+ 'en'
20
+ )
21
+ expect(localizedLinkProps.href).toBe('/en/deconstructing-cloud')
22
+ expect(localizedLinkProps.hrefLang).toBe('en')
23
+ })
24
+
25
+ it('does not format external paths', () => {
26
+ const localizedLinkProps = getLocalizedLinkProps('https://google.com', 'ja')
27
+ expect(localizedLinkProps.href).toBe('https://google.com')
28
+ expect(localizedLinkProps.hrefLang).toBe(undefined)
29
+ })
30
+ })
@@ -0,0 +1,45 @@
1
+ import { parseUrl } from '../parse-url'
2
+ import { allSupportedLocales } from '../supported-locales'
3
+
4
+ export const getLocalizedLinkProps = (
5
+ url: string,
6
+ locale?: string
7
+ ): {
8
+ href: string
9
+ hrefLang: string | undefined
10
+ } => {
11
+ const parsedHref = parseUrl(url).href
12
+
13
+ // example: /en
14
+ const hrefIsLocalizedHomepage = allSupportedLocales.includes(
15
+ parsedHref.substring(1)
16
+ )
17
+
18
+ // true example: /en/solutions
19
+ // false example: /entry-point
20
+ const hrefIsLocalized =
21
+ allSupportedLocales.includes(parsedHref.substring(1, 3)) &&
22
+ parsedHref[3] === '/'
23
+
24
+ // If the href is already localized:
25
+ // - do not format the href
26
+ // - use the locale from the href for the hrefLang
27
+ if (hrefIsLocalizedHomepage || hrefIsLocalized) {
28
+ return {
29
+ href: parsedHref,
30
+ hrefLang: parsedHref.substring(1, 3),
31
+ }
32
+ }
33
+
34
+ if (parsedHref.startsWith('/') && locale) {
35
+ return {
36
+ href: `/${locale}${parsedHref}`,
37
+ hrefLang: locale,
38
+ }
39
+ }
40
+
41
+ return {
42
+ href: parsedHref,
43
+ hrefLang: undefined,
44
+ }
45
+ }
@@ -34,13 +34,11 @@ const containsHashiCorpDestination = (str: string): boolean =>
34
34
  *
35
35
  * @throws {Error} Throws an error if the URL is undefined or invalid.
36
36
  */
37
-
38
37
  export function parseUrl(url: string | undefined): {
39
38
  linkType: 'inbound' | 'outbound' | ''
40
39
  href: string
41
40
  } {
42
41
  if (!url) {
43
- console.log('No url to parse, returning empty string')
44
42
  return { linkType: '', href: '' }
45
43
  }
46
44
 
@@ -0,0 +1,22 @@
1
+ import posthog from 'posthog-js'
2
+
3
+ /**
4
+ * A custom hook to send a custom event to PostHog.
5
+ *
6
+ * @param {string} eventName - The name of the custom event to be tracked in PostHog.
7
+ * @param {Record<string, any>} properties - A key-value object containing properties associated with the event.
8
+ *
9
+ * @example
10
+ * const MyComponent = () => {
11
+ * sendPosthogEvent('button_click', { buttonId: 'submit', action: 'clicked' });
12
+ * return <button id="submit">Submit</button>;
13
+ * };
14
+ */
15
+ const sendPosthogEvent = (
16
+ eventName: string,
17
+ properties: Record<string, any>
18
+ ) => {
19
+ posthog.capture(eventName, properties)
20
+ }
21
+
22
+ export default sendPosthogEvent
@@ -0,0 +1,10 @@
1
+ export const allSupportedLocales = [
2
+ 'en',
3
+ 'de',
4
+ 'es',
5
+ 'fr',
6
+ 'ja',
7
+ 'ko',
8
+ 'pt',
9
+ 'id',
10
+ ]
@@ -1,8 +1,8 @@
1
- import va from '@vercel/analytics'
1
+ import sendPosthogEvent from '../send-posthog-event'
2
2
 
3
3
  /**
4
- * Pushes a 'Nav link click' custom event to Vercel Analytics.
5
- * A wrapper around the Vercel Analytics track method.
4
+ * Pushes a 'Nav link click' custom event to PostHog.
5
+ * A wrapper around the PostHog custom event method.
6
6
  *
7
7
  * @param {string} name - The name of the nav link
8
8
  * @param {string} href - The href for the nav link
@@ -14,7 +14,7 @@ export const trackNavClickEvent = (
14
14
  href: string,
15
15
  section: string
16
16
  ) => {
17
- va.track('Nav link click', {
17
+ sendPosthogEvent('Nav link click', {
18
18
  name,
19
19
  href,
20
20
  section,