@hashicorp/react-components 0.0.0-nightly.250c263 → 0.0.0-nightly.2b9aca3

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 (161) hide show
  1. package/package.json +3 -8
  2. package/src/components/nav-panel/components/flight-icon/index.tsx +51 -0
  3. package/src/components/nav-panel/components/flight-icon/style.module.css +3 -0
  4. package/src/components/nav-panel/components/link-list/index.tsx +15 -9
  5. package/src/components/nav-panel/components/link-list/style.module.css +10 -10
  6. package/src/components/nav-panel/components/panel/column/style.module.css +3 -3
  7. package/src/components/nav-panel/components/panel/root/style.module.css +6 -6
  8. package/src/components/nav-panel/components/promo/index.tsx +15 -9
  9. package/src/components/nav-panel/components/promo/style.module.css +23 -13
  10. package/src/components/nav-panel/components/text/index.tsx +34 -0
  11. package/src/components/nav-panel/product-panel/index.tsx +36 -26
  12. package/src/components/nav-panel/product-panel/style.module.css +68 -41
  13. package/src/components/nav-panel/standard-panel/index.tsx +3 -0
  14. package/src/components/nav-panel/standard-panel/style.module.css +2 -2
  15. package/src/lib/get-localized-link-props/index.test.ts +30 -0
  16. package/src/lib/get-localized-link-props/index.ts +45 -0
  17. package/src/lib/parse-url/index.test.ts +40 -1
  18. package/src/lib/parse-url/index.ts +75 -9
  19. package/src/lib/supported-locales/index.ts +1 -0
  20. package/src/lib/track-nav-click-event/index.ts +4 -4
  21. package/src/lib/v/index.ts +4 -5
  22. package/src/components/actions/index.tsx +0 -107
  23. package/src/components/actions/style.module.css +0 -28
  24. package/src/components/actions/types.ts +0 -73
  25. package/src/components/call-to-action/index.tsx +0 -205
  26. package/src/components/call-to-action/styles/variant-centered.module.css +0 -93
  27. package/src/components/call-to-action/styles/variant-compact-grid.module.css +0 -88
  28. package/src/components/call-to-action/styles/variant-compact.module.css +0 -91
  29. package/src/components/call-to-action/styles/variant-links.module.css +0 -85
  30. package/src/components/card/README.md +0 -11
  31. package/src/components/card/card.tsx +0 -45
  32. package/src/components/card/index.test.tsx +0 -69
  33. package/src/components/card/index.tsx +0 -14
  34. package/src/components/card/newsroom-card/index.test.tsx +0 -39
  35. package/src/components/card/newsroom-card/index.tsx +0 -37
  36. package/src/components/card/newsroom-card/style.module.css +0 -12
  37. package/src/components/card/partner-card/index.test.tsx +0 -57
  38. package/src/components/card/partner-card/index.tsx +0 -69
  39. package/src/components/card/partner-card/style.module.css +0 -24
  40. package/src/components/card/person-card/index.test.tsx +0 -71
  41. package/src/components/card/person-card/index.tsx +0 -93
  42. package/src/components/card/person-card/style.module.css +0 -33
  43. package/src/components/card/primitives.tsx +0 -176
  44. package/src/components/card/promo-card/index.tsx +0 -51
  45. package/src/components/card/resource-card/index.test.tsx +0 -48
  46. package/src/components/card/resource-card/index.tsx +0 -37
  47. package/src/components/card/style.module.css +0 -145
  48. package/src/components/card/types.ts +0 -66
  49. package/src/components/card/unified-card/index.tsx +0 -64
  50. package/src/components/consent-manager/README.md +0 -73
  51. package/src/components/consent-manager/components/banner/banner.module.css +0 -23
  52. package/src/components/consent-manager/components/banner/banner.test.tsx +0 -31
  53. package/src/components/consent-manager/components/banner/banner.tsx +0 -73
  54. package/src/components/consent-manager/components/dialog/dialog.module.css +0 -145
  55. package/src/components/consent-manager/components/dialog/dialog.test.tsx +0 -194
  56. package/src/components/consent-manager/components/dialog/dialog.tsx +0 -339
  57. package/src/components/consent-manager/img/icn_close.tsx +0 -19
  58. package/src/components/consent-manager/index.test.tsx +0 -334
  59. package/src/components/consent-manager/index.tsx +0 -186
  60. package/src/components/consent-manager/loader/README.md +0 -29
  61. package/src/components/consent-manager/loader/categories.ts +0 -22
  62. package/src/components/consent-manager/loader/index.tsx +0 -94
  63. package/src/components/consent-manager/loader/presets/enterprise.ts +0 -12
  64. package/src/components/consent-manager/loader/presets/oss.ts +0 -10
  65. package/src/components/consent-manager/loader/services.ts +0 -45
  66. package/src/components/consent-manager/scripts/custom.tsx +0 -59
  67. package/src/components/consent-manager/scripts/segment.tsx +0 -87
  68. package/src/components/consent-manager/style.module.css +0 -9
  69. package/src/components/consent-manager/types.ts +0 -55
  70. package/src/components/consent-manager/util/cookies.test.ts +0 -75
  71. package/src/components/consent-manager/util/cookies.ts +0 -70
  72. package/src/components/consent-manager/util/integrations.test.ts +0 -115
  73. package/src/components/consent-manager/util/integrations.ts +0 -110
  74. package/src/components/intro/index.tsx +0 -82
  75. package/src/components/intro/style.module.css +0 -67
  76. package/src/components/intro/types.ts +0 -44
  77. package/src/components/marketo-form/CHANGELOG.md +0 -122
  78. package/src/components/marketo-form/README.md +0 -1
  79. package/src/components/marketo-form/contexts/FormMetadata.ts +0 -11
  80. package/src/components/marketo-form/docs.mdx +0 -197
  81. package/src/components/marketo-form/fixtures/index.ts +0 -185
  82. package/src/components/marketo-form/form/index.tsx +0 -369
  83. package/src/components/marketo-form/index.test.tsx +0 -320
  84. package/src/components/marketo-form/index.ts +0 -11
  85. package/src/components/marketo-form/package.original.json +0 -30
  86. package/src/components/marketo-form/partials/error-message/index.tsx +0 -12
  87. package/src/components/marketo-form/partials/error-message/style.module.css +0 -13
  88. package/src/components/marketo-form/partials/field/index.tsx +0 -90
  89. package/src/components/marketo-form/partials/field-wrapper/index.tsx +0 -26
  90. package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +0 -32
  91. package/src/components/marketo-form/partials/fields/email-field/index.tsx +0 -35
  92. package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +0 -21
  93. package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +0 -37
  94. package/src/components/marketo-form/partials/fields/htmltext-field/index.tsx +0 -21
  95. package/src/components/marketo-form/partials/fields/htmltext-field/style.module.css +0 -18
  96. package/src/components/marketo-form/partials/fields/name-field/index.tsx +0 -19
  97. package/src/components/marketo-form/partials/fields/name-field/style.module.css +0 -13
  98. package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +0 -48
  99. package/src/components/marketo-form/partials/fields/select-field/index.tsx +0 -39
  100. package/src/components/marketo-form/partials/fields/select-field/style.module.css +0 -5
  101. package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +0 -30
  102. package/src/components/marketo-form/partials/fields/text-field/index.tsx +0 -30
  103. package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +0 -29
  104. package/src/components/marketo-form/partials/label/index.tsx +0 -24
  105. package/src/components/marketo-form/partials/label/style.module.css +0 -12
  106. package/src/components/marketo-form/partials/visibility-rule/index.tsx +0 -84
  107. package/src/components/marketo-form/props.js +0 -66
  108. package/src/components/marketo-form/server/api-routes.ts +0 -109
  109. package/src/components/marketo-form/server/client.ts +0 -98
  110. package/src/components/marketo-form/server/index.ts +0 -8
  111. package/src/components/marketo-form/types.ts +0 -268
  112. package/src/components/marketo-form/utils.test.tsx +0 -103
  113. package/src/components/marketo-form/utils.ts +0 -449
  114. package/src/components/next-steps/index.tsx +0 -137
  115. package/src/components/next-steps/style.module.css +0 -270
  116. package/src/components/next-steps/types.ts +0 -63
  117. package/src/components/product-badge/index.test.tsx +0 -11
  118. package/src/components/product-badge/index.tsx +0 -42
  119. package/src/components/product-badge/style.module.css +0 -76
  120. package/src/components/products-used/index.tsx +0 -84
  121. package/src/components/products-used/style.module.css +0 -87
  122. package/src/components/products-used/types.ts +0 -31
  123. package/src/components/related-content/index.test.tsx +0 -74
  124. package/src/components/related-content/index.tsx +0 -56
  125. package/src/components/related-content/style.module.css +0 -89
  126. package/src/components/related-content/types.ts +0 -21
  127. package/src/components/subnav/helpers/areBasePathsMatching.ts +0 -13
  128. package/src/components/subnav/helpers/traverse/index.ts +0 -42
  129. package/src/components/subnav/helpers/useHeightRef.ts +0 -42
  130. package/src/components/subnav/helpers/useNavRef.ts +0 -30
  131. package/src/components/subnav/helpers/useOverflowRef.ts +0 -85
  132. package/src/components/subnav/helpers/useStuckRef.ts +0 -51
  133. package/src/components/subnav/index.tsx +0 -199
  134. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.test.ts +0 -26
  135. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.ts +0 -22
  136. package/src/components/subnav/partials/CtaLinks/github-stars-link/index.tsx +0 -87
  137. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.test.ts +0 -29
  138. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.ts +0 -32
  139. package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +0 -85
  140. package/src/components/subnav/partials/CtaLinks/icons/github-logo.js +0 -20
  141. package/src/components/subnav/partials/CtaLinks/icons/github.svg.js +0 -7
  142. package/src/components/subnav/partials/CtaLinks/icons/star.js +0 -20
  143. package/src/components/subnav/partials/CtaLinks/index.tsx +0 -130
  144. package/src/components/subnav/partials/CtaLinks/style.module.css +0 -45
  145. package/src/components/subnav/partials/DropdownTrigger/index.tsx +0 -35
  146. package/src/components/subnav/partials/DropdownTrigger/style.module.css +0 -36
  147. package/src/components/subnav/partials/MenuItemsDefault/index.tsx +0 -151
  148. package/src/components/subnav/partials/MenuItemsDefault/style.module.css +0 -91
  149. package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +0 -139
  150. package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +0 -82
  151. package/src/components/subnav/partials/TitleLink/index.tsx +0 -113
  152. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +0 -9
  153. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +0 -9
  154. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-dark.ts +0 -23
  155. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-light.ts +0 -23
  156. package/src/components/subnav/partials/TitleLink/style.module.css +0 -43
  157. package/src/components/subnav/partials/nav-item-text/index.tsx +0 -37
  158. package/src/components/subnav/partials/nav-item-text/style.module.css +0 -15
  159. package/src/components/subnav/style.module.css +0 -68
  160. package/src/components/subnav/subnav-consts.ts +0 -1
  161. package/src/components/subnav/theme.module.css +0 -50
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hashicorp/react-components",
3
- "version": "0.0.0-nightly.250c263",
3
+ "version": "0.0.0-nightly.2b9aca3",
4
4
  "main": "src/index.ts",
