@hashicorp/react-components 0.0.0-canary.57d393c → 0.0.0-canary.60e6118

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 (166) hide show
  1. package/package.json +9 -10
  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 +94 -0
  5. package/src/components/nav-panel/components/link-list/style.module.css +57 -0
  6. package/src/components/nav-panel/components/panel/column/index.tsx +24 -0
  7. package/src/components/nav-panel/components/panel/column/style.module.css +24 -0
  8. package/src/components/nav-panel/components/panel/index.tsx +4 -0
  9. package/src/components/nav-panel/components/panel/root/index.tsx +20 -0
  10. package/src/components/nav-panel/components/panel/root/style.module.css +30 -0
  11. package/src/components/nav-panel/components/promo/index.tsx +92 -0
  12. package/src/components/nav-panel/components/promo/style.module.css +128 -0
  13. package/src/components/nav-panel/components/text/index.tsx +34 -0
  14. package/src/components/nav-panel/index.tsx +6 -0
  15. package/src/components/nav-panel/product-panel/index.tsx +185 -0
  16. package/src/components/nav-panel/product-panel/style.module.css +353 -0
  17. package/src/components/nav-panel/standard-panel/index.tsx +47 -0
  18. package/src/components/nav-panel/standard-panel/style.module.css +11 -0
  19. package/src/lib/get-localized-link-props/index.test.ts +30 -0
  20. package/src/lib/get-localized-link-props/index.ts +45 -0
  21. package/src/lib/parse-url/index.test.ts +69 -0
  22. package/src/lib/parse-url/index.ts +98 -0
  23. package/src/lib/send-posthog-event/index.ts +22 -0
  24. package/src/lib/supported-locales/index.ts +1 -0
  25. package/src/lib/track-nav-click-event/index.ts +22 -0
  26. package/src/lib/v/index.ts +10 -0
  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 -176
  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 -37
  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.tsx +0 -64
  55. package/src/components/consent-manager/README.md +0 -73
  56. package/src/components/consent-manager/components/banner/banner.module.css +0 -23
  57. package/src/components/consent-manager/components/banner/banner.test.tsx +0 -31
  58. package/src/components/consent-manager/components/banner/banner.tsx +0 -73
  59. package/src/components/consent-manager/components/dialog/dialog.module.css +0 -145
  60. package/src/components/consent-manager/components/dialog/dialog.test.tsx +0 -194
  61. package/src/components/consent-manager/components/dialog/dialog.tsx +0 -339
  62. package/src/components/consent-manager/img/icn_close.tsx +0 -19
  63. package/src/components/consent-manager/index.test.tsx +0 -334
  64. package/src/components/consent-manager/index.tsx +0 -186
  65. package/src/components/consent-manager/loader/README.md +0 -29
  66. package/src/components/consent-manager/loader/categories.ts +0 -22
  67. package/src/components/consent-manager/loader/index.tsx +0 -94
  68. package/src/components/consent-manager/loader/presets/enterprise.ts +0 -12
  69. package/src/components/consent-manager/loader/presets/oss.ts +0 -10
  70. package/src/components/consent-manager/loader/services.ts +0 -45
  71. package/src/components/consent-manager/scripts/custom.tsx +0 -59
  72. package/src/components/consent-manager/scripts/segment.tsx +0 -87
  73. package/src/components/consent-manager/style.module.css +0 -9
  74. package/src/components/consent-manager/types.ts +0 -55
  75. package/src/components/consent-manager/util/cookies.test.ts +0 -75
  76. package/src/components/consent-manager/util/cookies.ts +0 -70
  77. package/src/components/consent-manager/util/integrations.test.ts +0 -115
  78. package/src/components/consent-manager/util/integrations.ts +0 -110
  79. package/src/components/intro/index.tsx +0 -82
  80. package/src/components/intro/style.module.css +0 -67
  81. package/src/components/intro/types.ts +0 -44
  82. package/src/components/marketo-form/CHANGELOG.md +0 -122
  83. package/src/components/marketo-form/README.md +0 -1
  84. package/src/components/marketo-form/contexts/FormMetadata.ts +0 -11
  85. package/src/components/marketo-form/docs.mdx +0 -197
  86. package/src/components/marketo-form/fixtures/index.ts +0 -185
  87. package/src/components/marketo-form/form/index.tsx +0 -369
  88. package/src/components/marketo-form/index.test.tsx +0 -320
  89. package/src/components/marketo-form/index.ts +0 -11
  90. package/src/components/marketo-form/package.original.json +0 -30
  91. package/src/components/marketo-form/partials/error-message/index.tsx +0 -12
  92. package/src/components/marketo-form/partials/error-message/style.module.css +0 -13
  93. package/src/components/marketo-form/partials/field/index.tsx +0 -90
  94. package/src/components/marketo-form/partials/field-wrapper/index.tsx +0 -26
  95. package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +0 -32
  96. package/src/components/marketo-form/partials/fields/email-field/index.tsx +0 -35
  97. package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +0 -21
  98. package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +0 -37
  99. package/src/components/marketo-form/partials/fields/htmltext-field/index.tsx +0 -21
  100. package/src/components/marketo-form/partials/fields/htmltext-field/style.module.css +0 -6
  101. package/src/components/marketo-form/partials/fields/name-field/index.tsx +0 -19
  102. package/src/components/marketo-form/partials/fields/name-field/style.module.css +0 -13
  103. package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +0 -48
  104. package/src/components/marketo-form/partials/fields/select-field/index.tsx +0 -39
  105. package/src/components/marketo-form/partials/fields/select-field/style.module.css +0 -5
  106. package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +0 -30
  107. package/src/components/marketo-form/partials/fields/text-field/index.tsx +0 -30
  108. package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +0 -29
  109. package/src/components/marketo-form/partials/label/index.tsx +0 -24
  110. package/src/components/marketo-form/partials/label/style.module.css +0 -12
  111. package/src/components/marketo-form/partials/visibility-rule/index.tsx +0 -84
  112. package/src/components/marketo-form/props.js +0 -66
  113. package/src/components/marketo-form/server/api-routes.ts +0 -109
  114. package/src/components/marketo-form/server/client.ts +0 -98
  115. package/src/components/marketo-form/server/index.ts +0 -8
  116. package/src/components/marketo-form/types.ts +0 -268
  117. package/src/components/marketo-form/utils.test.tsx +0 -103
  118. package/src/components/marketo-form/utils.ts +0 -445
  119. package/src/components/next-steps/index.tsx +0 -143
  120. package/src/components/next-steps/style.module.css +0 -270
  121. package/src/components/next-steps/types.ts +0 -63
  122. package/src/components/product-badge/index.test.tsx +0 -11
  123. package/src/components/product-badge/index.tsx +0 -42
  124. package/src/components/product-badge/style.module.css +0 -76
  125. package/src/components/products-used/index.tsx +0 -84
  126. package/src/components/products-used/style.module.css +0 -87
  127. package/src/components/products-used/types.ts +0 -31
  128. package/src/components/related-content/index.test.tsx +0 -74
  129. package/src/components/related-content/index.tsx +0 -56
  130. package/src/components/related-content/style.module.css +0 -89
  131. package/src/components/related-content/types.ts +0 -21
  132. package/src/components/subnav/helpers/areBasePathsMatching.ts +0 -13
  133. package/src/components/subnav/helpers/traverse/index.ts +0 -42
  134. package/src/components/subnav/helpers/useHeightRef.ts +0 -42
  135. package/src/components/subnav/helpers/useNavRef.ts +0 -30
  136. package/src/components/subnav/helpers/useOverflowRef.ts +0 -85
  137. package/src/components/subnav/helpers/useStuckRef.ts +0 -51
  138. package/src/components/subnav/index.tsx +0 -199
  139. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.test.ts +0 -26
  140. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.ts +0 -22
  141. package/src/components/subnav/partials/CtaLinks/github-stars-link/index.tsx +0 -87
  142. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.test.ts +0 -29
  143. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.ts +0 -32
  144. package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +0 -85
  145. package/src/components/subnav/partials/CtaLinks/icons/github-logo.js +0 -20
  146. package/src/components/subnav/partials/CtaLinks/icons/github.svg.js +0 -7
  147. package/src/components/subnav/partials/CtaLinks/icons/star.js +0 -20
  148. package/src/components/subnav/partials/CtaLinks/index.tsx +0 -131
  149. package/src/components/subnav/partials/CtaLinks/style.module.css +0 -45
  150. package/src/components/subnav/partials/DropdownTrigger/index.tsx +0 -35
  151. package/src/components/subnav/partials/DropdownTrigger/style.module.css +0 -36
  152. package/src/components/subnav/partials/MenuItemsDefault/index.tsx +0 -151
  153. package/src/components/subnav/partials/MenuItemsDefault/style.module.css +0 -91
  154. package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +0 -139
  155. package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +0 -82
  156. package/src/components/subnav/partials/TitleLink/index.tsx +0 -113
  157. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +0 -9
  158. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +0 -9
  159. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-dark.ts +0 -23
  160. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-light.ts +0 -23
  161. package/src/components/subnav/partials/TitleLink/style.module.css +0 -43
  162. package/src/components/subnav/partials/nav-item-text/index.tsx +0 -37
  163. package/src/components/subnav/partials/nav-item-text/style.module.css +0 -15
  164. package/src/components/subnav/style.module.css +0 -68
  165. package/src/components/subnav/subnav-consts.ts +0 -1
  166. 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-canary.57d393c",
