@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
package/.eslintrc.js CHANGED
@@ -1,4 +1,3 @@
1
1
  module.exports = {
2
- root: true,
3
- extends: require.resolve('@hashicorp/platform-cli/config/.eslintrc.js'),
2
+ /* Specify overrides here */
4
3
  }
package/.stylelintrc.js CHANGED
@@ -1,3 +1,3 @@
1
1
  module.exports = {
2
- extends: ['@hashicorp/platform-cli/config/stylelint.config']
2
+ extends: ['@hashicorp/platform-cli/config/stylelint.config'],
3
3
  }
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@hashicorp/react-components",
3
- "version": "0.0.0-nightly.ad81ac2",
3
+ "version": "0.0.0-nightly.b154bf4",
4
4
  "main": "src/index.ts",
5
5
  "scripts": {
6
6
  "lint": "next-hashicorp lint",
@@ -11,18 +11,13 @@
11
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-hds": "*",
15
- "@hashicorp/react-mds": "*",
16
14
  "@hashicorp/web-mktg-logos": "*",
17
15
  "@radix-ui/react-navigation-menu": "^1.2.0",
18
16
  "@radix-ui/react-visually-hidden": "^1.1.0",
19
- "@vercel/analytics": "^1.3.1",
20
17
  "@vercel/fetch": "^7.0.0",
21
18
  "@vercel/stega": "^0.1.2",
22
- "classnames": "^2.3.2",
23
- "js-cookie": "^3.0.5",
24
- "moize": "^6.1.3",
25
- "react-hook-form": "^7.43.5"
19
+ "posthog-js": "^1.195.0",
20
+ "classnames": "^2.3.2"
26
21
  },
27
22
  "devDependencies": {
28
23
  "@hashicorp/platform-cli": "^2.8.0",
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,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: inline-block;
3
+ }
@@ -0,0 +1,127 @@
1
+ import Link from 'next/link'
2
+ import classNames from 'classnames'
3
+ import { vercelSplit } from '../../../../lib/v'
4
+ import { getLocalizedLinkProps } from '../../../../lib/get-localized-link-props'
5
+ import FlightIcon from '../flight-icon'
6
+ import * as NavigationMenu from '@radix-ui/react-navigation-menu'
7
+ import s from './style.module.css'
8
+
9
+ interface NavLinkProps {
10
+ title: string
11
+ url: string
12
+ icon?: string
13
+ description?: string
14
+ iconGradient?: string
15
+ iconAppearance?: 'light' | 'dark'
16
+ linkClickHandler?: (title: string, url: string) => void
17
+ locale?: string
18
+ className?: string
19
+ }
20
+
21
+ const GRADIENT_VALUE_MAP = new Map([
22
+ [
23
+ 'ILM',
24
+ {
25
+ iconGradient: {
26
+ light: 'var(--icon-gradient-infrastructure-lifecycle-management)',
27
+ dark: 'var(--icon-gradient-infrastructure-lifecycle-management-dark)',
28
+ },
29
+ },
30
+ ],
31
+ [
32
+ 'SLM',
33
+ {
34
+ iconGradient: {
35
+ light: 'var(--icon-gradient-security-lifecycle-management)',
36
+ dark: 'var(--icon-gradient-security-lifecycle-management-dark)',
37
+ },
38
+ },
39
+ ],
40
+ [
41
+ 'Cloud',
42
+ {
43
+ iconGradient: {
44
+ light: 'var(--icon-gradient-infrastructure-cloud)',
45
+ dark: 'var(--icon-gradient-infrastructure-cloud-dark)',
46
+ },
47
+ },
48
+ ],
49
+ [
50
+ 'Black',
51
+ {
52
+ iconGradient: {
53
+ light: 'var(--token-color-surface-strong)',
54
+ dark: 'var(--token-color-surface-strong)',
55
+ },
56
+ },
57
+ ],
58
+ [
59
+ 'Solution Application',
60
+ {
61
+ iconGradient: {
62
+ light: 'var(--icon-gradient-surface-application)',
63
+ dark: 'var(--icon-gradient-surface-application-dark)',
64
+ },
65
+ },
66
+ ],
67
+ ])
68
+
69
+ export default function NavLink({
70
+ url,
71
+ title,
72
+ description,
73
+ icon,
74
+ iconGradient,
75
+ iconAppearance = 'light',
76
+ linkClickHandler,
77
+ locale,
78
+ className,
79
+ }: NavLinkProps) {
80
+ const style = iconGradient
81
+ ? {
82
+ ['--iconGradient' as string]: GRADIENT_VALUE_MAP.get(
83
+ vercelSplit(iconGradient)
84
+ )?.iconGradient[
85
+ vercelSplit(iconAppearance) === 'dark' ? 'dark' : 'light'
86
+ ],
87
+ }
88
+ : undefined
89
+
90
+ return (
91
+ <NavigationMenu.Link asChild>
92
+ <Link
93
+ className={classNames(s.link, className)}
94
+ {...getLocalizedLinkProps(url, locale)}
95
+ onClickCapture={() => {
96
+ linkClickHandler && linkClickHandler(title, url)
97
+ }}
98
+ >
99
+ {iconGradient && icon ? (
100
+ <div
101
+ className={s.iconBackground}
102
+ style={style}
103
+ data-theme={iconAppearance}
104
+ >
105
+ <FlightIcon
106
+ name={vercelSplit(icon)}
107
+ color="var(--token-color-foreground-strong)"
108
+ />
109
+ </div>
110
+ ) : (
111
+ icon && (
112
+ <div className={s.iconWrapper}>
113
+ <FlightIcon
114
+ name={vercelSplit(icon)}
115
+ color="var(--token-color-foreground-faint)"
116
+ />
117
+ </div>
118
+ )
119
+ )}
120
+ <div>
121
+ <div className={iconGradient && s.boldTitle}>{title}</div>
122
+ {description && <div className={s.description}>{description}</div>}
123
+ </div>
124
+ </Link>
125
+ </NavigationMenu.Link>
126
+ )
127
+ }
@@ -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(--token-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(--token-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(--token-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(--token-color-foreground-faint);
43
+ }
44
+
45
+ .iconBackground {
46
+ background: var(--iconGradient);
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
+ }
@@ -1,86 +1,34 @@
1
- import Link from 'next/link'
2
- import { parseUrl } from '../../../../lib/parse-url'
3
- import { vercelSplit } from '../../../../lib/v'
4
- import FlightIcon from '@hashicorp/react-hds/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
12
9
  icon?: string
13
10
  description?: string
14
11
  iconGradient?: string
12
+ iconAppearance?: 'light' | 'dark'
15
13
  }[]
16
14
  linkClickHandler?: (title: string, url: string) => void
17
15
  }
