@hashicorp/react-components 0.0.0-nightly.8df4a87 → 0.0.0-nightly.91abcef

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 (90) hide show
  1. package/package.json +10 -6
  2. package/src/components/actions/index.tsx +5 -5
  3. package/src/components/call-to-action/index.tsx +7 -7
  4. package/src/components/card/index.test.tsx +1 -1
  5. package/src/components/card/newsroom-card/index.test.tsx +1 -1
  6. package/src/components/card/partner-card/index.tsx +3 -3
  7. package/src/components/card/person-card/index.tsx +1 -1
  8. package/src/components/card/primitives.tsx +16 -15
  9. package/src/components/card/resource-card/index.test.tsx +1 -1
  10. package/src/components/card/resource-card/index.tsx +3 -0
  11. package/src/components/card/types.ts +2 -2
  12. package/src/components/card/unified-card/index.spec.tsx +40 -0
  13. package/src/components/card/unified-card/index.tsx +5 -11
  14. package/src/components/marketo-form/contexts/FormMetadata.ts +2 -0
  15. package/src/components/marketo-form/form/index.tsx +4 -2
  16. package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +1 -1
  17. package/src/components/marketo-form/partials/fields/email-field/index.tsx +1 -1
  18. package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +12 -1
  19. package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +1 -0
  20. package/src/components/marketo-form/partials/fields/htmltext-field/style.module.css +16 -4
  21. package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +1 -1
  22. package/src/components/marketo-form/partials/fields/select-field/index.tsx +1 -1
  23. package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +1 -1
  24. package/src/components/marketo-form/partials/fields/text-field/index.tsx +1 -1
  25. package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +1 -1
  26. package/src/components/marketo-form/types.ts +5 -11
  27. package/src/components/marketo-form/utils.ts +4 -0
  28. package/src/components/nav-panel/components/link-list/index.tsx +16 -10
  29. package/src/components/nav-panel/components/panel/column/index.tsx +17 -2
  30. package/src/components/nav-panel/components/panel/column/style.module.css +12 -2
  31. package/src/components/nav-panel/components/panel/root/index.tsx +13 -2
  32. package/src/components/nav-panel/components/panel/root/style.module.css +19 -4
  33. package/src/components/nav-panel/components/promo/index.tsx +23 -13
  34. package/src/components/nav-panel/components/promo/style.module.css +28 -6
  35. package/src/components/nav-panel/product-panel/index.tsx +114 -32
  36. package/src/components/nav-panel/product-panel/style.module.css +230 -15
  37. package/src/components/nav-panel/standard-panel/index.tsx +4 -1
  38. package/src/components/nav-panel/standard-panel/style.module.css +1 -1
  39. package/src/components/next-steps/index.tsx +7 -12
  40. package/src/components/product-badge/index.tsx +1 -1
  41. package/src/components/subnav/index.tsx +18 -8
  42. package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +8 -12
  43. package/src/components/subnav/partials/CtaLinks/index.tsx +10 -9
  44. package/src/components/subnav/partials/CtaLinks/style.module.css +4 -4
  45. package/src/components/subnav/partials/DropdownTrigger/index.tsx +3 -3
  46. package/src/components/subnav/partials/DropdownTrigger/style.module.css +7 -4
  47. package/src/components/subnav/partials/MenuItemsDefault/index.tsx +31 -9
  48. package/src/components/subnav/partials/MenuItemsDefault/style.module.css +37 -24
  49. package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +21 -5
  50. package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +22 -16
  51. package/src/components/subnav/partials/TitleLink/index.tsx +14 -12
  52. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +9 -8
  53. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +9 -8
  54. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-dark.ts +10 -10
  55. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-light.ts +10 -10
  56. package/src/components/subnav/partials/TitleLink/style.module.css +1 -1
  57. package/src/components/subnav/partials/nav-item-text/style.module.css +2 -4
  58. package/src/components/subnav/style.module.css +4 -6
  59. package/src/lib/get-localized-link-props/index.test.ts +30 -0
  60. package/src/lib/get-localized-link-props/index.ts +46 -0
  61. package/src/lib/parse-url/index.test.ts +69 -0
  62. package/src/lib/parse-url/index.ts +104 -0
  63. package/src/lib/supported-locales/index.ts +1 -0
  64. package/src/lib/track-nav-click-event/index.ts +22 -0
  65. package/src/lib/v/index.ts +10 -0
  66. package/src/components/consent-manager/README.md +0 -73
  67. package/src/components/consent-manager/components/banner/banner.module.css +0 -23
  68. package/src/components/consent-manager/components/banner/banner.test.tsx +0 -31
  69. package/src/components/consent-manager/components/banner/banner.tsx +0 -73
  70. package/src/components/consent-manager/components/dialog/dialog.module.css +0 -145
  71. package/src/components/consent-manager/components/dialog/dialog.test.tsx +0 -194
  72. package/src/components/consent-manager/components/dialog/dialog.tsx +0 -339
  73. package/src/components/consent-manager/img/icn_close.tsx +0 -19
  74. package/src/components/consent-manager/index.test.tsx +0 -334
  75. package/src/components/consent-manager/index.tsx +0 -186
  76. package/src/components/consent-manager/loader/README.md +0 -29
  77. package/src/components/consent-manager/loader/categories.ts +0 -22
  78. package/src/components/consent-manager/loader/index.tsx +0 -94
  79. package/src/components/consent-manager/loader/presets/enterprise.ts +0 -12
  80. package/src/components/consent-manager/loader/presets/oss.ts +0 -10
  81. package/src/components/consent-manager/loader/services.ts +0 -45
  82. package/src/components/consent-manager/scripts/custom.tsx +0 -59
  83. package/src/components/consent-manager/scripts/segment.tsx +0 -87
  84. package/src/components/consent-manager/style.module.css +0 -9
  85. package/src/components/consent-manager/types.ts +0 -55
  86. package/src/components/consent-manager/util/cookies.test.ts +0 -75
  87. package/src/components/consent-manager/util/cookies.ts +0 -70
  88. package/src/components/consent-manager/util/integrations.test.ts +0 -115
  89. package/src/components/consent-manager/util/integrations.ts +0 -110
  90. package/src/components/subnav/theme.module.css +0 -50