5
5
  "scripts": {
6
6
  "lint": "next-hashicorp lint",
@@ -8,20 +8,15 @@
8
8
  "test:watch": "vitest watch"
9
9
  },
10
10
  "dependencies": {
11
- "@hashicorp/flight-icons": "^3.5.0",
11
+ "@hashicorp/flight-icons": "^3.7.0",
12
12
  "@hashicorp/platform-product-meta": "^0.1.1",
13
13
  "@hashicorp/platform-util": "^0.2.0",
14
- "@hashicorp/react-design-system-components": "*",
15
14
  "@hashicorp/web-mktg-logos": "*",
16
15
  "@radix-ui/react-navigation-menu": "^1.2.0",
17
16
  "@radix-ui/react-visually-hidden": "^1.1.0",
18
- "@vercel/analytics": "^1.3.1",
19
17
  "@vercel/fetch": "^7.0.0",
20
18
  "@vercel/stega": "^0.1.2",
21
- "classnames": "^2.3.2",
22
- "js-cookie": "^3.0.5",
23
- "moize": "^6.1.3",
24
- "react-hook-form": "^7.43.5"
19
+ "classnames": "^2.3.2"
25
20
  },
26
21
  "devDependencies": {
27
22
  "@hashicorp/platform-cli": "^2.8.0",
@@ -0,0 +1,51 @@
1
+ import svgSprite from '@hashicorp/flight-icons/svg-sprite/svg-sprite.svg'
2
+ import classNames from 'classnames'
3
+ import { useId, type SVGProps } from 'react'
4
+ import s from './style.module.css'
5
+
6
+ interface Props extends SVGProps<SVGSVGElement> {
7
+ /**
8
+ * The name of the icon you wish to use. If the value does not match an
9
+ * existing icon name, an error will be thrown. Search for existing icon
10
+ * names in the Icon library.
11
+ */
12
+ name: string
13
+
14
+ /**
15
+ * The `color` prop can be used to change the color. It works by setting
16
+ * the value of the icon SVG’s fill property.
17
+ */
18
+ color?: string
19
+
20
+ className?: string
21
+ }
22
+
23
+ // When an SVG file is imported in Next.js, it is an object with a `src`
24
+ // property. However, tools like Webpack and Vite default to returning a URL.
25
+ // This runtime check allows the component to work in all of these cases.
26
+ const svgSpriteSrc =
27
+ typeof svgSprite === 'string' ? svgSprite : (svgSprite as { src: string }).src
28
+
29
+ export default function FlightIcon({
30
+ name,
31
+ color = 'currentColor',
32
+ className,
33
+ ...rest
34
+ }: Props) {
35
+ const iconId = useId()
36
+ return (
37
+ <svg
38
+ className={classNames(s['flight-icon'], className)}
39
+ {...rest}
40
+ aria-hidden="true"
41
+ fill={color}
42
+ id={iconId}
43
+ width={16}
44
+ height={16}
45
+ viewBox="0 0 16 16"
46
+ xmlns="http://www.w3.org/2000/svg"
47
+ >
48
+ <use href={`${svgSpriteSrc}#flight-${name}-16`}></use>
49
+ </svg>
50
+ )
51
+ }
@@ -0,0 +1,3 @@
1
+ .flight-icon {
2
+ display: block;
3
+ }
@@ -1,11 +1,12 @@
1
1
  import Link from 'next/link'
2
- import { parseUrl } from '../../../../lib/parse-url'
3
- import { v } from '../../../../lib/v'
4
- import FlightIcon from '@hashicorp/react-design-system-components/src/components/flight-icon'
2
+ import { vercelSplit } from '../../../../lib/v'
3
+ import { getLocalizedLinkProps } from '../../../../lib/get-localized-link-props'
4
+ import FlightIcon from '../flight-icon'
5
5
  import * as NavigationMenu from '@radix-ui/react-navigation-menu'
6
6
  import s from './style.module.css'
7
7
 
8
8
  export interface LinkListProps {
9
+ locale?: string
9
10
  links: {
10
11
  title: string
11
12
  url: string
@@ -37,15 +38,20 @@ const GRADIENT_VALUE_MAP = new Map([
37
38
  ],
38
39
  ])
39
40
 
40
- export default function LinkList({ links, linkClickHandler }: LinkListProps) {
41
+ export default function LinkList({
42
+ locale,
43
+ links,
44
+ linkClickHandler,
45
+ }: LinkListProps) {
41
46
  return (
42
47
  <ul className={s.linkList}>
43
48
  {links.map((link) => {
44
49
  let style
45
50
  link.iconGradient
46
51
  ? (style = {
47
- '--iconGradient': GRADIENT_VALUE_MAP.get(v(link.iconGradient))
48
- ?.iconGradient,
52
+ '--iconGradient': GRADIENT_VALUE_MAP.get(
53
+ vercelSplit(link.iconGradient)
54
+ )?.iconGradient,
49
55
  } as React.CSSProperties)
50
56
  : (style = null)
51
57
  return (
@@ -53,19 +59,19 @@ export default function LinkList({ links, linkClickHandler }: LinkListProps) {
53
59
  <NavigationMenu.Link asChild>
54
60
  <Link
55
61
  className={s.link}
56
- href={parseUrl(link.url).href}
62
+ {...getLocalizedLinkProps(link.url, locale)}
57
63
  onClickCapture={() => {
58
64
  linkClickHandler && linkClickHandler(link.title, link.url)
59
65
  }}
60
66
  >
61
67
  {link.iconGradient && link.icon ? (
62
68
  <div className={s.iconBackground} style={style}>
63
- <FlightIcon name={v(link.icon)} />
69
+ <FlightIcon name={vercelSplit(link.icon)} />
64
70
  </div>
65
71
  ) : (
66
72
  link.icon && (
67
73
  <FlightIcon
68
- name={v(link.icon)}
74
+ name={vercelSplit(link.icon)}
69
75
  color="var(--token-color-foreground-faint)"
70
76
  />
71
77
  )
@@ -2,7 +2,7 @@
2
2
  display: flex;
3
3
  list-style: none;
4
4
  flex-direction: column;
5
- gap: var(--hdsplus-spacing-03);
5
+ gap: var(--mds-spacing-03);
6
6
  margin: 0;
7
7
  padding: 0;
8
8
  }
@@ -10,14 +10,14 @@
10
10
  .link {
11
11
  color: var(--token-color-foreground-primary);
12
12
  display: flex;
13
- gap: var(--hdsplus-spacing-04);
14
- padding: var(--hdsplus-spacing-03) var(--hdsplus-spacing-04);
13
+ gap: var(--mds-spacing-04);
14
+ padding: var(--mds-spacing-03) var(--mds-spacing-04);
15
15
  min-width: 190px;
16
16
  align-items: center;
17
17
 
18
18
  &:hover {
19
19
  background-color: var(--token-color-surface-interactive-hover);
20
- border-radius: var(--hdsplus-spacing-01);
20
+ border-radius: var(--mds-spacing-01);
21
21
  }
22
22
 
23
23
  &:has(.iconBackground) {
@@ -35,15 +35,15 @@
35
35
  }
36
36
 
37
37
  .description {
38
- font-size: var(--hdsplus-typography-body-200-font-size);
39
- font-weight: var(--token-typography-font-weight-regular);
40
- margin-top: var(--hdsplus-spacing-02);
38
+ font-size: var(--mds-typography-body-200-font-size);
39
+ font-weight: var(--mds-typography-font-weight-regular);
40
+ margin-top: var(--mds-spacing-02);
41
41
  }
42
42
 
43
43
  .iconBackground {
44
44
  background: var(--iconGradient);
45
- height: var(--hdsplus-spacing-08);
46
- width: var(--hdsplus-spacing-08);
45
+ height: var(--mds-spacing-08);
46
+ width: var(--mds-spacing-08);
47
47
  display: flex;
48
48
  align-items: center;
49
49
  justify-content: center;
@@ -53,5 +53,5 @@
53
53
  }
54
54
 
55
55
  .boldTitle {
56
- font-weight: var(--font-weight-semi-bold);
56
+ font-weight: var(--mds-typography-font-weight-semibold);
57
57
  }
@@ -1,4 +1,4 @@
1
- @custom-media --dev-dot-viewport (min-width: 1230px);
1
+ @custom-media --dev-dot-viewport (min-width: 924px);
2
2
 
3
3
  .column {
4
4
  position: relative;
@@ -7,8 +7,8 @@
7
7
  justify-content: flex-start;
8
8
  min-width: 190px;
9
9
  padding: 0;
10
- margin: 0 var(--hdsplus-spacing-07);
11
- border-radius: var(--hdsplus-spacing-03);
10
+ margin: 0 var(--mds-spacing-07);
11
+ border-radius: var(--mds-spacing-03);
12
12
 
13
13
  @media (--large) {
14
14
  &:not(.hasSide) {
@@ -1,4 +1,4 @@
1
- @custom-media --dev-dot-viewport (min-width: 1230px);
1
+ @custom-media --dev-dot-viewport (min-width: 924px);
2
2
 
3
3
  .root {
4
4
  width: 100%;
@@ -6,15 +6,15 @@
6
6
  flex-direction: column;
7
7
  justify-content: space-between;
8
8
  /* stylelint-disable-next-line unit-no-unknown */
9
- min-height: calc(100dvh - var(--hdsplus-spacing-12));
9
+ min-height: calc(100dvh - var(--mds-spacing-12));
10
10
 
11
11
  @media (--large) {
12
12
  &:not(.hasSide) {
13
13
  justify-content: flex-start;
14
14
  height: 100%;
15
15
  min-height: fit-content;
16
- padding: var(--hdsplus-spacing-05) var(--hdsplus-spacing-04);
17
- gap: var(--hdsplus-spacing-04);
16
+ padding: var(--mds-spacing-05) var(--mds-spacing-04);
17
+ gap: var(--mds-spacing-04);
18
18
  }
19
19
  }
20
20
 
@@ -23,8 +23,8 @@
23
23
  justify-content: flex-start;
24
24
  height: 100%;
25
25
  min-height: fit-content;
26
- padding: var(--hdsplus-spacing-05) var(--hdsplus-spacing-04);
27
- gap: var(--hdsplus-spacing-04);
26
+ padding: var(--mds-spacing-05) var(--mds-spacing-04);
27
+ gap: var(--mds-spacing-04);
28
28
  }
29
29
  }
30
30
  }
@@ -1,14 +1,15 @@
1
1
  import { useCallback } from 'react'
2
2
  import classNames from 'classnames'
3
- import { v } from '../../../../lib/v'
3
+ import { vercelSplit } from '../../../../lib/v'
4
4
  import Link from 'next/link'
5
- import { parseUrl } from '../../../../lib/parse-url'
5
+ import { getLocalizedLinkProps } from '../../../../lib/get-localized-link-props'
6
6
  import { trackNavClickEvent } from '../../../../lib/track-nav-click-event'
7
- import FlightIcon from '@hashicorp/react-design-system-components/src/components/flight-icon'
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
13
14
  description: string
14
15
  linkUrl: string
@@ -17,9 +18,11 @@ export interface PromoProps {
17
18
  icon?: string
18
19
  theme: string
19
20
  hasSidePanel?: boolean
21
+ isPromoOnTop?: boolean
20
22
  }
21
23
 
22
24
  export default function Promo({
25
+ locale,
23
26
  title,
24
27
  description,
25
28
  linkUrl,
@@ -28,6 +31,7 @@ export default function Promo({
28
31
  icon,
29
32
  theme,
30
33
  hasSidePanel,
34
+ isPromoOnTop = false,
31
35
  }: PromoProps) {
32
36
  const handleClick = useCallback((title, linkUrl, linkTitle, slug) => {
33
37
  if (window && window.analytics) {
@@ -46,24 +50,25 @@ export default function Promo({
46
50
  className={classNames(s.promo, {
47
51
  [s.hasSide]: hasSidePanel,
48
52
  [s.noSide]: !hasSidePanel,
53
+ [s.topPromo]: isPromoOnTop,
49
54
  })}
50
55
  >
51
56
  {icon && (
52
57
  <div
53
58
  className={classNames(s.icon, {
54
- [s.hashidays]: v(theme) === 'hashidays',
55
- [s.hashiconf]: v(theme) === 'hashiconf',
59
+ [s.hashidays]: vercelSplit(theme) === 'hashidays',
60
+ [s.hashiconf]: vercelSplit(theme) === 'hashiconf',
56
61
  })}
57
62
  >
58
- <FlightIcon name={v(icon)} />
63
+ <FlightIcon name={vercelSplit(icon)} />
59
64
  </div>
60
65
  )}
61
66
  <div className={s.rightContent}>
62
67
  <div>
63
68
  <div
64
69
  className={classNames(s.title, {
65
- [s.hashidays]: v(theme) === 'hashidays',
66
- [s.hashiconf]: v(theme) === 'hashiconf',
70
+ [s.hashidays]: vercelSplit(theme) === 'hashidays',
71
+ [s.hashiconf]: vercelSplit(theme) === 'hashiconf',
67
72
  })}
68
73
  >
69
74
  {title}
@@ -72,7 +77,8 @@ export default function Promo({
72
77
  </div>
73
78
  <NavigationMenu.Link asChild>
74
79
  <Link
75
- href={parseUrl(linkUrl).href}
80
+ locale={locale ? locale : undefined}
81
+ {...getLocalizedLinkProps(linkUrl, locale)}
76
82
  className={s.link}
77
83
  onClickCapture={() => handleClick(title, linkUrl, linkTitle, slug)}
78
84
  >
@@ -1,18 +1,21 @@
1
- @custom-media --dev-dot-viewport (min-width: 1230px);
1
+ @custom-media --dev-dot-viewport (min-width: 924px);
2
2
 
3
3
  .promo {
4
4
  display: flex;
5
- border-radius: var(--hdsplus-spacing-01);
5
+ border-radius: var(--mds-spacing-01);
6
6
  border: 1px solid var(--token-color-border-faint);
7
7
  background-color: var(--token-color-surface-faint);
8
- padding: var(--hdsplus-spacing-05) var(--hdsplus-spacing-08)
9
- var(--hdsplus-spacing-06) var(--hdsplus-spacing-08);
8
+ padding: var(--mds-spacing-05) var(--mds-spacing-08)
9
+ var(--mds-spacing-06) var(--mds-spacing-08);
10
10
  flex-direction: row;
11
- gap: var(--hdsplus-spacing-04);
12
- margin: var(--hdsplus-spacing-07);
13
- margin-bottom: var(--hdsplus-spacing-09);
11
+ gap: var(--mds-spacing-04);
12
+ margin: var(--mds-spacing-07);
13
+ margin-bottom: var(--mds-spacing-09);
14
14
 
15
15
  @media (--large) {
16
+ &.topPromo {
17
+ margin-bottom: var(--mds-spacing-05);
18
+ }
16
19
  &.noSide {
17
20
  margin: 0;
18
21
  width: min-content;
@@ -21,6 +24,9 @@
21
24
  }
22
25
 
23
26
  @media (--dev-dot-viewport) {
27
+ &.topPromo {
28
+ margin-bottom: var(--mds-spacing-05);
29
+ }
24
30
  &.hasSide {
25
31
  margin: 0;
26
32
  width: min-content;
@@ -29,22 +35,26 @@
29
35
  }
30
36
  }
31
37
 
38
+ .topPromo {
39
+ margin-bottom: 0;
40
+ }
41
+
32
42
  .rightContent {
33
43
  display: flex;
34
44
  flex-wrap: wrap;
35
- gap: var(--hdsplus-spacing-03);
45
+ gap: var(--mds-spacing-03);
36
46
  width: 100%;
37
47
  justify-content: space-between;
38
48
  }
39
49
 
40
50
  .title {
41
- font-weight: var(--font-weight-semi-bold);
51
+ font-weight: var(--mds-typography-font-weight-semibold);
42
52
  }
43
53
 
44
54
  .description {
45
- font-size: var(--hdsplus-typography-body-200-font-size);
46
- font-weight: var(--token-typography-font-weight-regular);
47
- margin-top: var(--hdsplus-spacing-01);
55
+ font-size: var(--mds-typography-body-200-font-size);
56
+ font-weight: var(--mds-typography-font-weight-regular);
57
+ margin-top: var(--mds-spacing-01);
48
58
  }
49
59
 
50
60
  .icon {
@@ -70,7 +80,7 @@
70
80
  display: flex;
71
81
  flex-direction: row;
72
82
  align-items: center;
73
- gap: var(--hdsplus-spacing-02);
83
+ gap: var(--mds-spacing-02);
74
84
 
75
85
  &:hover {
76
86
  text-decoration: underline;
@@ -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,12 +1,11 @@
1
- import { CSSProperties } from 'react'
2
1
  import classNames from 'classnames'
3
2
  import Link from 'next/link'
4
3
  import * as NavPanel from '../components/panel'
5
4
  import Promo, { type PromoProps } from '../components/promo'
5
+ import { getLocalizedLinkProps } from '../../../lib/get-localized-link-props'
6
6
  import { Products } from '@hashicorp/platform-product-meta'
7
- import FlightIcon from '@hashicorp/react-design-system-components/src/components/flight-icon'
8
- import { TextPlus } from '@hashicorp/react-design-system-components/src/components/text'
9
- import { parseUrl } from '../../../lib/parse-url'
7
+ import FlightIcon from '../components/flight-icon'
8
+ import { Text } from '../components/text'
10
9
  import { trackNavClickEvent } from '../../../lib/track-nav-click-event'
11
10
  import * as NavigationMenu from '@radix-ui/react-navigation-menu'
12
11
  import s from './style.module.css'
@@ -31,6 +30,7 @@ const PRODUCT_LOGO_EXCEPTION_CLASSNAMES = {
31
30
  }
32
31
 
33
32
  export interface ProductsPanelProps {
33
+ locale: string
34
34
  productCategories: any
35
35
  promo?: PromoProps
36
36
  sidePanel?: {
@@ -42,43 +42,44 @@ export interface ProductsPanelProps {
42
42
  url: string
43
43
  }[]
44
44
  }
45
+ isPromoOnTop?: boolean
45
46
  }
46
47
 
47
48
  const ProductPanel = ({
49
+ locale,
48
50
  productCategories,
49
51
  promo,
50
52
  sidePanel,
53
+ isPromoOnTop = false,
51
54
  }: ProductsPanelProps) => {
52
55
  return (
53
56
  <NavPanel.Root
54
57
  className={classNames(s.productPanel, {
55
58
  [s.hasSide]: sidePanel,
56
59
  [s.noSide]: !sidePanel,
60
+ [s.topPromo]: isPromoOnTop,
57
61
  })}
58
62
  hasSidePanel={Boolean(sidePanel)}
59
63
  >
60
64
  <div className={s.mainPanel}>
65
+ {promo && isPromoOnTop ? (
66
+ <Promo
67
+ {...promo}
68
+ hasSidePanel={Boolean(sidePanel)}
69
+ isPromoOnTop={isPromoOnTop}
70
+ />
71
+ ) : null}
61
72
  <NavPanel.Column hasSidePanel={Boolean(sidePanel)}>
62
73
  <ul className={s.productCategories}>
63
74
  {productCategories.map(({ title, products }) => {
64
75
  return (
65
76
  <li key={title} className={s.productCategory}>
66
- <TextPlus.Body className={s.eyebrow}>{title}</TextPlus.Body>
67
- <ul
68
- className={s.productList}
69
- // Dynamically calculate row count based on number of items divided by expected columns
70
- style={
71
- {
72
- '--row-count-above-mobile': Math.ceil(
73
- products.length / 2
74
- ),
75
- } as CSSProperties
76
- }
77
- >
77
+ <Text className={s.eyebrow}>{title}</Text>
78
+ <ul className={s.productList}>
78
79
  {products.map((product) => {
79
80
  return (
80
81
  <li key={product.url}>
81
- <NavProduct {...product} />
82
+ <NavProduct locale={locale} {...product} />
82
83
  </li>
83
84
  )
84
85
  })}
@@ -88,14 +89,16 @@ const ProductPanel = ({
88
89
  })}
89
90
  </ul>
90
91
  </NavPanel.Column>
91
- {promo ? <Promo {...promo} hasSidePanel={Boolean(sidePanel)} /> : null}
92
+ {promo && !isPromoOnTop ? (
93
+ <Promo {...promo} hasSidePanel={Boolean(sidePanel)} />
94
+ ) : null}
92
95
  </div>
93
96
 
94
97
  {sidePanel ? (
95
98
  <NavPanel.Column className={s.sidePanel}>
96
- <TextPlus.Body size="200" weight="semibold">
99
+ <Text size="200" weight="semibold">
97
100
  {sidePanel.label}
98
- </TextPlus.Body>
101
+ </Text>
99
102
 
100
103
  {/* ! TODO Replace the below list with the <LinkList /> component,
101
104
  That component will require a refactor to support greater customization
@@ -106,18 +109,22 @@ const ProductPanel = ({
106
109
  {sidePanel.navItems.map(({ icon, title, description, url }) => {
107
110
  return (
108
111
  <li key={title}>
109
- <Link href={parseUrl(url).href} className={s.sidePanelItem}>
112
+ <Link
113
+ aria-label={`${title} - ${description}`}
114
+ {...getLocalizedLinkProps(url, locale)}
115
+ locale={locale ? locale : undefined}
116
+ className={classNames(s.sidePanelItem, s.focusIndicator)}
117
+ >
110
118
  <div className={s.iconBackground}>
111
119
  <FlightIcon
112
- size={16}
113
120
  name={icon}
114
121
  color="var(--token-color-foreground-faint)"
115
122
  />
116
123
  </div>
117
124
  <div className={s.sidePanelItemContent}>
118
- <TextPlus.Body size="200" weight="semibold" tag="span">
125
+ <Text size="200" weight="semibold">
119
126
  {title}
120
- </TextPlus.Body>
127
+ </Text>
121
128
  <span className={s.sidePanelItemDesc}>{description}</span>
122
129
  </div>
123
130
  </Link>
@@ -132,16 +139,19 @@ const ProductPanel = ({
132
139
  }
133
140
 
134
141
  export interface NavProductProps {
142
+ locale?: string
135
143
  url: string
136
144
  product: Products | string
137
145
  description: string
138
146
  }
139
147
 
140
- function NavProduct({ url, product, description }: NavProductProps) {
148
+ function NavProduct({ locale, url, product, description }: NavProductProps) {
141
149
  return (
142
150
  <NavigationMenu.Link asChild>
143
151
  <Link
144
- href={parseUrl(url).href}
152
+ aria-label={`${product} - ${description}`}
153
+ {...getLocalizedLinkProps(url, locale)}
154
+ locale={locale ? locale : undefined}
145
155
  onClickCapture={() => {
146
156
  trackNavClickEvent(product, url, 'products')
147
157
  }}