@hashicorp/react-components 0.0.0-nightly.97eb452 → 0.0.0-nightly.9aa5827

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 (143) 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.test.ts +30 -1
  24. package/src/lib/parse-url/index.ts +71 -8
  25. package/src/lib/send-posthog-event/index.ts +22 -0
  26. package/src/lib/supported-locales/index.ts +10 -0
  27. package/src/lib/track-nav-click-event/index.ts +4 -4
  28. package/src/components/actions/index.tsx +0 -107
  29. package/src/components/actions/style.module.css +0 -28
  30. package/src/components/actions/types.ts +0 -73
  31. package/src/components/call-to-action/index.tsx +0 -205
  32. package/src/components/call-to-action/styles/variant-centered.module.css +0 -93
  33. package/src/components/call-to-action/styles/variant-compact-grid.module.css +0 -88
  34. package/src/components/call-to-action/styles/variant-compact.module.css +0 -91
  35. package/src/components/call-to-action/styles/variant-links.module.css +0 -85
  36. package/src/components/card/README.md +0 -11
  37. package/src/components/card/card.tsx +0 -45
  38. package/src/components/card/index.test.tsx +0 -69
  39. package/src/components/card/index.tsx +0 -14
  40. package/src/components/card/newsroom-card/index.test.tsx +0 -39
  41. package/src/components/card/newsroom-card/index.tsx +0 -37
  42. package/src/components/card/newsroom-card/style.module.css +0 -12
  43. package/src/components/card/partner-card/index.test.tsx +0 -57
  44. package/src/components/card/partner-card/index.tsx +0 -69
  45. package/src/components/card/partner-card/style.module.css +0 -24
  46. package/src/components/card/person-card/index.test.tsx +0 -71
  47. package/src/components/card/person-card/index.tsx +0 -93
  48. package/src/components/card/person-card/style.module.css +0 -33
  49. package/src/components/card/primitives.tsx +0 -177
  50. package/src/components/card/promo-card/index.tsx +0 -51
  51. package/src/components/card/resource-card/index.test.tsx +0 -48
  52. package/src/components/card/resource-card/index.tsx +0 -37
  53. package/src/components/card/style.module.css +0 -145
  54. package/src/components/card/types.ts +0 -66
  55. package/src/components/card/unified-card/index.spec.tsx +0 -40
  56. package/src/components/card/unified-card/index.tsx +0 -58
  57. package/src/components/intro/index.tsx +0 -82
  58. package/src/components/intro/style.module.css +0 -67
  59. package/src/components/intro/types.ts +0 -44
  60. package/src/components/marketo-form/CHANGELOG.md +0 -122
  61. package/src/components/marketo-form/README.md +0 -1
  62. package/src/components/marketo-form/contexts/FormMetadata.ts +0 -13
  63. package/src/components/marketo-form/docs.mdx +0 -197
  64. package/src/components/marketo-form/fixtures/index.ts +0 -185
  65. package/src/components/marketo-form/form/index.tsx +0 -371
  66. package/src/components/marketo-form/index.test.tsx +0 -320
  67. package/src/components/marketo-form/index.ts +0 -11
  68. package/src/components/marketo-form/package.original.json +0 -30
  69. package/src/components/marketo-form/partials/error-message/index.tsx +0 -12
  70. package/src/components/marketo-form/partials/error-message/style.module.css +0 -13
  71. package/src/components/marketo-form/partials/field/index.tsx +0 -90
  72. package/src/components/marketo-form/partials/field-wrapper/index.tsx +0 -26
  73. package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +0 -32
  74. package/src/components/marketo-form/partials/fields/email-field/index.tsx +0 -35
  75. package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +0 -23
  76. package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +0 -38
  77. package/src/components/marketo-form/partials/fields/htmltext-field/index.tsx +0 -21
  78. package/src/components/marketo-form/partials/fields/htmltext-field/style.module.css +0 -18
  79. package/src/components/marketo-form/partials/fields/name-field/index.tsx +0 -19
  80. package/src/components/marketo-form/partials/fields/name-field/style.module.css +0 -13
  81. package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +0 -48
  82. package/src/components/marketo-form/partials/fields/select-field/index.tsx +0 -39
  83. package/src/components/marketo-form/partials/fields/select-field/style.module.css +0 -5
  84. package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +0 -30
  85. package/src/components/marketo-form/partials/fields/text-field/index.tsx +0 -30
  86. package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +0 -29
  87. package/src/components/marketo-form/partials/label/index.tsx +0 -24
  88. package/src/components/marketo-form/partials/label/style.module.css +0 -12
  89. package/src/components/marketo-form/partials/visibility-rule/index.tsx +0 -84
  90. package/src/components/marketo-form/props.js +0 -66
  91. package/src/components/marketo-form/server/api-routes.ts +0 -109
  92. package/src/components/marketo-form/server/client.ts +0 -98
  93. package/src/components/marketo-form/server/index.ts +0 -8
  94. package/src/components/marketo-form/types.ts +0 -268
  95. package/src/components/marketo-form/utils.test.tsx +0 -103
  96. package/src/components/marketo-form/utils.ts +0 -449
  97. package/src/components/next-steps/index.tsx +0 -138
  98. package/src/components/next-steps/style.module.css +0 -270
  99. package/src/components/next-steps/types.ts +0 -63
  100. package/src/components/product-badge/index.test.tsx +0 -11
  101. package/src/components/product-badge/index.tsx +0 -42
  102. package/src/components/product-badge/style.module.css +0 -76
  103. package/src/components/products-used/index.tsx +0 -84
  104. package/src/components/products-used/style.module.css +0 -87
  105. package/src/components/products-used/types.ts +0 -31
  106. package/src/components/related-content/index.test.tsx +0 -74
  107. package/src/components/related-content/index.tsx +0 -56
  108. package/src/components/related-content/style.module.css +0 -89
  109. package/src/components/related-content/types.ts +0 -21
  110. package/src/components/subnav/helpers/areBasePathsMatching.ts +0 -13
  111. package/src/components/subnav/helpers/traverse/index.ts +0 -42
  112. package/src/components/subnav/helpers/useHeightRef.ts +0 -42
  113. package/src/components/subnav/helpers/useNavRef.ts +0 -30
  114. package/src/components/subnav/helpers/useOverflowRef.ts +0 -85
  115. package/src/components/subnav/helpers/useStuckRef.ts +0 -51
  116. package/src/components/subnav/index.tsx +0 -203
  117. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.test.ts +0 -26
  118. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.ts +0 -22
  119. package/src/components/subnav/partials/CtaLinks/github-stars-link/index.tsx +0 -87
  120. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.test.ts +0 -29
  121. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.ts +0 -32
  122. package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +0 -81
  123. package/src/components/subnav/partials/CtaLinks/icons/github-logo.js +0 -20
  124. package/src/components/subnav/partials/CtaLinks/icons/github.svg.js +0 -7
  125. package/src/components/subnav/partials/CtaLinks/icons/star.js +0 -20
  126. package/src/components/subnav/partials/CtaLinks/index.tsx +0 -131
  127. package/src/components/subnav/partials/CtaLinks/style.module.css +0 -45
  128. package/src/components/subnav/partials/DropdownTrigger/index.tsx +0 -35
  129. package/src/components/subnav/partials/DropdownTrigger/style.module.css +0 -39
  130. package/src/components/subnav/partials/MenuItemsDefault/index.tsx +0 -158
  131. package/src/components/subnav/partials/MenuItemsDefault/style.module.css +0 -104
  132. package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +0 -143
  133. package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +0 -88
  134. package/src/components/subnav/partials/TitleLink/index.tsx +0 -113
  135. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +0 -10
  136. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +0 -10
  137. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-dark.ts +0 -23
  138. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-light.ts +0 -23
  139. package/src/components/subnav/partials/TitleLink/style.module.css +0 -43
  140. package/src/components/subnav/partials/nav-item-text/index.tsx +0 -37
  141. package/src/components/subnav/partials/nav-item-text/style.module.css +0 -13
  142. package/src/components/subnav/style.module.css +0 -66
  143. package/src/components/subnav/subnav-consts.ts +0 -1