3
+ "version": "0.0.0-canary.60e6118",
4
4
  "main": "src/index.ts",
5
5
  "scripts": {
6
6
  "lint": "next-hashicorp lint",
@@ -8,20 +8,19 @@
8
8
  "test:watch": "vitest watch"
9
9
  },
10
10
  "dependencies": {
11
- "@hashicorp/flight-icons": "^2.15.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
- "@radix-ui/react-visually-hidden": "^1.0.3",
14
+ "@hashicorp/web-mktg-logos": "*",
15
+ "@radix-ui/react-navigation-menu": "^1.2.0",
16
+ "@radix-ui/react-visually-hidden": "^1.1.0",
16
17
  "@vercel/fetch": "^7.0.0",
17
- "@web/mktg-logos": "*",
18
- "classnames": "^2.3.2",
19
- "js-cookie": "^3.0.5",
20
- "moize": "^6.1.3",
21
- "react-hook-form": "^7.43.5"
18
+ "@vercel/stega": "^0.1.2",
19
+ "posthog-js": "^1.195.0",
20
+ "classnames": "^2.3.2"
22
21
  },
23
22
  "devDependencies": {
24
- "@hashicorp/platform-cli": "^2.6.0",
23
+ "@hashicorp/platform-cli": "^2.8.0",
25
24
  "@hashicorp/platform-types": "^0.4.0",
26
25
  "@testing-library/jest-dom": "^6.4.2",
27
26
  "@vitejs/plugin-react": "^4.2.1",
@@ -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
+ }
@@ -0,0 +1,94 @@
1
+ import Link from 'next/link'
2
+ import { vercelSplit } from '../../../../lib/v'
3
+ import { getLocalizedLinkProps } from '../../../../lib/get-localized-link-props'
4
+ import FlightIcon from '../flight-icon'
5
+ import * as NavigationMenu from '@radix-ui/react-navigation-menu'
6
+ import s from './style.module.css'
7
+
8
+ export interface LinkListProps {
9
+ locale?: string
10
+ links: {
11
+ title: string
12
+ url: string
13
+ icon?: string
14
+ description?: string
15
+ iconGradient?: string
16
+ }[]
17
+ linkClickHandler?: (title: string, url: string) => void
18
+ }
19
+
20
+ const GRADIENT_VALUE_MAP = new Map([
21
+ [
22
+ 'ILM',
23
+ {
24
+ iconGradient: 'var(--icon-gradient-infrastructure-lifecycle-management)',
25
+ },
26
+ ],
27
+ [
28
+ 'SLM',
29
+ {
30
+ iconGradient: 'var(--icon-gradient-security-lifecycle-management)',
31
+ },
32
+ ],
33
+ [
34
+ 'Cloud',
35
+ {
36
+ iconGradient: 'var(--icon-gradient-infrastructure-cloud)',
37
+ },
38
+ ],
39
+ ])
40
+
41
+ export default function LinkList({
42
+ locale,
43
+ links,
44
+ linkClickHandler,
45
+ }: LinkListProps) {
46
+ return (
47
+ <ul className={s.linkList}>
48
+ {links.map((link) => {
49
+ let style
50
+ link.iconGradient
51
+ ? (style = {
52
+ '--iconGradient': GRADIENT_VALUE_MAP.get(
53
+ vercelSplit(link.iconGradient)
54
+ )?.iconGradient,
55
+ } as React.CSSProperties)
56
+ : (style = null)
57
+ return (
58
+ <li key={link.title}>
59
+ <NavigationMenu.Link asChild>
60
+ <Link
61
+ className={s.link}
62
+ {...getLocalizedLinkProps(link.url, locale)}
63
+ onClickCapture={() => {
64
+ linkClickHandler && linkClickHandler(link.title, link.url)
65
+ }}
66
+ >
67
+ {link.iconGradient && link.icon ? (
68
+ <div className={s.iconBackground} style={style}>
69
+ <FlightIcon name={vercelSplit(link.icon)} />
70
+ </div>
71
+ ) : (
72
+ link.icon && (
73
+ <FlightIcon
74
+ name={vercelSplit(link.icon)}
75
+ color="var(--token-color-foreground-faint)"
76
+ />
77
+ )
78
+ )}
79
+ <div>
80
+ <div className={link.iconGradient && s.boldTitle}>
81
+ {link.title}
82
+ </div>
83
+ {link.description && (
84
+ <div className={s.description}>{link.description}</div>
85
+ )}
86
+ </div>
87
+ </Link>
88
+ </NavigationMenu.Link>
89
+ </li>
90
+ )
91
+ })}
92
+ </ul>
93
+ )
94
+ }
@@ -0,0 +1,57 @@
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-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(--mds-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(--mds-typography-body-200-font-size);
39
+ font-weight: var(--mds-typography-font-weight-regular);
40
+ margin-top: var(--mds-spacing-02);
41
+ }
42
+
43
+ .iconBackground {
44
+ background: var(--iconGradient);
45
+ height: var(--mds-spacing-08);
46
+ width: var(--mds-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(--mds-typography-font-weight-semibold);
57
+ }
@@ -0,0 +1,24 @@
1
+ import classNames from 'classnames'
2
+ import s from './style.module.css'
3
+
4
+ export interface NavColumnProps {
5
+ className?: string
6
+ children: React.ReactNode
7
+ hasSidePanel?: boolean
8
+ }
9
+
10
+ export default function Column({
11
+ className,
12
+ children,
13
+ hasSidePanel,
14
+ }: NavColumnProps) {
15
+ return (
16
+ <div
17
+ className={classNames(s.column, className, {
18
+ [s.hasSide]: hasSidePanel,
19
+ })}
20
+ >
21
+ {children}
22
+ </div>
23
+ )
24
+ }
@@ -0,0 +1,24 @@
1
+ @custom-media --dev-dot-viewport (min-width: 924px);
2
+
3
+ .column {
4
+ position: relative;
5
+ display: flex;
6
+ flex-direction: column;
7
+ justify-content: flex-start;
8
+ min-width: 190px;
9
+ padding: 0;
10
+ margin: 0 var(--mds-spacing-07);
11
+ border-radius: var(--mds-spacing-03);
12
+
13
+ @media (--large) {
14
+ &:not(.hasSide) {
15
+ margin: 0;
16
+ }
17
+ }
18
+
19
+ @media (--dev-dot-viewport) {
20
+ &.hasSide {
21
+ margin: 0;
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,4 @@
1
+ import Root from './root'
2
+ import Column from './column'
3
+
4
+ export { Root, Column }
@@ -0,0 +1,20 @@
1
+ import classNames from 'classnames'
2
+ import s from './style.module.css'
3
+
4
+ interface RootProps {
5
+ className?: string
6
+ children: React.ReactNode
7
+ hasSidePanel?: boolean
8
+ }
9
+
10
+ export default function Root({ className, children, hasSidePanel }: RootProps) {
11
+ return (
12
+ <div
13
+ className={classNames(s.root, className, {
14
+ [s.hasSide]: hasSidePanel,
15
+ })}
16
+ >
17
+ {children}
18
+ </div>
19
+ )
20
+ }
@@ -0,0 +1,30 @@
1
+ @custom-media --dev-dot-viewport (min-width: 924px);
2
+
3
+ .root {
4
+ width: 100%;
5
+ display: flex;
6
+ flex-direction: column;
7
+ justify-content: space-between;
8
+ /* stylelint-disable-next-line unit-no-unknown */
9
+ min-height: calc(100dvh - var(--mds-spacing-12));
10
+
11
+ @media (--large) {
12
+ &:not(.hasSide) {
13
+ justify-content: flex-start;
14
+ height: 100%;
15
+ min-height: fit-content;
16
+ padding: var(--mds-spacing-05) var(--mds-spacing-04);
17
+ gap: var(--mds-spacing-04);
18
+ }
19
+ }
20
+
21
+ @media (--dev-dot-viewport) {
22
+ &.hasSide {
23
+ justify-content: flex-start;
24
+ height: 100%;
25
+ min-height: fit-content;
26
+ padding: var(--mds-spacing-05) var(--mds-spacing-04);
27
+ gap: var(--mds-spacing-04);
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,92 @@
1
+ import { useCallback } from 'react'
2
+ import classNames from 'classnames'
3
+ import { vercelSplit } from '../../../../lib/v'
4
+ import Link from 'next/link'
5
+ import { getLocalizedLinkProps } from '../../../../lib/get-localized-link-props'
6
+ import { trackNavClickEvent } from '../../../../lib/track-nav-click-event'
7
+ import FlightIcon from '../flight-icon'
8
+ import * as NavigationMenu from '@radix-ui/react-navigation-menu'
9
+ import s from './style.module.css'
10
+
11
+ export interface PromoProps {
12
+ locale?: string
13
+ title: string
14
+ description: string
15
+ linkUrl: string
16
+ linkTitle: string
17
+ slug?: string
18
+ icon?: string
19
+ theme: string
20
+ hasSidePanel?: boolean
21
+ isPromoOnTop?: boolean
22
+ }
23
+
24
+ export default function Promo({
25
+ locale,
26
+ title,
27
+ description,
28
+ linkUrl,
29
+ linkTitle,
30
+ slug,
31
+ icon,
32
+ theme,
33
+ hasSidePanel,
34
+ isPromoOnTop = false,
35
+ }: PromoProps) {
36
+ const handleClick = useCallback((title, linkUrl, linkTitle, slug) => {
37
+ if (window && window.analytics) {
38
+ window.analytics.track('Nav Promo', {
39
+ url: linkUrl,
40
+ title: title,
41
+ callout: linkTitle,
42
+ })
43
+
44
+ trackNavClickEvent(title, linkUrl, slug)
45
+ }
46
+ }, [])
47
+
48
+ return (
49
+ <div
50
+ className={classNames(s.promo, {
51
+ [s.hasSide]: hasSidePanel,
52
+ [s.noSide]: !hasSidePanel,
53
+ [s.topPromo]: isPromoOnTop,
54
+ })}
55
+ >
56
+ {icon && (
57
+ <div
58
+ className={classNames(s.icon, {
59
+ [s.hashidays]: vercelSplit(theme) === 'hashidays',
60
+ [s.hashiconf]: vercelSplit(theme) === 'hashiconf',
61
+ })}
62
+ >
63
+ <FlightIcon name={vercelSplit(icon)} />
64
+ </div>
65
+ )}
66
+ <div className={s.rightContent}>
67
+ <div>
68
+ <div
69
+ className={classNames(s.title, {
70
+ [s.hashidays]: vercelSplit(theme) === 'hashidays',
71
+ [s.hashiconf]: vercelSplit(theme) === 'hashiconf',
72
+ })}
73
+ >
74
+ {title}
75
+ </div>
76
+ <div className={s.description}>{description}</div>
77
+ </div>
78
+ <NavigationMenu.Link asChild>
79
+ <Link
80
+ locale={locale ? locale : undefined}
81
+ {...getLocalizedLinkProps(linkUrl, locale)}
82
+ className={s.link}
83
+ onClickCapture={() => handleClick(title, linkUrl, linkTitle, slug)}
84
+ >
85
+ {linkTitle}
86
+ <FlightIcon name="external-link" />
87
+ </Link>
88
+ </NavigationMenu.Link>
89
+ </div>
90
+ </div>
91
+ )
92
+ }
@@ -0,0 +1,128 @@
1
+ @custom-media --dev-dot-viewport (min-width: 924px);
2
+
3
+ .promo {
4
+ display: flex;
5
+ border-radius: var(--mds-spacing-01);
6
+ border: 1px solid var(--token-color-border-faint);
7
+ background-color: var(--token-color-surface-faint);
8
+ padding: var(--mds-spacing-05) var(--mds-spacing-08) var(--mds-spacing-06)
9
+ var(--mds-spacing-08);
10
+ flex-direction: row;
11
+ gap: var(--mds-spacing-04);
12
+ margin: var(--mds-spacing-07);
13
+ margin-bottom: var(--mds-spacing-09);
14
+
15
+ @media (--large) {
16
+ &.topPromo {
17
+ margin-bottom: var(--mds-spacing-05);
18
+ }
19
+ &.noSide {
20
+ margin: 0;
21
+ width: min-content;
22
+ min-width: 100%;
23
+ }
24
+ }
25
+
26
+ @media (--dev-dot-viewport) {
27
+ &.topPromo {
28
+ margin-bottom: var(--mds-spacing-05);
29
+ }
30
+ &.hasSide {
31
+ &.topPromo {
32
+ margin-bottom: var(--mds-spacing-05);
33
+ }
34
+
35
+ margin: 0;
36
+ width: min-content;
37
+ min-width: 100%;
38
+ }
39
+ }
40
+ }
41
+
42
+ .topPromo {
43
+ margin-bottom: 0;
44
+ }
45
+
46
+ .rightContent {
47
+ display: flex;
48
+ flex-wrap: wrap;
49
+ gap: var(--mds-spacing-03);
50
+ width: 100%;
51
+ justify-content: space-between;
52
+ }
53
+
54
+ .title {
55
+ font-weight: var(--mds-typography-font-weight-semibold);
56
+ }
57
+
58
+ .description {
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);
62
+ }
63
+
64
+ .icon {
65
+ display: none;
66
+
67
+ @media (--large) {
68
+ @nest .noSide & {
69
+ display: block;
70
+ margin-top: 3px;
71
+ }
72
+ }
73
+
74
+ @media (--dev-dot-viewport) {
75
+ @nest .hasSide & {
76
+ display: block;
77
+ margin-top: 6px;
78
+ }
79
+ }
80
+ }
81
+
82
+ .link {
83
+ color: var(--token-color-foreground-strong);
84
+ display: flex;
85
+ flex-direction: row;
86
+ align-items: center;
87
+ gap: var(--mds-spacing-02);
88
+
89
+ &:hover {
90
+ text-decoration: underline;
91
+ }
92
+
93
+ &:focus {
94
+ outline: 2px solid var(--token-color-focus-action-internal);
95
+ outline-style: auto;
96
+ }
97
+ }
98
+
99
+ .hashidays {
100
+ background: linear-gradient(
101
+ 90deg,
102
+ #7b54b6 0%,
103
+ #4c69d8 74.77%,
104
+ #60d0dc 115.93%
105
+ );
106
+ -webkit-background-clip: text;
107
+ -webkit-text-fill-color: transparent;
108
+ max-width: fit-content;
109
+
110
+ & svg {
111
+ color: #7956b9;
112
+ }
113
+ }
114
+
115
+ .hashiconf {
116
+ background: linear-gradient(
117
+ to right,
118
+ var(--token-color-terraform-foreground),
119
+ var(--token-color-vagrant-foreground)
120
+ );
121
+ -webkit-background-clip: text;
122
+ -webkit-text-fill-color: transparent;
123
+ max-width: fit-content;
124
+
125
+ & svg {
126
+ color: var(--token-color-terraform-foreground);
127
+ }
128
+ }
@@ -0,0 +1,34 @@
1
+ import classNames from 'classnames'
2
+ import { type ReactNode, type HTMLAttributes } from 'react'
3
+
4
+ type TextSize = '200' | '300' | '400'
5
+ type TextWeight = 'regular' | 'medium' | 'semibold' | 'bold'
6
+
7
+ interface TextProps extends HTMLAttributes<HTMLSpanElement> {
8
+ size?: TextSize
9
+ weight?: TextWeight
10
+ children: ReactNode
11
+ }
12
+
13
+ const Text = ({
14
+ size = '300',
15
+ weight,
16
+ children,
17
+ className,
18
+ ...rest
19
+ }: TextProps) => {
20
+ return (
21
+ <span
22
+ className={classNames(
23
+ `mds-typography-body-${size}`,
24
+ weight && `mds-typography-font-weight-${weight}`,
25
+ className
26
+ )}
27
+ {...rest}
28
+ >
29
+ {children}
30
+ </span>
31
+ )
32
+ }
33
+
34
+ export { Text }
@@ -0,0 +1,6 @@
1
+ import ProductPanel, { type NavProductProps } from './product-panel'
2
+ import StandardPanel, { type NavItem } from './standard-panel'
3
+ import { PromoProps } from './components/promo'
4
+
5
+ export { ProductPanel, StandardPanel }
6
+ export type { NavProductProps, PromoProps, NavItem }