@hashicorp/react-components 0.0.0-canary.29ac326 → 0.0.0-canary.32599ff
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.
- package/package.json +7 -6
- package/src/components/actions/index.tsx +5 -5
- package/src/components/call-to-action/index.tsx +12 -10
- package/src/components/call-to-action/styles/variant-centered.module.css +5 -4
- package/src/components/call-to-action/styles/variant-compact-grid.module.css +6 -4
- package/src/components/call-to-action/styles/variant-compact.module.css +6 -4
- package/src/components/call-to-action/styles/variant-links.module.css +6 -11
- package/src/components/card/index.test.tsx +1 -1
- package/src/components/card/newsroom-card/index.test.tsx +1 -1
- package/src/components/card/newsroom-card/style.module.css +1 -1
- package/src/components/card/partner-card/index.tsx +5 -5
- package/src/components/card/person-card/index.tsx +3 -3
- package/src/components/card/primitives.tsx +20 -19
- package/src/components/card/resource-card/index.test.tsx +1 -1
- package/src/components/card/resource-card/index.tsx +3 -0
- package/src/components/card/style.module.css +2 -2
- package/src/components/card/types.ts +2 -2
- package/src/components/card/unified-card/index.spec.tsx +40 -0
- package/src/components/card/unified-card/index.tsx +5 -11
- package/src/components/inline-video/index.tsx +104 -0
- package/src/components/inline-video/style.module.css +99 -0
- package/src/components/intro/style.module.css +2 -2
- package/src/components/marketo-form/contexts/FormMetadata.ts +2 -0
- package/src/components/marketo-form/form/index.tsx +12 -7
- package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/email-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +12 -1
- package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +1 -0
- package/src/components/marketo-form/partials/fields/htmltext-field/style.module.css +2 -2
- package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/select-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/text-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +1 -1
- package/src/components/marketo-form/types.ts +10 -12
- package/src/components/marketo-form/utils.ts +1 -1
- package/src/components/nav-panel/components/link-list/index.tsx +15 -9
- package/src/components/nav-panel/components/link-list/style.module.css +10 -10
- package/src/components/nav-panel/components/panel/column/index.tsx +15 -2
- package/src/components/nav-panel/components/panel/column/style.module.css +13 -3
- package/src/components/nav-panel/components/panel/root/index.tsx +11 -2
- package/src/components/nav-panel/components/panel/root/style.module.css +20 -6
- package/src/components/nav-panel/components/promo/index.tsx +23 -10
- package/src/components/nav-panel/components/promo/style.module.css +48 -16
- package/src/components/nav-panel/product-panel/index.tsx +46 -16
- package/src/components/nav-panel/product-panel/style.module.css +151 -42
- package/src/components/nav-panel/standard-panel/index.tsx +3 -0
- package/src/components/nav-panel/standard-panel/style.module.css +2 -2
- package/src/components/next-steps/index.tsx +3 -2
- package/src/components/next-steps/style.module.css +18 -18
- package/src/components/product-badge/index.tsx +1 -1
- package/src/components/product-badge/style.module.css +2 -2
- package/src/components/products-used/style.module.css +7 -7
- package/src/components/related-content/index.tsx +28 -29
- package/src/components/related-content/style.module.css +58 -60
- package/src/components/related-content/types.ts +2 -2
- package/src/components/subnav/index.tsx +12 -3
- package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +8 -12
- package/src/components/subnav/partials/CtaLinks/index.tsx +9 -8
- package/src/components/subnav/partials/CtaLinks/style.module.css +6 -6
- package/src/components/subnav/partials/DropdownTrigger/index.tsx +2 -2
- package/src/components/subnav/partials/DropdownTrigger/style.module.css +11 -8
- package/src/components/subnav/partials/MenuItemsDefault/index.tsx +24 -8
- package/src/components/subnav/partials/MenuItemsDefault/style.module.css +44 -31
- package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +17 -4
- package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +24 -18
- package/src/components/subnav/partials/TitleLink/index.tsx +6 -4
- package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +2 -1
- package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +2 -1
- package/src/components/subnav/partials/TitleLink/style.module.css +3 -3
- package/src/components/subnav/partials/nav-item-text/style.module.css +2 -4
- package/src/components/subnav/style.module.css +5 -7
- package/src/lib/get-localized-link-props/index.test.ts +30 -0
- package/src/lib/get-localized-link-props/index.ts +45 -0
- package/src/lib/parse-url/index.test.ts +40 -1
- package/src/lib/parse-url/index.ts +77 -9
- package/src/lib/supported-locales/index.ts +1 -0
- package/src/lib/track-nav-click-event/index.ts +4 -4
- package/src/lib/v/index.ts +4 -5
- package/src/components/consent-manager/README.md +0 -73
- package/src/components/consent-manager/components/banner/banner.module.css +0 -23
- package/src/components/consent-manager/components/banner/banner.test.tsx +0 -31
- package/src/components/consent-manager/components/banner/banner.tsx +0 -73
- package/src/components/consent-manager/components/dialog/dialog.module.css +0 -145
- package/src/components/consent-manager/components/dialog/dialog.test.tsx +0 -194
- package/src/components/consent-manager/components/dialog/dialog.tsx +0 -339
- package/src/components/consent-manager/img/icn_close.tsx +0 -19
- package/src/components/consent-manager/index.test.tsx +0 -334
- package/src/components/consent-manager/index.tsx +0 -186
- package/src/components/consent-manager/loader/README.md +0 -29
- package/src/components/consent-manager/loader/categories.ts +0 -22
- package/src/components/consent-manager/loader/index.tsx +0 -94
- package/src/components/consent-manager/loader/presets/enterprise.ts +0 -12
- package/src/components/consent-manager/loader/presets/oss.ts +0 -10
- package/src/components/consent-manager/loader/services.ts +0 -45
- package/src/components/consent-manager/scripts/custom.tsx +0 -59
- package/src/components/consent-manager/scripts/segment.tsx +0 -87
- package/src/components/consent-manager/style.module.css +0 -9
- package/src/components/consent-manager/types.ts +0 -55
- package/src/components/consent-manager/util/cookies.test.ts +0 -75
- package/src/components/consent-manager/util/cookies.ts +0 -70
- package/src/components/consent-manager/util/integrations.test.ts +0 -115
- package/src/components/consent-manager/util/integrations.ts +0 -110
- 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.
|
|
3
|
+
"version": "0.0.0-canary.32599ff",
|
|
4
4
|
"main": "src/index.ts",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"lint": "next-hashicorp lint",
|
|
@@ -8,23 +8,24 @@
|
|
|
8
8
|
"test:watch": "vitest watch"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@hashicorp/flight-icons": "^
|
|
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-
|
|
14
|
+
"@hashicorp/react-mds": "*",
|
|
15
15
|
"@hashicorp/web-mktg-logos": "*",
|
|
16
16
|
"@radix-ui/react-navigation-menu": "^1.2.0",
|
|
17
17
|
"@radix-ui/react-visually-hidden": "^1.1.0",
|
|
18
|
-
"@vercel/analytics": "^1.3.1",
|
|
19
18
|
"@vercel/fetch": "^7.0.0",
|
|
20
19
|
"@vercel/stega": "^0.1.2",
|
|
21
20
|
"classnames": "^2.3.2",
|
|
21
|
+
"isomorphic-unfetch": "4.0.2",
|
|
22
22
|
"js-cookie": "^3.0.5",
|
|
23
23
|
"moize": "^6.1.3",
|
|
24
|
-
"react-hook-form": "^7.43.5"
|
|
24
|
+
"react-hook-form": "^7.43.5",
|
|
25
|
+
"react-player": "2.10.1"
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
27
|
-
"@hashicorp/platform-cli": "^2.
|
|
28
|
+
"@hashicorp/platform-cli": "^2.8.0",
|
|
28
29
|
"@hashicorp/platform-types": "^0.4.0",
|
|
29
30
|
"@testing-library/jest-dom": "^6.4.2",
|
|
30
31
|
"@vitejs/plugin-react": "^4.2.1",
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import classNames from 'classnames'
|
|
7
|
-
import
|
|
8
|
-
import
|
|
7
|
+
import { HDSButton } from '@hashicorp/react-mds/src/hds/components/button'
|
|
8
|
+
import { HDSPlusStandaloneLink } from '@hashicorp/react-mds/src/hds-plus/standalone-link'
|
|
9
9
|
import { IconArrowRight16 } from '@hashicorp/flight-icons/svg-react/arrow-right-16'
|
|
10
10
|
import { IconArrowRight24 } from '@hashicorp/flight-icons/svg-react/arrow-right-24'
|
|
11
11
|
import type { ActionsProps } from './types'
|
|
@@ -49,7 +49,7 @@ export default function Actions({
|
|
|
49
49
|
// have the `primary` and `secondary` variations respectively.
|
|
50
50
|
|
|
51
51
|
const standaloneLinkVariant: ComponentProps<
|
|
52
|
-
typeof
|
|
52
|
+
typeof HDSPlusStandaloneLink
|
|
53
53
|
>['color'] =
|
|
54
54
|
index === 0
|
|
55
55
|
? 'primary'
|
|
@@ -60,7 +60,7 @@ export default function Actions({
|
|
|
60
60
|
|
|
61
61
|
if (isStandaloneLink) {
|
|
62
62
|
return (
|
|
63
|
-
<
|
|
63
|
+
<HDSPlusStandaloneLink
|
|
64
64
|
// eslint-disable-next-line react/no-array-index-key
|
|
65
65
|
key={index}
|
|
66
66
|
text={cta.title}
|
|
@@ -89,7 +89,7 @@ export default function Actions({
|
|
|
89
89
|
)
|
|
90
90
|
} else {
|
|
91
91
|
return (
|
|
92
|
-
<
|
|
92
|
+
<HDSButton
|
|
93
93
|
// eslint-disable-next-line react/no-array-index-key
|
|
94
94
|
key={index}
|
|
95
95
|
text={cta.title}
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MPL-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import type { ReactNode } from 'react'
|
|
7
|
+
import {
|
|
8
|
+
ButtonColor,
|
|
9
|
+
HDSButton,
|
|
10
|
+
} from '@hashicorp/react-mds/src/hds/components/button'
|
|
11
|
+
import { HDSPlusStandaloneLink } from '@hashicorp/react-mds/src/hds-plus/standalone-link'
|
|
10
12
|
import { IconArrowRight24 } from '@hashicorp/flight-icons/svg-react/arrow-right-24'
|
|
11
13
|
import { IconExternalLink24 } from '@hashicorp/flight-icons/svg-react/external-link-24'
|
|
12
14
|
import { IconDownload24 } from '@hashicorp/flight-icons/svg-react/download-24'
|
|
@@ -117,9 +119,9 @@ function CallToAction({
|
|
|
117
119
|
</div>
|
|
118
120
|
)}
|
|
119
121
|
{links && (
|
|
120
|
-
<
|
|
122
|
+
<div className={s.links} data-testid="links">
|
|
121
123
|
{links.map((link, stableIdx) => {
|
|
122
|
-
let color:
|
|
124
|
+
let color: ButtonColor =
|
|
123
125
|
variant === 'links'
|
|
124
126
|
? 'tertiary'
|
|
125
127
|
: stableIdx === 0
|
|
@@ -128,7 +130,7 @@ function CallToAction({
|
|
|
128
130
|
|
|
129
131
|
if (color === 'tertiary') {
|
|
130
132
|
return (
|
|
131
|
-
<
|
|
133
|
+
<HDSPlusStandaloneLink
|
|
132
134
|
key={stableIdx}
|
|
133
135
|
color="secondary"
|
|
134
136
|
text={link.text}
|
|
@@ -158,7 +160,7 @@ function CallToAction({
|
|
|
158
160
|
color = 'secondary'
|
|
159
161
|
} else if (theme === 'brand' && color === 'secondary') {
|
|
160
162
|
return (
|
|
161
|
-
<
|
|
163
|
+
<HDSPlusStandaloneLink
|
|
162
164
|
key={stableIdx}
|
|
163
165
|
color="secondary-inverted"
|
|
164
166
|
text={link.text}
|
|
@@ -177,7 +179,7 @@ function CallToAction({
|
|
|
177
179
|
}
|
|
178
180
|
|
|
179
181
|
return (
|
|
180
|
-
<
|
|
182
|
+
<HDSButton
|
|
181
183
|
// eslint-disable-next-line react/no-array-index-key
|
|
182
184
|
key={stableIdx}
|
|
183
185
|
// className={s.button}
|
|
@@ -194,7 +196,7 @@ function CallToAction({
|
|
|
194
196
|
/>
|
|
195
197
|
)
|
|
196
198
|
})}
|
|
197
|
-
</
|
|
199
|
+
</div>
|
|
198
200
|
)}
|
|
199
201
|
</div>
|
|
200
202
|
</div>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
.root {
|
|
7
|
-
--background: var(--
|
|
7
|
+
--background: var(--wpl-neutral-0);
|
|
8
8
|
--text-color-display: var(--gray-1);
|
|
9
9
|
--text-color-body: var(--gray-2);
|
|
10
10
|
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
&.theme-dark {
|
|
26
|
-
--background: var(--
|
|
27
|
-
--text-color-display: var(--
|
|
26
|
+
--background: var(--wpl-neutral-900);
|
|
27
|
+
--text-color-display: var(--wpl-neutral-0);
|
|
28
28
|
--text-color-body: var(--gray-5);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
&.theme-brand {
|
|
32
32
|
--background: var(--brand);
|
|
33
|
-
--text-color-display: var(--
|
|
33
|
+
--text-color-display: var(--wpl-neutral-0);
|
|
34
34
|
--text-color-body: var(--gray-6);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
display: flex;
|
|
68
68
|
flex-wrap: wrap;
|
|
69
69
|
justify-content: center;
|
|
70
|
+
gap: var(--mds-spacing-05);
|
|
70
71
|
|
|
71
72
|
/*
|
|
72
73
|
* Margins here account for extra 8px margin on buttons
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
.root {
|
|
7
|
-
--background: var(--
|
|
7
|
+
--background: var(--wpl-neutral-0);
|
|
8
8
|
--text-color-display: var(--gray-1);
|
|
9
9
|
--text-color-body: var(--gray-2);
|
|
10
10
|
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
&.theme-dark {
|
|
26
|
-
--background: var(--
|
|
27
|
-
--text-color-display: var(--
|
|
26
|
+
--background: var(--wpl-neutral-900);
|
|
27
|
+
--text-color-display: var(--wpl-neutral-0);
|
|
28
28
|
--text-color-body: var(--gray-5);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
&.theme-brand {
|
|
32
32
|
--background: var(--brand);
|
|
33
|
-
--text-color-display: var(--
|
|
33
|
+
--text-color-display: var(--wpl-neutral-0);
|
|
34
34
|
--text-color-body: var(--gray-6);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -74,6 +74,8 @@
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
.links {
|
|
77
|
+
display: flex;
|
|
78
|
+
gap: var(--mds-spacing-05);
|
|
77
79
|
margin-top: 32px;
|
|
78
80
|
margin-bottom: -16px;
|
|
79
81
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
.root {
|
|
7
|
-
--background: var(--
|
|
7
|
+
--background: var(--wpl-neutral-0);
|
|
8
8
|
--text-color-display: var(--gray-1);
|
|
9
9
|
--text-color-body: var(--gray-2);
|
|
10
10
|
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
&.theme-dark {
|
|
26
|
-
--background: var(--
|
|
27
|
-
--text-color-display: var(--
|
|
26
|
+
--background: var(--wpl-neutral-900);
|
|
27
|
+
--text-color-display: var(--wpl-neutral-0);
|
|
28
28
|
--text-color-body: var(--gray-5);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
&.theme-brand {
|
|
32
32
|
--background: var(--brand);
|
|
33
|
-
--text-color-display: var(--
|
|
33
|
+
--text-color-display: var(--wpl-neutral-0);
|
|
34
34
|
--text-color-body: var(--gray-6);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -77,6 +77,8 @@
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
.links {
|
|
80
|
+
display: flex;
|
|
81
|
+
gap: var(--mds-spacing-05);
|
|
80
82
|
margin-top: 32px;
|
|
81
83
|
margin-bottom: -16px;
|
|
82
84
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
.root {
|
|
7
|
-
--background: var(--
|
|
7
|
+
--background: var(--wpl-neutral-0);
|
|
8
8
|
--text-color-display: var(--gray-1);
|
|
9
9
|
--text-color-body: var(--gray-2);
|
|
10
10
|
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
&.theme-dark {
|
|
26
|
-
--background: var(--
|
|
27
|
-
--text-color-display: var(--
|
|
26
|
+
--background: var(--wpl-neutral-900);
|
|
27
|
+
--text-color-display: var(--wpl-neutral-0);
|
|
28
28
|
--text-color-body: var(--gray-5);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
&.theme-brand {
|
|
32
32
|
--background: var(--brand);
|
|
33
|
-
--text-color-display: var(--
|
|
33
|
+
--text-color-display: var(--wpl-neutral-0);
|
|
34
34
|
--text-color-body: var(--gray-6);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -61,18 +61,13 @@
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
.links {
|
|
64
|
+
display: flex;
|
|
65
|
+
gap: var(--mds-spacing-05);
|
|
64
66
|
margin-top: 32px;
|
|
65
67
|
|
|
66
68
|
@media (--large) {
|
|
67
69
|
margin-top: 40px;
|
|
68
70
|
}
|
|
69
|
-
|
|
70
|
-
&::after {
|
|
71
|
-
display: block;
|
|
72
|
-
float: none;
|
|
73
|
-
content: '';
|
|
74
|
-
clear: both;
|
|
75
|
-
}
|
|
76
71
|
}
|
|
77
72
|
|
|
78
73
|
.button {
|
|
@@ -56,7 +56,7 @@ describe('<Card />', () => {
|
|
|
56
56
|
const metaElement = screen.getByTestId('wpl-card-meta')
|
|
57
57
|
|
|
58
58
|
cardMeta.forEach((item) => {
|
|
59
|
-
expect(metaElement).
|
|
59
|
+
expect(metaElement).toHaveTextContent(item)
|
|
60
60
|
})
|
|
61
61
|
expect(metaElement).toContainElement(screen.getByText('|'))
|
|
62
62
|
})
|
|
@@ -26,7 +26,7 @@ describe('<NewsroomCard />', () => {
|
|
|
26
26
|
const metaElement = screen.getByTestId('wpl-card-meta')
|
|
27
27
|
|
|
28
28
|
expectedMeta.forEach((item) => {
|
|
29
|
-
expect(metaElement).
|
|
29
|
+
expect(metaElement).toHaveTextContent(item)
|
|
30
30
|
})
|
|
31
31
|
|
|
32
32
|
expect(metaElement).toContainElement(screen.queryByText('|'))
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import Image, { type ImageProps } from 'next/image'
|
|
7
|
-
import Badge from '@hashicorp/react-
|
|
8
|
-
import FlightIcon from '@hashicorp/react-
|
|
9
|
-
import {
|
|
7
|
+
import { Badge } from '@hashicorp/react-mds/src/components/badge'
|
|
8
|
+
import FlightIcon from '@hashicorp/react-mds/src/hds/components/flight-icon'
|
|
9
|
+
import { Text } from '@hashicorp/react-mds/src/components/text'
|
|
10
10
|
import * as CardPrimitives from '../primitives'
|
|
11
11
|
import type { CardProps } from '../types'
|
|
12
12
|
import s from './style.module.css'
|
|
@@ -48,9 +48,9 @@ export function PartnerCard({
|
|
|
48
48
|
</div>
|
|
49
49
|
<CardPrimitives.Content>
|
|
50
50
|
<CardPrimitives.Meta items={meta} />
|
|
51
|
-
<
|
|
51
|
+
<Text.Body tag="p" size="200" className={s.description}>
|
|
52
52
|
{description}
|
|
53
|
-
</
|
|
53
|
+
</Text.Body>
|
|
54
54
|
{hasProductBadges || hasCompetencyBadges ? (
|
|
55
55
|
<CardPrimitives.ProductBadges badges={productBadges || []}>
|
|
56
56
|
{hasCompetencyBadges &&
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { memo, type ReactNode } from 'react'
|
|
7
|
-
import {
|
|
7
|
+
import { Text } from '@hashicorp/react-mds/src/components/text'
|
|
8
8
|
import { IconGithub16 } from '@hashicorp/flight-icons/svg-react/github-16'
|
|
9
9
|
import { IconTwitter16 } from '@hashicorp/flight-icons/svg-react/twitter-16'
|
|
10
10
|
import { IconLinkedin16 } from '@hashicorp/flight-icons/svg-react/linkedin-16'
|
|
@@ -76,9 +76,9 @@ export function PersonCard({
|
|
|
76
76
|
<div>
|
|
77
77
|
<CardPrimitives.Heading>{name}</CardPrimitives.Heading>
|
|
78
78
|
{location ? (
|
|
79
|
-
<
|
|
79
|
+
<Text.Body tag="p" size="200" className={s.location}>
|
|
80
80
|
{location}
|
|
81
|
-
</
|
|
81
|
+
</Text.Body>
|
|
82
82
|
) : null}
|
|
83
83
|
</div>
|
|
84
84
|
{bio ? (
|
|
@@ -7,8 +7,8 @@ import * as React from 'react'
|
|
|
7
7
|
import classNames from 'classnames'
|
|
8
8
|
import Image from 'next/image'
|
|
9
9
|
import Link from 'next/link'
|
|
10
|
-
import HDSCard from '@hashicorp/react-
|
|
11
|
-
import {
|
|
10
|
+
import HDSCard from '@hashicorp/react-mds/src/hds/components/card'
|
|
11
|
+
import { Text } from '@hashicorp/react-mds/src/components/text'
|
|
12
12
|
import { IconArrowRight24 } from '@hashicorp/flight-icons/svg-react/arrow-right-24'
|
|
13
13
|
import ProductBadge from '../product-badge'
|
|
14
14
|
import type {
|
|
@@ -33,6 +33,7 @@ const Card = React.forwardRef<HTMLAnchorElement, CardPrimitiveProps>(
|
|
|
33
33
|
hasBorder = true,
|
|
34
34
|
children,
|
|
35
35
|
className,
|
|
36
|
+
'aria-label': ariaLabel,
|
|
36
37
|
} = props
|
|
37
38
|
|
|
38
39
|
const linkProps = isExternal
|
|
@@ -58,7 +59,7 @@ const Card = React.forwardRef<HTMLAnchorElement, CardPrimitiveProps>(
|
|
|
58
59
|
href={link}
|
|
59
60
|
ref={ref}
|
|
60
61
|
className={s.link}
|
|
61
|
-
aria-label={heading}
|
|
62
|
+
aria-label={ariaLabel ?? heading}
|
|
62
63
|
onClickCapture={clickHandler}
|
|
63
64
|
{...linkProps}
|
|
64
65
|
/>
|
|
@@ -100,23 +101,23 @@ function LogoThumbnail({ src, alt }: ThumbnailProps) {
|
|
|
100
101
|
|
|
101
102
|
function Meta({ items }: MetaProps) {
|
|
102
103
|
return (
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
<div className={s.meta} data-testid="wpl-card-meta">
|
|
105
|
+
<Text.Label>
|
|
106
|
+
{items.map((item, stableIdx) => {
|
|
107
|
+
const isLastItem = stableIdx === items.length - 1
|
|
108
|
+
return (
|
|
109
|
+
<>
|
|
109
110
|
{item}
|
|
110
|
-
{
|
|
111
|
+
{!isLastItem ? (
|
|
111
112
|
<span className={s.metaSeparator} aria-hidden={true}>
|
|
112
113
|
|
|
|
113
114
|
</span>
|
|
114
115
|
) : null}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
</
|
|
116
|
+
</>
|
|
117
|
+
)
|
|
118
|
+
})}
|
|
119
|
+
</Text.Label>
|
|
120
|
+
</div>
|
|
120
121
|
)
|
|
121
122
|
}
|
|
122
123
|
|
|
@@ -130,9 +131,9 @@ function Content({ children }: ContentProps) {
|
|
|
130
131
|
|
|
131
132
|
function Heading({ as = 'h2', children }: HeadingProps) {
|
|
132
133
|
return (
|
|
133
|
-
<
|
|
134
|
+
<Text.DisplayExpressive tag={as} size="200" className={s.heading}>
|
|
134
135
|
{children}
|
|
135
|
-
</
|
|
136
|
+
</Text.DisplayExpressive>
|
|
136
137
|
)
|
|
137
138
|
}
|
|
138
139
|
|
|
@@ -156,9 +157,9 @@ function ProductBadges({ badges, children }: ProductBadgesProps) {
|
|
|
156
157
|
|
|
157
158
|
function Description({ children }: DescriptionProps) {
|
|
158
159
|
return (
|
|
159
|
-
<
|
|
160
|
+
<Text.Body tag="p" size="200" className={s.description}>
|
|
160
161
|
{children}
|
|
161
|
-
</
|
|
162
|
+
</Text.Body>
|
|
162
163
|
)
|
|
163
164
|
}
|
|
164
165
|
|
|
@@ -26,7 +26,7 @@ describe('<ResourceCard />', () => {
|
|
|
26
26
|
const metaElement = screen.getByTestId('wpl-card-meta')
|
|
27
27
|
|
|
28
28
|
expectedMeta.forEach((item) => {
|
|
29
|
-
expect(metaElement).
|
|
29
|
+
expect(metaElement).toHaveTextContent(item)
|
|
30
30
|
})
|
|
31
31
|
|
|
32
32
|
expect(metaElement).toContainElement(screen.getByText('|'))
|
|
@@ -13,6 +13,7 @@ export interface ResourceCardProps {
|
|
|
13
13
|
link: string
|
|
14
14
|
productBadges?: CardProps['productBadges']
|
|
15
15
|
thumbnail: ThumbnailProps
|
|
16
|
+
isExternal?: CardProps['isExternal']
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
export function ResourceCard({
|
|
@@ -22,6 +23,7 @@ export function ResourceCard({
|
|
|
22
23
|
link,
|
|
23
24
|
productBadges,
|
|
24
25
|
thumbnail,
|
|
26
|
+
isExternal,
|
|
25
27
|
}: ResourceCardProps) {
|
|
26
28
|
const meta: string[] = date ? [date, category] : [category]
|
|
27
29
|
|
|
@@ -32,6 +34,7 @@ export function ResourceCard({
|
|
|
32
34
|
meta={meta}
|
|
33
35
|
productBadges={productBadges}
|
|
34
36
|
thumbnail={thumbnail}
|
|
37
|
+
isExternal={isExternal}
|
|
35
38
|
/>
|
|
36
39
|
)
|
|
37
40
|
}
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
|
|
72
72
|
.logoThumbnail {
|
|
73
73
|
composes: thumbnail;
|
|
74
|
-
padding: var(--
|
|
74
|
+
padding: var(--mds-spacing-07);
|
|
75
75
|
|
|
76
76
|
& .image {
|
|
77
77
|
aspect-ratio: none;
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
.heading {
|
|
112
|
-
font-weight: var(--
|
|
112
|
+
font-weight: var(--mds-typography-font-weight-bold);
|
|
113
113
|
color: var(--token-color-foreground-strong);
|
|
114
114
|
margin: 0;
|
|
115
115
|
}
|
|
@@ -10,14 +10,14 @@ import type { PersonCardProps } from './person-card'
|
|
|
10
10
|
import type { ResourceCardProps } from './resource-card'
|
|
11
11
|
import type { UnifiedCardProps } from './unified-card'
|
|
12
12
|
|
|
13
|
-
export interface BaseCardProps
|
|
13
|
+
export interface BaseCardProps
|
|
14
|
+
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
14
15
|
withArrow?: boolean
|
|
15
16
|
heading: string
|
|
16
17
|
link: string
|
|
17
18
|
clickHandler?: () => void
|
|
18
19
|
isExternal?: boolean
|
|
19
20
|
hasBorder?: boolean
|
|
20
|
-
className?: string
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export interface CardPrimitiveProps extends BaseCardProps {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) HashiCorp, Inc.
|
|
3
|
+
* SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { render, screen } from '@testing-library/react'
|
|
7
|
+
import { UnifiedCard, UnifiedCardProps } from '.'
|
|
8
|
+
|
|
9
|
+
const defaultProps: UnifiedCardProps = {
|
|
10
|
+
link: 'https://hashicorp.com',
|
|
11
|
+
heading: 'Example heading',
|
|
12
|
+
thumbnail: {
|
|
13
|
+
src: 'https://www.datocms-assets.com/19447/1648680074-screenshot-2022-03-31-at-00-40-47.png',
|
|
14
|
+
alt: 'HashiConf Europe 2022 Recap',
|
|
15
|
+
},
|
|
16
|
+
} as const
|
|
17
|
+
|
|
18
|
+
describe(`<UnifiedCard />`, () => {
|
|
19
|
+
it('should render the provided meta with a separator if n > 1', () => {
|
|
20
|
+
const expectedMeta = ['Category', 'Hello']
|
|
21
|
+
render(<UnifiedCard {...defaultProps} meta={expectedMeta} />)
|
|
22
|
+
|
|
23
|
+
const metaElement = screen.getByTestId('wpl-card-meta')
|
|
24
|
+
|
|
25
|
+
expectedMeta.forEach((item) => {
|
|
26
|
+
expect(metaElement).toHaveTextContent(item)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
expect(metaElement).toContainElement(screen.getByText('|'))
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('it should not render a separator if n === 1', () => {
|
|
33
|
+
render(<UnifiedCard {...defaultProps} meta={['Category']} />)
|
|
34
|
+
const metaElement = screen.getByTestId('wpl-card-meta')
|
|
35
|
+
|
|
36
|
+
expect(metaElement).toContainElement(screen.getByText('Category'))
|
|
37
|
+
|
|
38
|
+
expect(metaElement).not.toContainElement(screen.queryByText('|'))
|
|
39
|
+
})
|
|
40
|
+
})
|
|
@@ -4,20 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { ReactNode } from 'react'
|
|
7
|
-
import Badge from '@hashicorp/react-
|
|
7
|
+
import { Badge } from '@hashicorp/react-mds/src/components/badge'
|
|
8
8
|
import * as CardPrimitives from '../primitives'
|
|
9
|
-
import type { CardProps
|
|
9
|
+
import type { CardProps } from '../types'
|
|
10
10
|
|
|
11
|
-
export interface UnifiedCardProps {
|
|
12
|
-
heading: string
|
|
13
|
-
meta?: string[]
|
|
14
|
-
link: string
|
|
15
|
-
productBadges?: CardProps['productBadges']
|
|
11
|
+
export interface UnifiedCardProps extends CardProps {
|
|
16
12
|
badges?: (string | [ReactNode, string])[]
|
|
17
|
-
thumbnail?: ThumbnailProps
|
|
18
|
-
withArrow?: boolean
|
|
19
|
-
isExternal?: boolean
|
|
20
|
-
className?: string
|
|
21
13
|
}
|
|
22
14
|
|
|
23
15
|
export function UnifiedCard({
|
|
@@ -30,6 +22,7 @@ export function UnifiedCard({
|
|
|
30
22
|
withArrow = false,
|
|
31
23
|
isExternal = false,
|
|
32
24
|
className,
|
|
25
|
+
'aria-label': ariaLabel,
|
|
33
26
|
}: UnifiedCardProps) {
|
|
34
27
|
return (
|
|
35
28
|
<CardPrimitives.Card
|
|
@@ -38,6 +31,7 @@ export function UnifiedCard({
|
|
|
38
31
|
withArrow={withArrow}
|
|
39
32
|
isExternal={isExternal}
|
|
40
33
|
className={className}
|
|
34
|
+
aria-label={ariaLabel ?? heading}
|
|
41
35
|
>
|
|
42
36
|
{thumbnail ? <CardPrimitives.Thumbnail {...thumbnail} /> : null}
|
|
43
37
|
<CardPrimitives.Content>
|