18
16
 
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) {
17
+ export default function LinkList({
18
+ locale,
19
+ links,
20
+ linkClickHandler,
21
+ }: LinkListProps) {
41
22
  return (
42
23
  <ul className={s.linkList}>
43
24
  {links.map((link) => {
44
- let style
45
- link.iconGradient
46
- ? (style = {
47
- '--iconGradient': GRADIENT_VALUE_MAP.get(
48
- vercelSplit(link.iconGradient)
49
- )?.iconGradient,
50
- } as React.CSSProperties)
51
- : (style = null)
52
25
  return (
53
26
  <li key={link.title}>
54
- <NavigationMenu.Link asChild>
55
- <Link
56
- className={s.link}
57
- href={parseUrl(link.url).href}
58
- onClickCapture={() => {
59
- linkClickHandler && linkClickHandler(link.title, link.url)
60
- }}
61
- >
62
- {link.iconGradient && link.icon ? (
63
- <div className={s.iconBackground} style={style}>
64
- <FlightIcon name={vercelSplit(link.icon)} />
65
- </div>
66
- ) : (
67
- link.icon && (
68
- <FlightIcon
69
- name={vercelSplit(link.icon)}
70
- color="var(--token-color-foreground-faint)"
71
- />
72
- )
73
- )}
74
- <div>
75
- <div className={link.iconGradient && s.boldTitle}>
76
- {link.title}
77
- </div>
78
- {link.description && (
79
- <div className={s.description}>{link.description}</div>
80
- )}
81
- </div>
82
- </Link>
83
- </NavigationMenu.Link>
27
+ <NavLink
28
+ {...link}
29
+ linkClickHandler={linkClickHandler}
30
+ locale={locale}
31
+ />
84
32
  </li>
85
33
  )
86
34
  })}
@@ -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
  }
@@ -2,14 +2,16 @@ import { useCallback } from 'react'
2
2
  import classNames from 'classnames'
3
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-hds/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,6 +52,7 @@ 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 && (
@@ -60,19 +67,32 @@ export default function Promo({
60
67
  )}
61
68
  <div className={s.rightContent}>
62
69
  <div>
63
- <div
64
- className={classNames(s.title, {
65
- [s.hashidays]: vercelSplit(theme) === 'hashidays',
66
- [s.hashiconf]: vercelSplit(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
  >
@@ -2,17 +2,20 @@
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) var(--mds-spacing-06)
9
+ 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,7 +24,14 @@
21
24
  }
22
25
 
23
26
  @media (--dev-dot-viewport) {
27
+ &.topPromo {
28
+ margin-bottom: var(--mds-spacing-05);
29
+ }
24
30
  &.hasSide {
31
+ &.topPromo {
32
+ margin-bottom: var(--mds-spacing-05);
33
+ }
34
+
25
35
  margin: 0;
26
36
  width: min-content;
27
37
  min-width: 100%;
@@ -29,22 +39,26 @@
29
39
  }
30
40
  }
31
41
 
42
+ .topPromo {
43
+ margin-bottom: 0;
44
+ }
45
+
32
46
  .rightContent {
33
47
  display: flex;
34
48
  flex-wrap: wrap;
35
- gap: var(--hdsplus-spacing-03);
49
+ gap: var(--mds-spacing-03);
36
50
  width: 100%;
37
51
  justify-content: space-between;
38
52
  }
39
53
 
40
54
  .title {
41
- font-weight: var(--font-weight-semi-bold);
55
+ font-weight: var(--mds-typography-font-weight-semibold);
42
56
  }
43
57
 
44
58
  .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);
59
+ font-size: var(--mds-typography-body-200-font-size);
60
+ font-weight: var(--mds-typography-font-weight-regular);
61
+ margin-top: var(--mds-spacing-01);
48
62
  }
49
63
 
50
64
  .icon {
@@ -70,7 +84,7 @@
70
84
  display: flex;
71
85
  flex-direction: row;
72
86
  align-items: center;
73
- gap: var(--hdsplus-spacing-02);
87
+ gap: var(--mds-spacing-02);
74
88
 
75
89
  &:hover {
76
90
  text-decoration: underline;