@hashicorp/react-components 1.1.10 → 1.2.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 (173) hide show
  1. package/README.md +1 -1
  2. package/package.json +8 -13
  3. package/postcss.config.js +1 -1
  4. package/src/components/nav-panel/components/flight-icon/index.tsx +53 -0
  5. package/src/components/nav-panel/components/flight-icon/style.module.css +3 -0
  6. package/src/components/nav-panel/components/link/cloud-fill.svg +3 -0
  7. package/src/components/nav-panel/components/link/index.tsx +139 -0
  8. package/src/components/nav-panel/components/link/layers-fill.svg +5 -0
  9. package/src/components/nav-panel/components/link/shield-alert-fill.svg +3 -0
  10. package/src/components/nav-panel/components/link/style.module.css +64 -0
  11. package/src/components/nav-panel/components/link/zap-fill.svg +3 -0
  12. package/src/components/nav-panel/components/link-list/index.tsx +12 -64
  13. package/src/components/nav-panel/components/link-list/style.module.css +1 -50
  14. package/src/components/nav-panel/components/panel/column/style.module.css +2 -2
  15. package/src/components/nav-panel/components/panel/root/style.module.css +5 -5
  16. package/src/components/nav-panel/components/promo/index.tsx +35 -15
  17. package/src/components/nav-panel/components/promo/style.module.css +32 -28
  18. package/src/components/nav-panel/components/text/index.tsx +34 -0
  19. package/src/components/nav-panel/product-panel/index.tsx +71 -20
  20. package/src/components/nav-panel/product-panel/style.module.css +111 -53
  21. package/src/components/nav-panel/standard-panel/index.tsx +3 -0
  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 +57 -2
  26. package/src/lib/parse-url/index.ts +97 -13
  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 +5 -5
  30. package/src/lib/v/index.ts +9 -4
  31. package/tsconfig.json +1 -2
  32. package/.eslintrc.js +0 -4
  33. package/.stylelintrc.js +0 -3
  34. package/src/components/actions/index.tsx +0 -107
  35. package/src/components/actions/style.module.css +0 -28
  36. package/src/components/actions/types.ts +0 -73
  37. package/src/components/call-to-action/index.tsx +0 -205
  38. package/src/components/call-to-action/styles/variant-centered.module.css +0 -93
  39. package/src/components/call-to-action/styles/variant-compact-grid.module.css +0 -88
  40. package/src/components/call-to-action/styles/variant-compact.module.css +0 -91
  41. package/src/components/call-to-action/styles/variant-links.module.css +0 -85
  42. package/src/components/card/README.md +0 -11
  43. package/src/components/card/card.tsx +0 -45
  44. package/src/components/card/index.test.tsx +0 -69
  45. package/src/components/card/index.tsx +0 -14
  46. package/src/components/card/newsroom-card/index.test.tsx +0 -39
  47. package/src/components/card/newsroom-card/index.tsx +0 -37
  48. package/src/components/card/newsroom-card/style.module.css +0 -12
  49. package/src/components/card/partner-card/index.test.tsx +0 -57
  50. package/src/components/card/partner-card/index.tsx +0 -69
  51. package/src/components/card/partner-card/style.module.css +0 -24
  52. package/src/components/card/person-card/index.test.tsx +0 -71
  53. package/src/components/card/person-card/index.tsx +0 -93
  54. package/src/components/card/person-card/style.module.css +0 -33
  55. package/src/components/card/primitives.tsx +0 -176
  56. package/src/components/card/promo-card/index.tsx +0 -51
  57. package/src/components/card/resource-card/index.test.tsx +0 -48
  58. package/src/components/card/resource-card/index.tsx +0 -37
  59. package/src/components/card/style.module.css +0 -145
  60. package/src/components/card/types.ts +0 -66
  61. package/src/components/card/unified-card/index.tsx +0 -64
  62. package/src/components/consent-manager/README.md +0 -73
  63. package/src/components/consent-manager/components/banner/banner.module.css +0 -23
  64. package/src/components/consent-manager/components/banner/banner.test.tsx +0 -31
  65. package/src/components/consent-manager/components/banner/banner.tsx +0 -73
  66. package/src/components/consent-manager/components/dialog/dialog.module.css +0 -145
  67. package/src/components/consent-manager/components/dialog/dialog.test.tsx +0 -194
  68. package/src/components/consent-manager/components/dialog/dialog.tsx +0 -339
  69. package/src/components/consent-manager/img/icn_close.tsx +0 -19
  70. package/src/components/consent-manager/index.test.tsx +0 -334
  71. package/src/components/consent-manager/index.tsx +0 -186
  72. package/src/components/consent-manager/loader/README.md +0 -29
  73. package/src/components/consent-manager/loader/categories.ts +0 -22
  74. package/src/components/consent-manager/loader/index.tsx +0 -94
  75. package/src/components/consent-manager/loader/presets/enterprise.ts +0 -12
  76. package/src/components/consent-manager/loader/presets/oss.ts +0 -10
  77. package/src/components/consent-manager/loader/services.ts +0 -45
  78. package/src/components/consent-manager/scripts/custom.tsx +0 -59
  79. package/src/components/consent-manager/scripts/segment.tsx +0 -87
  80. package/src/components/consent-manager/style.module.css +0 -9
  81. package/src/components/consent-manager/types.ts +0 -55
  82. package/src/components/consent-manager/util/cookies.test.ts +0 -75
  83. package/src/components/consent-manager/util/cookies.ts +0 -70
  84. package/src/components/consent-manager/util/integrations.test.ts +0 -115
  85. package/src/components/consent-manager/util/integrations.ts +0 -110
  86. package/src/components/intro/index.tsx +0 -82
  87. package/src/components/intro/style.module.css +0 -67
  88. package/src/components/intro/types.ts +0 -44
  89. package/src/components/marketo-form/CHANGELOG.md +0 -122
  90. package/src/components/marketo-form/README.md +0 -1
  91. package/src/components/marketo-form/contexts/FormMetadata.ts +0 -11
  92. package/src/components/marketo-form/docs.mdx +0 -197
  93. package/src/components/marketo-form/fixtures/index.ts +0 -185
  94. package/src/components/marketo-form/form/index.tsx +0 -369
  95. package/src/components/marketo-form/index.test.tsx +0 -320
  96. package/src/components/marketo-form/index.ts +0 -11
  97. package/src/components/marketo-form/package.original.json +0 -30
  98. package/src/components/marketo-form/partials/error-message/index.tsx +0 -12
  99. package/src/components/marketo-form/partials/error-message/style.module.css +0 -13
  100. package/src/components/marketo-form/partials/field/index.tsx +0 -90
  101. package/src/components/marketo-form/partials/field-wrapper/index.tsx +0 -26
  102. package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +0 -32
  103. package/src/components/marketo-form/partials/fields/email-field/index.tsx +0 -35
  104. package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +0 -21
  105. package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +0 -37
  106. package/src/components/marketo-form/partials/fields/htmltext-field/index.tsx +0 -21
  107. package/src/components/marketo-form/partials/fields/htmltext-field/style.module.css +0 -18
  108. package/src/components/marketo-form/partials/fields/name-field/index.tsx +0 -19
  109. package/src/components/marketo-form/partials/fields/name-field/style.module.css +0 -13
  110. package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +0 -48
  111. package/src/components/marketo-form/partials/fields/select-field/index.tsx +0 -39
  112. package/src/components/marketo-form/partials/fields/select-field/style.module.css +0 -5
  113. package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +0 -30
  114. package/src/components/marketo-form/partials/fields/text-field/index.tsx +0 -30
  115. package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +0 -29
  116. package/src/components/marketo-form/partials/label/index.tsx +0 -24
  117. package/src/components/marketo-form/partials/label/style.module.css +0 -12
  118. package/src/components/marketo-form/partials/visibility-rule/index.tsx +0 -84
  119. package/src/components/marketo-form/props.js +0 -66
  120. package/src/components/marketo-form/server/api-routes.ts +0 -109
  121. package/src/components/marketo-form/server/client.ts +0 -98
  122. package/src/components/marketo-form/server/index.ts +0 -8
  123. package/src/components/marketo-form/types.ts +0 -268
  124. package/src/components/marketo-form/utils.test.tsx +0 -103
  125. package/src/components/marketo-form/utils.ts +0 -449
  126. package/src/components/next-steps/index.tsx +0 -137
  127. package/src/components/next-steps/style.module.css +0 -270
  128. package/src/components/next-steps/types.ts +0 -63
  129. package/src/components/product-badge/index.test.tsx +0 -11
  130. package/src/components/product-badge/index.tsx +0 -42
  131. package/src/components/product-badge/style.module.css +0 -76
  132. package/src/components/products-used/index.tsx +0 -84
  133. package/src/components/products-used/style.module.css +0 -87
  134. package/src/components/products-used/types.ts +0 -31
  135. package/src/components/related-content/index.test.tsx +0 -74
  136. package/src/components/related-content/index.tsx +0 -56
  137. package/src/components/related-content/style.module.css +0 -89
  138. package/src/components/related-content/types.ts +0 -21
  139. package/src/components/subnav/helpers/areBasePathsMatching.ts +0 -13
  140. package/src/components/subnav/helpers/traverse/index.ts +0 -42
  141. package/src/components/subnav/helpers/useHeightRef.ts +0 -42
  142. package/src/components/subnav/helpers/useNavRef.ts +0 -30
  143. package/src/components/subnav/helpers/useOverflowRef.ts +0 -85
  144. package/src/components/subnav/helpers/useStuckRef.ts +0 -51
  145. package/src/components/subnav/index.tsx +0 -199
  146. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.test.ts +0 -26
  147. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.ts +0 -22
  148. package/src/components/subnav/partials/CtaLinks/github-stars-link/index.tsx +0 -87
  149. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.test.ts +0 -29
  150. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.ts +0 -32
  151. package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +0 -85
  152. package/src/components/subnav/partials/CtaLinks/icons/github-logo.js +0 -20
  153. package/src/components/subnav/partials/CtaLinks/icons/github.svg.js +0 -7
  154. package/src/components/subnav/partials/CtaLinks/icons/star.js +0 -20
  155. package/src/components/subnav/partials/CtaLinks/index.tsx +0 -130
  156. package/src/components/subnav/partials/CtaLinks/style.module.css +0 -45
  157. package/src/components/subnav/partials/DropdownTrigger/index.tsx +0 -35
  158. package/src/components/subnav/partials/DropdownTrigger/style.module.css +0 -36
  159. package/src/components/subnav/partials/MenuItemsDefault/index.tsx +0 -151
  160. package/src/components/subnav/partials/MenuItemsDefault/style.module.css +0 -91
  161. package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +0 -139
  162. package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +0 -82
  163. package/src/components/subnav/partials/TitleLink/index.tsx +0 -113
  164. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +0 -9
  165. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +0 -9
  166. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-dark.ts +0 -23
  167. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-light.ts +0 -23
  168. package/src/components/subnav/partials/TitleLink/style.module.css +0 -43
  169. package/src/components/subnav/partials/nav-item-text/index.tsx +0 -37
  170. package/src/components/subnav/partials/nav-item-text/style.module.css +0 -15
  171. package/src/components/subnav/style.module.css +0 -68
  172. package/src/components/subnav/subnav-consts.ts +0 -1
  173. package/src/components/subnav/theme.module.css +0 -50
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
1
  # `@hashicorp/react-components`