@@ -1,9 +1,24 @@
1
+ import classNames from 'classnames'
1
2
  import s from './style.module.css'
2
3
 
3
4
  export interface NavColumnProps {
5
+ className?: string
4
6
  children: React.ReactNode
7
+ hasSidePanel?: boolean
5
8
  }
6
9
 
7
- export default function Column({ children }: NavColumnProps) {
8
- return <div className={s.column}>{children}</div>
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
+ )
9
24
  }
@@ -1,3 +1,5 @@
1
+ @custom-media --dev-dot-viewport (min-width: 924px);
2
+
1
3
  .column {
2
4
  position: relative;
3
5
  display: flex;
@@ -5,10 +7,18 @@
5
7
  justify-content: flex-start;
6
8
  min-width: 190px;
7
9
  padding: 0;
8
- margin: 0 var(--hdsplus-spacing-05);
10
+ margin: 0 var(--hdsplus-spacing-07);
9
11
  border-radius: var(--hdsplus-spacing-03);
10
12
 
11
13
  @media (--large) {
12
- margin: 0;
14
+ &:not(.hasSide) {
15
+ margin: 0;
16
+ }
17
+ }
18
+
19
+ @media (--dev-dot-viewport) {
20
+ &.hasSide {
21
+ margin: 0;
22
+ }
13
23
  }
14
24
  }
@@ -1,9 +1,20 @@
1
+ import classNames from 'classnames'
1
2
  import s from './style.module.css'
2
3
 
3
4
  interface RootProps {
5
+ className?: string
4
6
  children: React.ReactNode
7
+ hasSidePanel?: boolean
5
8
  }
6
9
 
7
- export default function Root({ children }: RootProps) {
8
- return <div className={s.root}>{children}</div>
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
+ )
9
20
  }