@@ -1,71 +0,0 @@
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 { PersonCard } from './index'
8
-
9
- const defaultProps = {
10
- link: 'https://hashicorp.com',
11
- name: 'Example name',
12
- bio: 'Example bio',
13
- location: 'Example location',
14
- meta: ['August 15, 2022', 'Category'],
15
- thumbnail: {
16
- src: 'https://www.datocms-assets.com/19447/1648680074-screenshot-2022-03-31-at-00-40-47.png',
17
- alt: 'HashiConf Europe 2022 Recap',
18
- },
19
- }
20
-
21
- describe('<PersonCard />', () => {
22
- // Prop tests
23
- it('should render the provided name prop', () => {
24
- render(<PersonCard {...defaultProps} />)
25
-
26
- const name = screen.getByText(defaultProps.name)
27
- expect(name.tagName).toBe('H2')
28
- })
29
-
30
- it('should render the provided bio prop', () => {
31
- render(<PersonCard {...defaultProps} />)
32
-
33
- const bio = screen.getByText(defaultProps.bio)
34
- expect(bio.tagName).toBe('P')
35
- })
36
-
37
- it('should render the provided location prop', () => {
38
- render(<PersonCard {...defaultProps} />)
39
-
40
- const location = screen.getByText(defaultProps.location)
41
- expect(location.tagName).toBe('P')
42
- })
43
-
44
- it('should render the correct thumbnail icon based on the provided link prop', () => {
45
- const links = {
46
- github: 'https://github.com',
47
- twitter: 'https://twitter.com',
48
- linkedin: 'https://linkedin.com',
49
- link: 'https://example.com',
50
- mail: 'mailto:name@example.com',
51
- }
52
-
53
- render(
54
- <>
55
- {Object.keys(links).map((platform) => (
56
- <PersonCard key={platform} {...defaultProps} link={links[platform]} />
57
- ))}
58
- </>
59
- )
60
-
61
- Object.keys(links).forEach((platform) => {
62
- screen.getByTestId(`wpl-personcard-${platform}-icon`)
63
- })
64
- })
65
-
66
- it('should not render a thumbnail icon when link is on hashicorp.com', () => {
67
- render(<PersonCard {...defaultProps} link="https://hashicorp.com" />)
68
-
69
- expect(screen.queryByTestId('wpl-personcard-link-icon')).toBeNull()
70
- })
71
- })
@@ -1,93 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import { memo, type ReactNode } from 'react'
7
- import { TextPlus } from '@hashicorp/react-hds/src/components/text'
8
- import { IconGithub16 } from '@hashicorp/flight-icons/svg-react/github-16'
9
- import { IconTwitter16 } from '@hashicorp/flight-icons/svg-react/twitter-16'
10
- import { IconLinkedin16 } from '@hashicorp/flight-icons/svg-react/linkedin-16'
11
- import { IconLink16 } from '@hashicorp/flight-icons/svg-react/link-16'
12
- import { IconMail16 } from '@hashicorp/flight-icons/svg-react/mail-16'
13
- import type { ProductBadgesProps, ThumbnailProps } from '../types'
14
- import * as CardPrimitives from '../primitives'
15
- import s from './style.module.css'
16
-
17
- export interface PersonCardProps {
18
- thumbnail: ThumbnailProps
19
- link: string
20
- name: string
21
- location?: string
22
- bio?: string
23
- productBadges?: ProductBadgesProps['badges']
24
- }
25
-
26
- // Map of hostnames to icons.
27
- /* eslint-disable react/jsx-key */
28
- const iconMap = new Map<string, ReactNode>([
29
- // null signals that we don't want to render any icon
30
- ['hashicorp.com', null],
31
- [
32
- 'twitter.com',
33
- <IconTwitter16 data-testid={'wpl-personcard-twitter-icon'} />,
34
- ],
35
- ['github.com', <IconGithub16 data-testid={'wpl-personcard-github-icon'} />],
36
- [
37
- 'linkedin.com',
38
- <IconLinkedin16 data-testid={'wpl-personcard-linkedin-icon'} />,
39
- ],
40
- ['mailto:', <IconMail16 data-testid={'wpl-personcard-mail-icon'} />],
41
- ])
42
- /* eslint-enable react/jsx-key */
43
-
44
- const Icon = memo(function Icon({ url }: { url: string }) {
45
- const { protocol, host } = new URL(url)
46
- const icon = iconMap.get(protocol === 'mailto:' ? 'mailto:' : host)
47
-
48
- // If the icon value is null, don't render an icon
49
- if (icon === null) {
50
- return null
51
- }
52
-
53
- // Render the icon or the default icon if the icon value is undefined
54
- return (
55
- <div className={s.thumbnailIcon}>
56
- {icon ?? <IconLink16 data-testid={'wpl-personcard-link-icon'} />}
57
- </div>
58
- )
59
- })
60
-
61
- export function PersonCard({
62
- link,
63
- thumbnail,
64
- name,
65
- location,
66
- bio,
67
- productBadges,
68
- }: PersonCardProps) {
69
- return (
70
- <CardPrimitives.Card heading={name} link={link} withArrow={false}>
71
- <div className={s.thumbnailContainer}>
72
- <CardPrimitives.PersonThumbnail {...thumbnail} />
73
- <Icon url={link} />
74
- </div>
75
- <CardPrimitives.Content>
76
- <div>
77
- <CardPrimitives.Heading>{name}</CardPrimitives.Heading>
78
- {location ? (
79
- <TextPlus.Body tag="p" size="200" className={s.location}>
80
- {location}
81
- </TextPlus.Body>
82
- ) : null}
83
- </div>
84
- {bio ? (
85
- <CardPrimitives.Description>{bio}</CardPrimitives.Description>
86
- ) : null}
87
- {productBadges && productBadges?.length > 0 ? (
88
- <CardPrimitives.ProductBadges badges={productBadges} />
89
- ) : null}
90
- </CardPrimitives.Content>
91
- </CardPrimitives.Card>
92
- )
93
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- .location {
7
- margin: 0;
8
- color: var(--token-color-foreground-faint);
9
- }
10
-
11
- .thumbnailContainer {
12
- position: relative;
13
- }
14
-
15
- .thumbnailIcon {
16
- --size: 40px;
17
-
18
- position: absolute;
19
- bottom: 20px;
20
- right: 20px;
21
- width: var(--size);
22
- height: var(--size);
23
- display: grid;
24
- place-items: center;
25
- border-radius: 9999px;
26
- overflow: hidden;
27
- background-color: white;
28
- opacity: 0.5;
29
-
30
- & svg {
31
- position: relative;
32
- }
33
- }
@@ -1,177 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import * as React from 'react'
7
- import classNames from 'classnames'
8
- import Image from 'next/image'
9
- import Link from 'next/link'
10
- import HDSCard from '@hashicorp/react-hds/src/components/card'
11
- import { TextPlus } from '@hashicorp/react-hds/src/components/text'
12
- import { IconArrowRight24 } from '@hashicorp/flight-icons/svg-react/arrow-right-24'
13
- import ProductBadge from '../product-badge'
14
- import type {
15
- CardPrimitiveProps,
16
- ThumbnailProps,
17
- MetaProps,
18
- ContentProps,
19
- HeadingProps,
20
- ProductBadgesProps,
21
- DescriptionProps,
22
- } from './types'
23
- import s from './style.module.css'
24
-
25
- const Card = React.forwardRef<HTMLAnchorElement, CardPrimitiveProps>(
26
- (props, ref) => {
27
- const {
28
- withArrow = true,
29
- heading,
30
- link,
31
- clickHandler,
32
- isExternal,
33
- hasBorder = true,
34
- children,
35
- className,
36
- 'aria-label': ariaLabel,
37
- } = props
38
-
39
- const linkProps = isExternal
40
- ? { target: '_blank', rel: 'noopener noreferrer' }
41
- : {}
42
-
43
- return (
44
- <HDSCard
45
- level="mid"
46
- levelHover="high"
47
- className={classNames(s.card, className)}
48
- overflow="hidden"
49
- hasBorder={hasBorder}
50
- >
51
- <div className={s.contentContainer}>
52
- {children}
53
-
54
- <div className={s.cta} data-testid="wpl-card-cta">
55
- {withArrow ? <IconArrowRight24 /> : null}
56
- </div>
57
-
58
- <Link
59
- href={link}
60
- ref={ref}
61
- className={s.link}
62
- aria-label={ariaLabel ?? heading}
63
- onClickCapture={clickHandler}
64
- {...linkProps}
65
- />
66
- </div>
67
- </HDSCard>
68
- )
69
- }
70
- )
71
-
72
- function Thumbnail({ src, alt }: ThumbnailProps) {
73
- return (
74
- <div className={s.thumbnail} data-testid="wpl-card-thumbnail">
75
- <div className={s.image}>
76
- <Image src={src} alt={alt} width={800} height={450} />
77
- </div>
78
- </div>
79
- )
80
- }
81
-
82
- function PersonThumbnail({ src, alt }: ThumbnailProps) {
83
- return (
84
- <div className={s.personThumbnail} data-testid="wpl-card-thumbnail">
85
- <div className={s.image}>
86
- <Image src={src} alt={alt} width={800} height={450} />
87
- </div>
88
- </div>
89
- )
90
- }
91
-
92
- function LogoThumbnail({ src, alt }: ThumbnailProps) {
93
- return (
94
- <div className={s.logoThumbnail} data-testid="wpl-card-logo-thumbnail">
95
- <div className={s.image}>
96
- <Image src={src} alt={alt} width={800} height={450} />
97
- </div>
98
- </div>
99
- )
100
- }
101
-
102
- function Meta({ items }: MetaProps) {
103
- return (
104
- <div className={s.meta} data-testid="wpl-card-meta">
105
- <TextPlus.Label>
106
- {items.map((item, stableIdx) => {
107
- const isLastItem = stableIdx === items.length - 1
108
- return (
109
- <>
110
- {item}
111
- {!isLastItem ? (
112
- <span className={s.metaSeparator} aria-hidden={true}>
113
- |
114
- </span>
115
- ) : null}
116
- </>
117
- )
118
- })}
119
- </TextPlus.Label>
120
- </div>
121
- )
122
- }
123
-
124
- function Content({ children }: ContentProps) {
125
- return (
126
- <div className={s.content} data-testid="wpl-card-content">
127
- {children}
128
- </div>
129
- )
130
- }
131
-
132
- function Heading({ as = 'h2', children }: HeadingProps) {
133
- return (
134
- <TextPlus.DisplayExpressive tag={as} size="200" className={s.heading}>
135
- {children}
136
- </TextPlus.DisplayExpressive>
137
- )
138
- }
139
-
140
- function ProductBadges({ badges, children }: ProductBadgesProps) {
141
- return (
142
- <div className={s.productBadges} data-testid="wpl-card-badges">
143
- {badges.map((badge, stableIdx) => {
144
- return (
145
- <ProductBadge
146
- // eslint-disable-next-line react/no-array-index-key
147
- key={`product-badge-${stableIdx}`}
148
- productName={badge}
149
- hasDot={true}
150
- />
151
- )
152
- })}
153
- {children}
154
- </div>
155
- )
156
- }
157
-
158
- function Description({ children }: DescriptionProps) {
159
- return (
160
- <TextPlus.Body tag="p" size="200" className={s.description}>
161
- {children}
162
- </TextPlus.Body>
163
- )
164
- }
165
-
166
- Card.displayName = 'Card'
167
- export {
168
- Card,
169
- Thumbnail,
170
- PersonThumbnail,
171
- LogoThumbnail,
172
- Meta,
173
- Content,
174
- Heading,
175
- Description,
176
- ProductBadges,
177
- }
@@ -1,51 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import * as CardPrimitives from '../primitives'
7
- import type { ThumbnailProps } from '../types'
8
-
9
- export interface PromoCardProps {
10
- heading: string
11
- description?: string
12
- eyebrow?: string
13
- link: string
14
- clickHandler?: () => void
15
- thumbnail?: ThumbnailProps
16
- withArrow?: boolean
17
- isExternal?: boolean
18
- className?: string
19
- }
20
-
21
- export function PromoCard({
22
- heading,
23
- description,
24
- eyebrow,
25
- link,
26
- clickHandler,
27
- thumbnail,
28
- withArrow = false,
29
- isExternal = false,
30
- className,
31
- }: PromoCardProps) {
32
- return (
33
- <CardPrimitives.Card
34
- heading={heading}
35
- link={link}
36
- withArrow={withArrow}
37
- isExternal={isExternal}
38
- className={className}
39
- clickHandler={clickHandler}
40
- >
41
- {thumbnail ? <CardPrimitives.Thumbnail {...thumbnail} /> : null}
42
- <CardPrimitives.Content>
43
- {eyebrow ? <CardPrimitives.Meta items={[eyebrow]} /> : null}
44
- <CardPrimitives.Heading>{heading}</CardPrimitives.Heading>
45
- {description ? (
46
- <CardPrimitives.Description>{description}</CardPrimitives.Description>
47
- ) : null}
48
- </CardPrimitives.Content>
49
- </CardPrimitives.Card>
50
- )
51
- }
@@ -1,48 +0,0 @@
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 { ResourceCard } from '.'
8
-
9
- const defaultProps = {
10
- link: 'https://hashicorp.com',
11
- heading: 'Example heading',
12
- date: 'August 15, 2022',
13
- category: 'Category',
14
- thumbnail: {
15
- src: 'https://www.datocms-assets.com/19447/1648680074-screenshot-2022-03-31-at-00-40-47.png',
16
- alt: 'HashiConf Europe 2022 Recap',
17
- },
18
- }
19
-
20
- describe('<ResourceCard />', () => {
21
- it('should render the provided date and category with separator', () => {
22
- const expectedMeta = [defaultProps.date, defaultProps.category]
23
-
24
- render(<ResourceCard {...defaultProps} />)
25
-
26
- const metaElement = screen.getByTestId('wpl-card-meta')
27
-
28
- expectedMeta.forEach((item) => {
29
- expect(metaElement).toHaveTextContent(item)
30
- })
31
-
32
- expect(metaElement).toContainElement(screen.getByText('|'))
33
- })
34
-
35
- it('should not render the date if no date is provided', () => {
36
- const defaultPropsWithoutDate = { ...defaultProps, date: '' }
37
-
38
- render(<ResourceCard {...defaultPropsWithoutDate} />)
39
-
40
- const metaElement = screen.getByTestId('wpl-card-meta')
41
-
42
- expect(metaElement).toContainElement(
43
- screen.getByText(defaultProps.category)
44
- )
45
-
46
- expect(metaElement).not.toContainElement(screen.queryByText('|'))
47
- })
48
- })
@@ -1,37 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import type { CardProps, ThumbnailProps } from '../types'
7
- import { UnifiedCard } from '../unified-card'
8
-
9
- export interface ResourceCardProps {
10
- heading: string
11
- date?: string
12
- category: string
13
- link: string
14
- productBadges?: CardProps['productBadges']
15
- thumbnail: ThumbnailProps
16
- }
17
-
18
- export function ResourceCard({
19
- heading,
20
- date,
21
- category,
22
- link,
23
- productBadges,
24
- thumbnail,
25
- }: ResourceCardProps) {
26
- const meta: string[] = date ? [date, category] : [category]
27
-
28
- return (
29
- <UnifiedCard
30
- heading={heading}
31
- link={link}
32
- meta={meta}
33
- productBadges={productBadges}
34
- thumbnail={thumbnail}
35
- />
36
- )
37
- }
@@ -1,145 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- .card {
7
- display: flex;
8
- flex-direction: column;
9
- flex-grow: 1;
10
- transition: 0.2s ease;
11
- transition-property: transform, box-shadow, border-color, background-color;
12
-
13
- &:hover {
14
- transform: translateY(-2px);
15
-
16
- & .cta svg {
17
- transform: translateX(2px);
18
- }
19
- }
20
-
21
- &.dark {
22
- & .thumbnail {
23
- border-bottom: 0;
24
- }
25
- }
26
-
27
- &:focus-within {
28
- outline-color: var(--token-color-focus-action-external);
29
- outline-width: 2px;
30
- outline-style: solid;
31
- outline-offset: 0;
32
- }
33
- }
34
-
35
- .contentContainer {
36
- display: flex;
37
- flex-direction: column;
38
- flex-grow: 1;
39
- overflow: hidden;
40
- position: relative;
41
- }
42
-
43
- .link {
44
- position: absolute;
45
- inset: 0;
46
- outline: none;
47
- }
48
-
49
- .thumbnail {
50
- & .image {
51
- position: relative;
52
- display: grid;
53
- aspect-ratio: 16 / 9;
54
- overflow: hidden;
55
-
56
- & img {
57
- object-fit: cover;
58
- object-position: center;
59
- width: 100%;
60
- height: 100%;
61
- }
62
- }
63
- }
64
-
65
- .personThumbnail {
66
- composes: thumbnail;
67
- & .image {
68
- aspect-ratio: 4 / 3;
69
- }
70
- }
71
-
72
- .logoThumbnail {
73
- composes: thumbnail;
74
- padding: var(--hdsplus-spacing-07);
75
-
76
- & .image {
77
- aspect-ratio: none;
78
-
79
- & img {
80
- aspect-ratio: 16 / 9;
81
- object-fit: contain;
82
- }
83
- }
84
- }
85
-
86
- .meta {
87
- color: var(--token-color-foreground-faint);
88
- text-transform: uppercase;
89
- margin: 0;
90
- display: flex;
91
- flex-wrap: wrap;
92
- list-style: none;
93
- padding: 0;
94
- }
95
-
96
- .metaSeparator {
97
- --padding-x: 12px;
98
-
99
- padding-left: var(--padding-x);
100
- padding-right: var(--padding-x);
101
- }
102
-
103
- .content {
104
- display: flex;
105
- flex-direction: column;
106
- flex-grow: 1;
107
- row-gap: 16px;
108
- padding: 20px 20px 0 20px;
109
- }
110
-
111
- .heading {
112
- font-weight: var(--token-typography-font-weight-bold);
113
- color: var(--token-color-foreground-strong);
114
- margin: 0;
115
- }
116
-
117
- .description {
118
- color: var(--token-color-foreground-primary);
119
- margin: 0;
120
- }
121
-
122
- .productBadges {
123
- margin-top: auto;
124
- display: flex;
125
- flex-wrap: wrap;
126
- gap: 8px;
127
- }
128
-
129
- .cta {
130
- display: flex;
131
- align-items: center;
132
- justify-content: flex-end;
133
- color: var(--token-color-foreground-primary);
134
- padding: 8px 20px 20px 20px;
135
- margin-top: auto;
136
- transition: color 0.25s ease;
137
-
138
- & svg {
139
- transition: transform 0.25s ease;
140
- }
141
-
142
- &:empty {
143
- padding-top: 0;
144
- }
145
- }