2
2
 
3
- This package contains React components that are built using HDS guidelines that don't align with existing HDS components.
3
+ This package contains React components that are built using HDS guidelines that don't align with existing HDS components.
package/package.json CHANGED
@@ -1,30 +1,25 @@
1
1
  {
2
2
  "name": "@hashicorp/react-components",
3
- "version": "1.1.10",
3
+ "version": "1.2.0",
4
4
  "main": "src/index.ts",
5
5
  "scripts": {
6
- "lint": "next-hashicorp lint",
6
+ "lint": "npm run lint:js",
7
+ "lint:js": "eslint . --quiet",
7
8
  "test": "vitest run",
8
9
  "test:watch": "vitest watch"
9
10
  },
10
11
  "dependencies": {
11
- "@hashicorp/flight-icons": "^3.5.0",
12
- "@hashicorp/platform-product-meta": "^0.1.1",
13
- "@hashicorp/platform-util": "^0.2.0",
14
- "@hashicorp/react-design-system-components": "*",
12
+ "@hashicorp/flight-icons": "^3.7.0",
13
+ "@web/product-meta": "^0.1.1",
15
14
  "@hashicorp/web-mktg-logos": "*",
16
- "@radix-ui/react-navigation-menu": "^1.2.0",
17
- "@radix-ui/react-visually-hidden": "^1.1.0",
18
- "@vercel/analytics": "^1.3.1",
15
+ "@radix-ui/react-navigation-menu": "^1.2.14",
16
+ "@radix-ui/react-visually-hidden": "^1.2.4",
19
17
  "@vercel/fetch": "^7.0.0",
20
18
  "@vercel/stega": "^0.1.2",
21
19
  "classnames": "^2.3.2",
22
- "js-cookie": "^3.0.5",
23
- "moize": "^6.1.3",
24
- "react-hook-form": "^7.43.5"
20
+ "posthog-js": "^1.195.0"
25
21
  },
26
22
  "devDependencies": {
27
- "@hashicorp/platform-cli": "^2.8.0",
28
23
  "@hashicorp/platform-types": "^0.4.0",
29
24
  "@testing-library/jest-dom": "^6.4.2",
30
25
  "@vitejs/plugin-react": "^4.2.1",
package/postcss.config.js CHANGED
@@ -13,7 +13,7 @@ function standardSyntax(plugins) {
13
13
  return _plugins
14
14
  }
15
15
 
16
- const baseConfig = require('@hashicorp/platform-postcss-config')
16
+ const baseConfig = require('@hashicorp/mds-postcss-config')
17
17
 
18
18
  module.exports = {
19
19
  ...baseConfig,
@@ -0,0 +1,53 @@
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
+ size?: 16 | 24
22
+ }
23
+
24
+ // When an SVG file is imported in Next.js, it is an object with a `src`
25
+ // property. However, tools like Webpack and Vite default to returning a URL.
26
+ // This runtime check allows the component to work in all of these cases.
27
+ const svgSpriteSrc =
28
+ typeof svgSprite === 'string' ? svgSprite : (svgSprite as { src: string }).src
29
+
30
+ export default function FlightIcon({
31
+ name,
32
+ color = 'currentColor',
33
+ className,
34
+ size = 16,
35
+ ...rest
36
+ }: Props) {
37
+ const iconId = useId()
38
+ return (
39
+ <svg
40
+ className={classNames(s['flight-icon'], className)}
41
+ {...rest}
42
+ aria-hidden="true"
43
+ fill={color}
44
+ id={iconId}
45
+ width={size}
46
+ height={size}
47
+ viewBox="0 0 16 16"
48
+ xmlns="http://www.w3.org/2000/svg"
49
+ >
50
+ <use href={`${svgSpriteSrc}#flight-${name}-16`}></use>
51
+ </svg>
52
+ )
53
+ }
@@ -0,0 +1,3 @@
1
+ .flight-icon {
2
+ display: inline-block;
3
+ }
@@ -0,0 +1,3 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M3.93179 2.37285C4.98771 1.98353 6.13197 1.89703 7.23466 2.12309C8.33737 2.34915 9.35467 2.87879 10.1708 3.65225C10.844 4.29015 11.358 5.07282 11.6757 5.93748H11.9554C13.0271 5.93748 14.0556 6.36147 14.8143 7.11713C15.5731 7.8729 16 8.89859 16 9.96872C16 11.0389 15.5731 12.0645 14.8143 12.8203C14.0556 13.576 13.0271 14 11.9554 14H6.03326C6.03078 14 6.02829 14 6.02579 14C4.90005 14.0008 3.79643 13.6872 2.84032 13.0944C1.88417 12.5016 1.11373 11.6533 0.616922 10.6456C0.120097 9.63781 -0.0830371 8.51125 0.0307977 7.39398C0.144632 6.27672 0.57082 5.21396 1.26058 4.32641C1.94849 3.44122 2.87099 2.76578 3.92346 2.37597C3.92623 2.37492 3.929 2.37388 3.93179 2.37285Z" fill="#EFEFF1"/>
3
+ </svg>
@@ -0,0 +1,139 @@
1
+ import Image from 'next/image'
2
+ import Link from 'next/link'
3
+ import classNames from 'classnames'
4
+ import { vercelSplit } from '../../../../lib/v'
5
+ import { getLocalizedLinkProps } from '../../../../lib/get-localized-link-props'
6
+ import FlightIcon from '../flight-icon'
7
+ import * as NavigationMenu from '@radix-ui/react-navigation-menu'
8
+ import ShieldAlertFill from './shield-alert-fill.svg'
9
+ import CloudFill from './cloud-fill.svg'
10
+ import LayersFill from './layers-fill.svg'
11
+ import ZapFill from './zap-fill.svg'
12
+ import s from './style.module.css'
13
+
14
+ interface NavLinkProps {
15
+ title: string
16
+ url: string
17
+ icon?: string
18
+ description?: string
19
+ iconGradient?: string
20
+ linkClickHandler?: (title: string, url: string) => void
21
+ locale?: string
22
+ className?: string
23
+ }
24
+
25
+ const GRADIENT_VALUE_MAP = new Map([
26
+ [
27
+ 'ILM',
28
+ {
29
+ iconBackground: 'var(--mds-gradient-ilm)',
30
+ },
31
+ ],
32
+ [
33
+ 'SLM',
34
+ {
35
+ iconBackground: 'var(--mds-gradient-slm)',
36
+ },
37
+ ],
38
+ [
39
+ 'Cloud',
40
+ {
41
+ iconBackground: 'var(--mds-gradient-hashicorp)',
42
+ },
43
+ ],
44
+ [
45
+ 'Black',
46
+ {
47
+ iconBackground: 'var(--mds-color-surface-faint)',
48
+ },
49
+ ],
50
+ [
51
+ 'Solution Application',
52
+ {
53
+ iconBackground:
54
+ 'linear-gradient(90deg, #a3f7d6 0%, #5cd1d9 50%, #5494e3 100%)',
55
+ },
56
+ ],
57
+ ['ILM Solid', { iconBackground: '#7948FF' }],
58
+ ['SLM Solid', { iconBackground: '#FF6423' }],
59
+ ])
60
+
61
+ export default function NavLink({
62
+ url,
63
+ title,
64
+ description,
65
+ icon,
66
+ iconGradient,
67
+ linkClickHandler,
68
+ locale,
69
+ className,
70
+ }: NavLinkProps) {
71
+ const style = iconGradient
72
+ ? {
73
+ ['--iconBackground' as string]: GRADIENT_VALUE_MAP.get(
74
+ vercelSplit(iconGradient),
75
+ )?.iconBackground,
76
+ }
77
+ : undefined
78
+
79
+ return (
80
+ <NavigationMenu.Link asChild>
81
+ <Link
82
+ className={classNames(s.link, className)}
83
+ {...getLocalizedLinkProps(url, locale)}
84
+ onClickCapture={() => {
85
+ linkClickHandler && linkClickHandler(title, url)
86
+ }}
87
+ >
88
+ {iconGradient && icon ? (
89
+ <div className={s.iconBackground} style={style} data-theme="dark">
90
+ <IconSwitcher icon={icon} iconGradient={iconGradient} />
91
+ </div>
92
+ ) : (
93
+ icon && (
94
+ <div className={s.iconWrapper}>
95
+ <FlightIcon
96
+ name={vercelSplit(icon)}
97
+ color="var(--mds-color-foreground-faint)"
98
+ />
99
+ </div>
100
+ )
101
+ )}
102
+ <div>
103
+ <div className={iconGradient && s.boldTitle}>{title}</div>
104
+ {description && <div className={s.description}>{description}</div>}
105
+ </div>
106
+ </Link>
107
+ </NavigationMenu.Link>
108
+ )
109
+ }
110
+
111
+ const IconSwitcher = ({
112
+ icon,
113
+ iconGradient,
114
+ }: {
115
+ icon: string
116
+ iconGradient: string
117
+ }) => {
118
+ switch (icon) {
119
+ case 'shield-alert':
120
+ return <Image src={ShieldAlertFill} alt="shield alert icon" />
121
+ case 'cloud':
122
+ return <Image src={CloudFill} alt="cloud icon" />
123
+ case 'layers':
124
+ return <Image src={LayersFill} alt="layers icon" />
125
+ case 'zap':
126
+ return <Image src={ZapFill} alt="zap icon" />
127
+ default:
128
+ return (
129
+ <FlightIcon
130
+ name={vercelSplit(icon)}
131
+ color={
132
+ iconGradient === 'ILM' || iconGradient === 'SLM'
133
+ ? 'var(--mds-color-foreground-high-contrast)'
134
+ : 'var(--mds-color-foreground-strong)'
135
+ }
136
+ />
137
+ )
138
+ }
139
+ }
@@ -0,0 +1,5 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M7.65568 0.0838368C7.87179 -0.0279456 8.1287 -0.0279456 8.34481 0.0838368L15.5948 3.83384C15.8439 3.96265 16.0002 4.21962 16.0002 4.5C16.0002 4.78038 15.8439 5.03735 15.5948 5.16616L8.34481 8.91616C8.1287 9.02795 7.87179 9.02795 7.65568 8.91616L0.405677 5.16616C0.156637 5.03735 0.000244137 4.78038 0.000244137 4.5C0.000244137 4.21962 0.156637 3.96265 0.405677 3.83384L7.65568 0.0838368Z" fill="#EFEFF1"/>
3
+ <path d="M0.0934554 10.8876C0.293553 10.5249 0.749771 10.3931 1.11245 10.5932L8.00014 14.3933L14.8878 10.5932C15.2505 10.3931 15.7067 10.5249 15.9068 10.8876C16.1069 11.2503 15.9751 11.7065 15.6124 11.9066L8.36245 15.9066C8.13693 16.031 7.86335 16.031 7.63783 15.9066L0.387831 11.9066C0.0251545 11.7065 -0.106642 11.2503 0.0934554 10.8876Z" fill="#EFEFF1"/>
4
+ <path d="M1.11245 7.09321C0.749771 6.89311 0.293553 7.02491 0.0934554 7.38759C-0.106642 7.75026 0.0251545 8.20648 0.387831 8.40658L7.63783 12.4066C7.86335 12.531 8.13693 12.531 8.36245 12.4066L15.6124 8.40658C15.9751 8.20648 16.1069 7.75026 15.9068 7.38759C15.7067 7.02491 15.2505 6.89311 14.8878 7.09321L8.00014 10.8933L1.11245 7.09321Z" fill="#EFEFF1"/>
5
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="14" height="16" viewBox="0 0 14 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M6.26074 0.125C6.73954 -0.0415734 7.26046 -0.0415732 7.73926 0.125L12.4893 1.77832C13.3937 2.09305 14 2.94572 14 3.90332V7.91211C13.9998 9.96031 12.8191 11.6595 11.5498 12.9033C10.2686 14.1588 8.79248 15.0539 7.97656 15.501C7.36496 15.8361 6.63504 15.8361 6.02344 15.501C5.20752 15.0539 3.7314 14.1588 2.4502 12.9033C1.18094 11.6595 0.00016175 9.96031 0 7.91211V3.90332C0 2.94572 0.606344 2.09305 1.51074 1.77832L6.26074 0.125ZM7 10C6.44772 10 6 10.4477 6 11C6.00004 11.5522 6.44774 12 7 12H7.00684C7.55902 11.9999 8.00679 11.5522 8.00684 11C8.00684 10.4478 7.55904 10.0001 7.00684 10H7ZM7 4C6.58579 4 6.25 4.33579 6.25 4.75V8.25C6.25004 8.66418 6.58581 9 7 9C7.41419 9 7.74996 8.66418 7.75 8.25C7.75 8.25 7.75 5.16452 7.75 4.75C7.75 4.33579 7.41421 4 7 4Z" fill="white"/>
3
+ </svg>
@@ -0,0 +1,64 @@
1
+ .linkList {
2
+ display: flex;
3
+ list-style: none;
4
+ flex-direction: column;
5
+ gap: var(--mds-spacing-03);
6
+ margin: 0;
7
+ padding: 0;
8
+ }
9
+
10
+ .link {
11
+ color: var(--mds-color-foreground-primary);
12
+ display: flex;
13
+ gap: var(--mds-spacing-04);
14
+ padding: var(--mds-spacing-03) var(--mds-spacing-05);
15
+ min-width: 190px;
16
+ align-items: flex-start;
17
+ height: 100%;
18
+
19
+ &:hover {
20
+ background-color: var(--mds-color-surface-interactive-hover);
21
+ border-radius: var(--mds-spacing-01);
22
+ }
23
+
24
+ &:has(.iconBackground) {
25
+ align-items: flex-start;
26
+ }
27
+
28
+ @media (--large) {
29
+ max-width: 416px;
30
+ }
31
+
32
+ &:focus {
33
+ outline: 2px solid var(--mds-color-focus-action-internal);
34
+ outline-style: auto;
35
+ }
36
+ }
37
+
38
+ .description {
39
+ font-size: var(--mds-typography-body-200-font-size);
40
+ font-weight: var(--mds-typography-font-weight-regular);
41
+ margin-top: var(--mds-spacing-02);
42
+ color: var(--mds-color-foreground-faint);
43
+ }
44
+
45
+ .iconBackground {
46
+ background: var(--iconBackground);
47
+ height: var(--mds-spacing-08);
48
+ width: var(--mds-spacing-08);
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ border-radius: 3px;
53
+ flex: none;
54
+ margin-top: 3px;
55
+ }
56
+
57
+ .boldTitle {
58
+ font-weight: var(--mds-typography-font-weight-semibold);
59
+ }
60
+
61
+ .iconWrapper {
62
+ margin-top: 3px;
63
+ height: fit-content;
64
+ }
@@ -0,0 +1,3 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M9.3747 0.078024C9.67891 0.228777 9.8439 0.565087 9.77695 0.897934L8.88834 5.31559L14.3726 6.22441C14.6414 6.26896 14.865 6.45581 14.9565 6.71247C15.048 6.96914 14.9931 7.25524 14.813 7.4598L7.52137 15.7455C7.29708 16.0004 6.92954 16.0728 6.62533 15.922C6.32112 15.7713 6.15612 15.435 6.22307 15.1021L7.11168 10.6845L1.6274 9.77566C1.35858 9.73111 1.13506 9.54426 1.04356 9.2876C0.952061 9.03093 1.00697 8.74483 1.18699 8.54027L8.47865 0.254555C8.70295 -0.000319332 9.07049 -0.0727287 9.3747 0.078024Z" fill="#EFEFF1"/>
3
+ </svg>
@@ -1,11 +1,8 @@
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'
5
- import * as NavigationMenu from '@radix-ui/react-navigation-menu'
1
+ import NavLink from '../link'
6
2
  import s from './style.module.css'
7
3
 
8
4
  export interface LinkListProps {
5
+ locale?: string
9
6
  links: {
10
7
  title: string
11
8
  url: string
@@ -16,70 +13,21 @@ export interface LinkListProps {
16
13
  linkClickHandler?: (title: string, url: string) => void
17
14
  }
18
15
 
19
- const GRADIENT_VALUE_MAP = new Map([
20
- [
21
- 'ILM',
22
- {
23
- iconGradient: 'var(--icon-gradient-infrastructure-lifecycle-management)',
24
- },
25
- ],
26
- [
27
- 'SLM',
28
- {
29
- iconGradient: 'var(--icon-gradient-security-lifecycle-management)',
30
- },
31
- ],
32
- [
33
- 'Cloud',
34
- {
35
- iconGradient: 'var(--icon-gradient-infrastructure-cloud)',
36
- },
37
- ],
38
- ])
39
-
40
- export default function LinkList({ links, linkClickHandler }: LinkListProps) {
16
+ export default function LinkList({
17
+ locale,
18
+ links,
19
+ linkClickHandler,
20
+ }: LinkListProps) {
41
21
  return (
42
22
  <ul className={s.linkList}>
43
23
  {links.map((link) => {
44
- let style
45
- link.iconGradient
46
- ? (style = {
47
- '--iconGradient': GRADIENT_VALUE_MAP.get(v(link.iconGradient))
48
- ?.iconGradient,
49
- } as React.CSSProperties)
50
- : (style = null)
51
24
  return (
52
25
  <li key={link.title}>
53
- <NavigationMenu.Link asChild>
54
- <Link
55
- className={s.link}
56
- href={parseUrl(link.url).href}
57
- onClickCapture={() => {
58
- linkClickHandler && linkClickHandler(link.title, link.url)
59
- }}
60
- >
61
- {link.iconGradient && link.icon ? (
62
- <div className={s.iconBackground} style={style}>
63
- <FlightIcon name={v(link.icon)} />
64
- </div>
65
- ) : (
66
- link.icon && (
67
- <FlightIcon
68
- name={v(link.icon)}
69
- color="var(--token-color-foreground-faint)"
70
- />
71
- )
72
- )}
73
- <div>
74
- <div className={link.iconGradient && s.boldTitle}>
75
- {link.title}
76
- </div>
77
- {link.description && (
78
- <div className={s.description}>{link.description}</div>
79
- )}
80
- </div>
81
- </Link>
82
- </NavigationMenu.Link>
26
+ <NavLink
27
+ {...link}
28
+ linkClickHandler={linkClickHandler}
29
+ locale={locale}
30
+ />
83
31
  </li>
84
32
  )
85
33
  })}
@@ -2,56 +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
  }
9
-
10
- .link {
11
- color: var(--token-color-foreground-primary);
12
- display: flex;
13
- gap: var(--hdsplus-spacing-04);
14
- padding: var(--hdsplus-spacing-03) var(--hdsplus-spacing-04);
15
- min-width: 190px;
16
- align-items: center;
17
-
18
- &:hover {
19
- background-color: var(--token-color-surface-interactive-hover);
20
- border-radius: var(--hdsplus-spacing-01);
21
- }
22
-
23
- &:has(.iconBackground) {
24
- align-items: flex-start;
25
- }
26
-
27
- @media (--large) {
28
- max-width: 416px;
29
- }
30
-
31
- &:focus {
32
- outline: 2px solid var(--token-color-focus-action-internal);
33
- outline-style: auto;
34
- }
35
- }
36
-
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);
41
- }
42
-
43
- .iconBackground {
44
- background: var(--iconGradient);
45
- height: var(--hdsplus-spacing-08);
46
- width: var(--hdsplus-spacing-08);
47
- display: flex;
48
- align-items: center;
49
- justify-content: center;
50
- border-radius: 3px;
51
- flex: none;
52
- margin-top: 3px;
53
- }
54
-
55
- .boldTitle {
56
- font-weight: var(--font-weight-semi-bold);
57
- }
@@ -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) {
@@ -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,15 +1,17 @@
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
14
+ titleLinkUrl?: string
13
15
  description: string
14
16
  linkUrl: string
15
17
  linkTitle: string
@@ -17,10 +19,13 @@ export interface PromoProps {
17
19
  icon?: string
18
20
  theme: string
19
21
  hasSidePanel?: boolean
22
+ isPromoOnTop?: boolean
20
23
  }
21
24
 
22
25
  export default function Promo({
26
+ locale,
23
27
  title,
28
+ titleLinkUrl,
24
29
  description,
25
30
  linkUrl,
26
31
  linkTitle,
@@ -28,6 +33,7 @@ export default function Promo({
28
33
  icon,
29
34
  theme,
30
35
  hasSidePanel,
36
+ isPromoOnTop = false,
31
37
  }: PromoProps) {
32
38
  const handleClick = useCallback((title, linkUrl, linkTitle, slug) => {
33
39
  if (window && window.analytics) {
@@ -46,33 +52,47 @@ export default function Promo({
46
52
  className={classNames(s.promo, {
47
53
  [s.hasSide]: hasSidePanel,
48
54
  [s.noSide]: !hasSidePanel,
55
+ [s.topPromo]: isPromoOnTop,
49
56
  })}
50
57
  >
51
58
  {icon && (
52
59
  <div
53
60
  className={classNames(s.icon, {
54
- [s.hashidays]: v(theme) === 'hashidays',
55
- [s.hashiconf]: v(theme) === 'hashiconf',
61
+ [s.hashidays]: vercelSplit(theme) === 'hashidays',
62
+ [s.hashiconf]: vercelSplit(theme) === 'hashiconf',
56
63
  })}
57
64
  >
58
- <FlightIcon name={v(icon)} />
65
+ <FlightIcon name={vercelSplit(icon)} size={24} />
59
66
  </div>
60
67
  )}
61
68
  <div className={s.rightContent}>
62
69
  <div>
63
- <div
64
- className={classNames(s.title, {
65
- [s.hashidays]: v(theme) === 'hashidays',
66
- [s.hashiconf]: v(theme) === 'hashiconf',
67
- })}
68
- >
69
- {title}
70
- </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
+ )}
71
90
  <div className={s.description}>{description}</div>
72
91
  </div>
73
92
  <NavigationMenu.Link asChild>
74
93
  <Link
75
- href={parseUrl(linkUrl).href}
94
+ locale={locale ? locale : undefined}
95
+ {...getLocalizedLinkProps(linkUrl, locale)}
76
96
  className={s.link}
77
97
  onClickCapture={() => handleClick(title, linkUrl, linkTitle, slug)}
78
98
  >