@@ -1,3 +1,5 @@
1
+ @custom-media --dev-dot-viewport (min-width: 924px);
2
+
1
3
  .root {
2
4
  width: 100%;
3
5
  display: flex;
@@ -7,9 +9,22 @@
7
9
  min-height: calc(100dvh - var(--hdsplus-spacing-12));
8
10
 
9
11
  @media (--large) {
10
- justify-content: flex-start;
11
- height: 100%;
12
- min-height: fit-content;
13
- gap: var(--hdsplus-spacing-04);
12
+ &:not(.hasSide) {
13
+ justify-content: flex-start;
14
+ height: 100%;
15
+ min-height: fit-content;
16
+ padding: var(--hdsplus-spacing-05) var(--hdsplus-spacing-04);
17
+ gap: var(--hdsplus-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(--hdsplus-spacing-05) var(--hdsplus-spacing-04);
27
+ gap: var(--hdsplus-spacing-04);
28
+ }
14
29
  }
15
30
  }
@@ -1,14 +1,15 @@
1
1
  import { useCallback } from 'react'
2
- import { trackNavClickEvent } from '../../../../../../../apps/www/layouts/standard/nav'
3
- import { v } from '@web/cms'
4
- import s from './style.module.css'
5
- import Link from 'next/link'
6
2
  import classNames from 'classnames'
7
- import { parseUrl } from '../../../../../../../apps/www/lib/parseUrl'
8
- import FlightIcon from '@hashicorp/react-design-system-components/src/components/flight-icon'
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 '@hashicorp/react-hds/src/components/flight-icon'
9
8
  import * as NavigationMenu from '@radix-ui/react-navigation-menu'
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
@@ -16,9 +17,11 @@ export interface PromoProps {
16
17
  slug?: string
17
18
  icon?: string
18
19
  theme: string
20
+ hasSidePanel?: boolean
19
21
  }
20
22
 
21
23
  export default function Promo({
24
+ locale,
22
25
  title,
23
26
  description,
24
27
  linkUrl,
@@ -26,6 +29,7 @@ export default function Promo({
26
29
  slug,
27
30
  icon,
28
31
  theme,
32
+ hasSidePanel,
29
33
  }: PromoProps) {
30
34
  const handleClick = useCallback((title, linkUrl, linkTitle, slug) => {
31
35
  if (window && window.analytics) {
@@ -40,23 +44,28 @@ export default function Promo({
40
44
  }, [])
41
45
 
42
46
  return (
43
- <div className={s.promo}>
47
+ <div
48
+ className={classNames(s.promo, {
49
+ [s.hasSide]: hasSidePanel,
50
+ [s.noSide]: !hasSidePanel,
51
+ })}
52
+ >
44
53
  {icon && (
45
54
  <div
46
55
  className={classNames(s.icon, {
47
- [s.hashidays]: v(theme) === 'hashidays',
48
- [s.hashiconf]: v(theme) === 'hashiconf',
56
+ [s.hashidays]: vercelSplit(theme) === 'hashidays',
57
+ [s.hashiconf]: vercelSplit(theme) === 'hashiconf',
49
58
  })}
50
59
  >
51
- <FlightIcon name={v(icon)} />
60
+ <FlightIcon name={vercelSplit(icon)} />
52
61
  </div>
53
62
  )}
54
63
  <div className={s.rightContent}>
55
64
  <div>
56
65
  <div
57
66
  className={classNames(s.title, {
58
- [s.hashidays]: v(theme) === 'hashidays',
59
- [s.hashiconf]: v(theme) === 'hashiconf',
67
+ [s.hashidays]: vercelSplit(theme) === 'hashidays',
68
+ [s.hashiconf]: vercelSplit(theme) === 'hashiconf',
60
69
  })}
61
70
  >
62
71
  {title}
@@ -65,7 +74,8 @@ export default function Promo({
65
74
  </div>
66
75
  <NavigationMenu.Link asChild>
67
76
  <Link
68
- href={parseUrl(linkUrl).href}
77
+ locale={locale ? locale : undefined}
78
+ {...getLocalizedLinkProps(linkUrl, locale)}
69
79
  className={s.link}
70
80
  onClickCapture={() => handleClick(title, linkUrl, linkTitle, slug)}
71
81
  >
@@ -1,3 +1,5 @@
1
+ @custom-media --dev-dot-viewport (min-width: 924px);
2
+
1
3
  .promo {
2
4
  display: flex;
3
5
  border-radius: var(--hdsplus-spacing-01);
@@ -7,12 +9,23 @@
7
9
  var(--hdsplus-spacing-06) var(--hdsplus-spacing-08);
8
10
  flex-direction: row;
9
11
  gap: var(--hdsplus-spacing-04);
10
- margin: var(--hdsplus-spacing-05);
12
+ margin: var(--hdsplus-spacing-07);
13
+ margin-bottom: var(--hdsplus-spacing-09);
11
14
 
12
15
  @media (--large) {
13
- margin: 0;
14
- width: min-content;
15
- min-width: 100%;
16
+ &.noSide {
17
+ margin: 0;
18
+ width: min-content;
19
+ min-width: 100%;
20
+ }
21
+ }
22
+
23
+ @media (--dev-dot-viewport) {
24
+ &.hasSide {
25
+ margin: 0;
26
+ width: min-content;
27
+ min-width: 100%;
28
+ }
16
29
  }
17
30
  }
18
31
 
@@ -38,8 +51,17 @@
38
51
  display: none;
39
52
 
40
53
  @media (--large) {
41
- display: block;
42
- margin-top: 3px;
54
+ @nest .noSide & {
55
+ display: block;
56
+ margin-top: 3px;
57
+ }
58
+ }
59
+
60
+ @media (--dev-dot-viewport) {
61
+ @nest .hasSide & {
62
+ display: block;
63
+ margin-top: 3px;
64
+ }
43
65
  }
44
66
  }
45
67
 
@@ -1,16 +1,17 @@
1
+ import classNames from 'classnames'
1
2
  import Link from 'next/link'
2
3
  import * as NavPanel from '../components/panel'
3
4
  import Promo, { type PromoProps } from '../components/promo'
5
+ import { getLocalizedLinkProps } from '../../../lib/get-localized-link-props'
4
6
  import { Products } from '@hashicorp/platform-product-meta'
5
- import FlightIcon from '@hashicorp/react-design-system-components/src/components/flight-icon'
6
- import { TextPlus } from '@hashicorp/react-design-system-components/src/components/text'
7
- import { parseUrl } from '../../../../../../apps/www/lib/parseUrl'
8
- import { trackNavClickEvent } from '../../../../../../apps/www/layouts/standard/nav'
9
- import s from './style.module.css'
7
+ import FlightIcon from '@hashicorp/react-hds/src/components/flight-icon'
8
+ import { TextPlus } from '@hashicorp/react-hds/src/components/text'
9
+ import { trackNavClickEvent } from '../../../lib/track-nav-click-event'
10
10
  import * as NavigationMenu from '@radix-ui/react-navigation-menu'
11
+ import s from './style.module.css'
11
12
 
12
13
  const PRODUCT_LOGO_MAP = new Map([
13
- ['Terraform', 'terraform-fill-color'],
14
+ ['Terraform', 'terraform-fill'],
14
15
  ['Packer', 'packer-fill-color'],
15
16
  ['Vault', 'vault-fill-color'],
16
17
  ['Boundary', 'boundary-fill-color'],
@@ -18,52 +19,128 @@ const PRODUCT_LOGO_MAP = new Map([
18
19
  ['Nomad', 'nomad-fill-color'],
19
20
  ['Waypoint', 'waypoint-fill-color'],
20
21
  ['Vagrant', 'vagrant-fill-color'],
22
+ ['HCP Vault Secrets', 'vault-secrets'],
23
+ ['HCP Vault Radar', 'vault-radar'],
21
24
  ])
22
25
 
23
- interface ProductsPanelProps {
26
+ const PRODUCT_LOGO_EXCEPTION_CLASSNAMES = {
27
+ Terraform: 'terraform',
28
+ 'HCP Vault Secrets': 'hcpVaultSecrets',
29
+ 'HCP Vault Radar': 'hcpVaultRadar',
30
+ }
31
+
32
+ export interface ProductsPanelProps {
33
+ locale: string
24
34
  productCategories: any
25
35
  promo?: PromoProps
36
+ sidePanel?: {
37
+ label: string
38
+ navItems: {
39
+ icon: string
40
+ title: string
41
+ description: string
42
+ url: string
43
+ }[]
44
+ }
26
45
  }
27
46
 
28
- const ProductPanel = ({ productCategories, promo }: ProductsPanelProps) => {
47
+ const ProductPanel = ({
48
+ locale,
49
+ productCategories,
50
+ promo,
51
+ sidePanel,
52
+ }: ProductsPanelProps) => {
29
53
  return (
30
- <NavPanel.Root>
31
- <NavPanel.Column>
32
- <ul className={s.productCategories}>
33
- {productCategories.map(({ title, products }) => {
34
- return (
35
- <li key={title} className={s.productCategory}>
36
- <TextPlus.Body className={s.eyebrow}>{title}</TextPlus.Body>
37
- <ul className={s.productList}>
38
- {products.map((product) => {
39
- return (
40
- <li key={product.url}>
41
- <NavProduct {...product} />
42
- </li>
43
- )
44
- })}
45
- </ul>
46
- </li>
47
- )
48
- })}
49
- </ul>
50
- </NavPanel.Column>
51
- {promo ? <Promo {...promo} /> : null}
54
+ <NavPanel.Root
55
+ className={classNames(s.productPanel, {
56
+ [s.hasSide]: sidePanel,
57
+ [s.noSide]: !sidePanel,
58
+ })}
59
+ hasSidePanel={Boolean(sidePanel)}
60
+ >
61
+ <div className={s.mainPanel}>
62
+ <NavPanel.Column hasSidePanel={Boolean(sidePanel)}>
63
+ <ul className={s.productCategories}>
64
+ {productCategories.map(({ title, products }) => {
65
+ return (
66
+ <li key={title} className={s.productCategory}>
67
+ <TextPlus.Body className={s.eyebrow}>{title}</TextPlus.Body>
68
+ <ul className={s.productList}>
69
+ {products.map((product) => {
70
+ return (
71
+ <li key={product.url}>
72
+ <NavProduct locale={locale} {...product} />
73
+ </li>
74
+ )
75
+ })}
76
+ </ul>
77
+ </li>
78
+ )
79
+ })}
80
+ </ul>
81
+ </NavPanel.Column>
82
+ {promo ? <Promo {...promo} hasSidePanel={Boolean(sidePanel)} /> : null}
83
+ </div>
84
+
85
+ {sidePanel ? (
86
+ <NavPanel.Column className={s.sidePanel}>
87
+ <TextPlus.Body size="200" weight="semibold">
88
+ {sidePanel.label}
89
+ </TextPlus.Body>
90
+
91
+ {/* ! TODO Replace the below list with the <LinkList /> component,
92
+ That component will require a refactor to support greater customization
93
+ Ticket:
94
+ https://app.asana.com/0/1206176289707208/1208162145034615/f
95
+ */}
96
+ <ul className={s.sidePanelItems}>
97
+ {sidePanel.navItems.map(({ icon, title, description, url }) => {
98
+ return (
99
+ <li key={title}>
100
+ <Link
101
+ aria-label={`${title} - ${description}`}
102
+ {...getLocalizedLinkProps(url, locale)}
103
+ locale={locale ? locale : undefined}
104
+ className={classNames(s.sidePanelItem, s.focusIndicator)}
105
+ >
106
+ <div className={s.iconBackground}>
107
+ <FlightIcon
108
+ size={16}
109
+ name={icon}
110
+ color="var(--token-color-foreground-faint)"
111
+ />
112
+ </div>
113
+ <div className={s.sidePanelItemContent}>
114
+ <TextPlus.Body size="200" weight="semibold" tag="span">
115
+ {title}
116
+ </TextPlus.Body>
117
+ <span className={s.sidePanelItemDesc}>{description}</span>
118
+ </div>
119
+ </Link>
120
+ </li>
121
+ )
122
+ })}
123
+ </ul>
124
+ </NavPanel.Column>
125
+ ) : null}
52
126
  </NavPanel.Root>
53
127
  )
54
128
  }
55
129
 
56
130
  export interface NavProductProps {
131
+ locale?: string
57
132
  url: string
58
133
  product: Products | string
59
134
  description: string
60
135
  }
61
136
 
62
- function NavProduct({ url, product, description }: NavProductProps) {
137
+ function NavProduct({ locale, url, product, description }: NavProductProps) {
63
138
  return (
64
139
  <NavigationMenu.Link asChild>
65
140
  <Link
66
- href={parseUrl(url).href}
141
+ aria-label={`${product} - ${description}`}
142
+ {...getLocalizedLinkProps(url, locale)}
143
+ locale={locale ? locale : undefined}
67
144
  onClickCapture={() => {
68
145
  trackNavClickEvent(product, url, 'products')
69
146
  }}
@@ -73,6 +150,11 @@ function NavProduct({ url, product, description }: NavProductProps) {
73
150
  <div className={s.productLogo}>
74
151
  <FlightIcon
75
152
  name={PRODUCT_LOGO_MAP.get(product) ?? 'hashicorp-fill-color'}
153
+ className={
154
+ PRODUCT_LOGO_EXCEPTION_CLASSNAMES[product]
155
+ ? s[PRODUCT_LOGO_EXCEPTION_CLASSNAMES[product]]
156
+ : undefined
157
+ }
76
158
  />
77
159
  </div>
78
160
  <div className={s.productTextContent}>