@hashicorp/react-components 0.0.0-nightly.f535c63 → 0.0.0-nightly.f8bc604

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 (160) hide show
  1. package/package.json +3 -7
  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 +9 -4
  5. package/src/components/nav-panel/components/link-list/style.module.css +10 -10
  6. package/src/components/nav-panel/components/panel/column/style.module.css +2 -2
  7. package/src/components/nav-panel/components/panel/root/style.module.css +5 -5
  8. package/src/components/nav-panel/components/promo/index.tsx +9 -3
  9. package/src/components/nav-panel/components/promo/style.module.css +22 -12
  10. package/src/components/nav-panel/components/text/index.tsx +34 -0
  11. package/src/components/nav-panel/product-panel/index.tsx +30 -14
  12. package/src/components/nav-panel/product-panel/style.module.css +63 -36
  13. package/src/components/nav-panel/standard-panel/index.tsx +3 -0
  14. package/src/components/nav-panel/standard-panel/style.module.css +2 -2
  15. package/src/lib/get-localized-link-props/index.test.ts +30 -0
  16. package/src/lib/get-localized-link-props/index.ts +45 -0
  17. package/src/lib/parse-url/index.test.ts +35 -1
  18. package/src/lib/parse-url/index.ts +75 -9
  19. package/src/lib/send-posthog-event/index.ts +22 -0
  20. package/src/lib/supported-locales/index.ts +1 -0
  21. package/src/lib/track-nav-click-event/index.ts +4 -4
  22. package/src/components/actions/index.tsx +0 -107
  23. package/src/components/actions/style.module.css +0 -28
  24. package/src/components/actions/types.ts +0 -73
  25. package/src/components/call-to-action/index.tsx +0 -205
  26. package/src/components/call-to-action/styles/variant-centered.module.css +0 -93
  27. package/src/components/call-to-action/styles/variant-compact-grid.module.css +0 -88
  28. package/src/components/call-to-action/styles/variant-compact.module.css +0 -91
  29. package/src/components/call-to-action/styles/variant-links.module.css +0 -85
  30. package/src/components/card/README.md +0 -11
  31. package/src/components/card/card.tsx +0 -45
  32. package/src/components/card/index.test.tsx +0 -69
  33. package/src/components/card/index.tsx +0 -14
  34. package/src/components/card/newsroom-card/index.test.tsx +0 -39
  35. package/src/components/card/newsroom-card/index.tsx +0 -37
  36. package/src/components/card/newsroom-card/style.module.css +0 -12
  37. package/src/components/card/partner-card/index.test.tsx +0 -57
  38. package/src/components/card/partner-card/index.tsx +0 -69
  39. package/src/components/card/partner-card/style.module.css +0 -24
  40. package/src/components/card/person-card/index.test.tsx +0 -71
  41. package/src/components/card/person-card/index.tsx +0 -93
  42. package/src/components/card/person-card/style.module.css +0 -33
  43. package/src/components/card/primitives.tsx +0 -177
  44. package/src/components/card/promo-card/index.tsx +0 -51
  45. package/src/components/card/resource-card/index.test.tsx +0 -48
  46. package/src/components/card/resource-card/index.tsx +0 -37
  47. package/src/components/card/style.module.css +0 -145
  48. package/src/components/card/types.ts +0 -66
  49. package/src/components/card/unified-card/index.tsx +0 -58
  50. package/src/components/consent-manager/README.md +0 -73
  51. package/src/components/consent-manager/components/banner/banner.module.css +0 -23
  52. package/src/components/consent-manager/components/banner/banner.test.tsx +0 -31
  53. package/src/components/consent-manager/components/banner/banner.tsx +0 -73
  54. package/src/components/consent-manager/components/dialog/dialog.module.css +0 -145
  55. package/src/components/consent-manager/components/dialog/dialog.test.tsx +0 -194
  56. package/src/components/consent-manager/components/dialog/dialog.tsx +0 -339
  57. package/src/components/consent-manager/img/icn_close.tsx +0 -19
  58. package/src/components/consent-manager/index.test.tsx +0 -334
  59. package/src/components/consent-manager/index.tsx +0 -186
  60. package/src/components/consent-manager/loader/README.md +0 -29
  61. package/src/components/consent-manager/loader/categories.ts +0 -22
  62. package/src/components/consent-manager/loader/index.tsx +0 -94
  63. package/src/components/consent-manager/loader/presets/enterprise.ts +0 -12
  64. package/src/components/consent-manager/loader/presets/oss.ts +0 -10
  65. package/src/components/consent-manager/loader/services.ts +0 -45
  66. package/src/components/consent-manager/scripts/custom.tsx +0 -59
  67. package/src/components/consent-manager/scripts/segment.tsx +0 -87
  68. package/src/components/consent-manager/style.module.css +0 -9
  69. package/src/components/consent-manager/types.ts +0 -55
  70. package/src/components/consent-manager/util/cookies.test.ts +0 -75
  71. package/src/components/consent-manager/util/cookies.ts +0 -70
  72. package/src/components/consent-manager/util/integrations.test.ts +0 -115
  73. package/src/components/consent-manager/util/integrations.ts +0 -110
  74. package/src/components/intro/index.tsx +0 -82
  75. package/src/components/intro/style.module.css +0 -67
  76. package/src/components/intro/types.ts +0 -44
  77. package/src/components/marketo-form/CHANGELOG.md +0 -122
  78. package/src/components/marketo-form/README.md +0 -1
  79. package/src/components/marketo-form/contexts/FormMetadata.ts +0 -11
  80. package/src/components/marketo-form/docs.mdx +0 -197
  81. package/src/components/marketo-form/fixtures/index.ts +0 -185
  82. package/src/components/marketo-form/form/index.tsx +0 -369
  83. package/src/components/marketo-form/index.test.tsx +0 -320
  84. package/src/components/marketo-form/index.ts +0 -11
  85. package/src/components/marketo-form/package.original.json +0 -30
  86. package/src/components/marketo-form/partials/error-message/index.tsx +0 -12
  87. package/src/components/marketo-form/partials/error-message/style.module.css +0 -13
  88. package/src/components/marketo-form/partials/field/index.tsx +0 -90
  89. package/src/components/marketo-form/partials/field-wrapper/index.tsx +0 -26
  90. package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +0 -32
  91. package/src/components/marketo-form/partials/fields/email-field/index.tsx +0 -35
  92. package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +0 -21
  93. package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +0 -37
  94. package/src/components/marketo-form/partials/fields/htmltext-field/index.tsx +0 -21
  95. package/src/components/marketo-form/partials/fields/htmltext-field/style.module.css +0 -18
  96. package/src/components/marketo-form/partials/fields/name-field/index.tsx +0 -19
  97. package/src/components/marketo-form/partials/fields/name-field/style.module.css +0 -13
  98. package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +0 -48
  99. package/src/components/marketo-form/partials/fields/select-field/index.tsx +0 -39
  100. package/src/components/marketo-form/partials/fields/select-field/style.module.css +0 -5
  101. package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +0 -30
  102. package/src/components/marketo-form/partials/fields/text-field/index.tsx +0 -30
  103. package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +0 -29
  104. package/src/components/marketo-form/partials/label/index.tsx +0 -24
  105. package/src/components/marketo-form/partials/label/style.module.css +0 -12
  106. package/src/components/marketo-form/partials/visibility-rule/index.tsx +0 -84
  107. package/src/components/marketo-form/props.js +0 -66
  108. package/src/components/marketo-form/server/api-routes.ts +0 -109
  109. package/src/components/marketo-form/server/client.ts +0 -98
  110. package/src/components/marketo-form/server/index.ts +0 -8
  111. package/src/components/marketo-form/types.ts +0 -268
  112. package/src/components/marketo-form/utils.test.tsx +0 -103
  113. package/src/components/marketo-form/utils.ts +0 -449
  114. package/src/components/next-steps/index.tsx +0 -137
  115. package/src/components/next-steps/style.module.css +0 -270
  116. package/src/components/next-steps/types.ts +0 -63
  117. package/src/components/product-badge/index.test.tsx +0 -11
  118. package/src/components/product-badge/index.tsx +0 -42
  119. package/src/components/product-badge/style.module.css +0 -76
  120. package/src/components/products-used/index.tsx +0 -84
  121. package/src/components/products-used/style.module.css +0 -87
  122. package/src/components/products-used/types.ts +0 -31
  123. package/src/components/related-content/index.test.tsx +0 -74
  124. package/src/components/related-content/index.tsx +0 -56
  125. package/src/components/related-content/style.module.css +0 -89
  126. package/src/components/related-content/types.ts +0 -21
  127. package/src/components/subnav/helpers/areBasePathsMatching.ts +0 -13
  128. package/src/components/subnav/helpers/traverse/index.ts +0 -42
  129. package/src/components/subnav/helpers/useHeightRef.ts +0 -42
  130. package/src/components/subnav/helpers/useNavRef.ts +0 -30
  131. package/src/components/subnav/helpers/useOverflowRef.ts +0 -85
  132. package/src/components/subnav/helpers/useStuckRef.ts +0 -51
  133. package/src/components/subnav/index.tsx +0 -199
  134. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.test.ts +0 -26
  135. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.ts +0 -22
  136. package/src/components/subnav/partials/CtaLinks/github-stars-link/index.tsx +0 -87
  137. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.test.ts +0 -29
  138. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.ts +0 -32
  139. package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +0 -81
  140. package/src/components/subnav/partials/CtaLinks/icons/github-logo.js +0 -20
  141. package/src/components/subnav/partials/CtaLinks/icons/github.svg.js +0 -7
  142. package/src/components/subnav/partials/CtaLinks/icons/star.js +0 -20
  143. package/src/components/subnav/partials/CtaLinks/index.tsx +0 -130
  144. package/src/components/subnav/partials/CtaLinks/style.module.css +0 -45
  145. package/src/components/subnav/partials/DropdownTrigger/index.tsx +0 -35
  146. package/src/components/subnav/partials/DropdownTrigger/style.module.css +0 -39
  147. package/src/components/subnav/partials/MenuItemsDefault/index.tsx +0 -158
  148. package/src/components/subnav/partials/MenuItemsDefault/style.module.css +0 -104
  149. package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +0 -143
  150. package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +0 -88
  151. package/src/components/subnav/partials/TitleLink/index.tsx +0 -113
  152. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +0 -10
  153. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +0 -10
  154. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-dark.ts +0 -23
  155. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-light.ts +0 -23
  156. package/src/components/subnav/partials/TitleLink/style.module.css +0 -43
  157. package/src/components/subnav/partials/nav-item-text/index.tsx +0 -37
  158. package/src/components/subnav/partials/nav-item-text/style.module.css +0 -13
  159. package/src/components/subnav/style.module.css +0 -66
  160. package/src/components/subnav/subnav-consts.ts +0 -1
@@ -1,69 +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 Card from './'
8
-
9
- const defaultProps = {
10
- link: 'https://hashicorp.com',
11
- heading: 'Example heading',
12
- description: 'Example description',
13
- meta: ['August 15, 2022', '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('<Card />', () => {
21
- // Prop tests
22
- it('should render the provided link prop', () => {
23
- render(<Card {...defaultProps} />)
24
-
25
- expect(screen.getByRole('link')).toHaveAttribute('href', defaultProps.link)
26
- })
27
-
28
- it('should render the provided heading prop', () => {
29
- render(<Card {...defaultProps} />)
30
-
31
- const heading = screen.getByText(defaultProps.heading)
32
- expect(heading.tagName).toBe('H2')
33
- })
34
-
35
- it('should render the provided description prop', () => {
36
- render(<Card {...defaultProps} />)
37
-
38
- const description = screen.getByText(defaultProps.description)
39
- expect(description.tagName).toBe('P')
40
- })
41
-
42
- it('should render the provided meta prop (single item)', () => {
43
- const cardMeta = ['Category']
44
-
45
- render(<Card {...defaultProps} meta={cardMeta} />)
46
-
47
- const metaElement = screen.getByTestId('wpl-card-meta')
48
- expect(metaElement).toContainElement(screen.getByText(cardMeta[0]))
49
- })
50
-
51
- it('should render the provided meta prop (two items)', () => {
52
- const cardMeta = ['August 15, 2022', 'Category']
53
-
54
- render(<Card {...defaultProps} />)
55
-
56
- const metaElement = screen.getByTestId('wpl-card-meta')
57
-
58
- cardMeta.forEach((item) => {
59
- expect(metaElement).toContainElement(screen.getByText(item))
60
- })
61
- expect(metaElement).toContainElement(screen.getByText('|'))
62
- })
63
-
64
- it('should render the provided thumbnail prop', () => {
65
- const { getByAltText } = render(<Card {...defaultProps} />)
66
-
67
- expect(getByAltText(defaultProps.thumbnail.alt).tagName).toBe('IMG')
68
- })
69
- })
@@ -1,14 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import Card from './card'
7
- import { NewsroomCard } from './newsroom-card'
8
- import { PersonCard } from './person-card'
9
- import { ResourceCard } from './resource-card'
10
- import { UnifiedCard } from './unified-card'
11
- import { PromoCard } from './promo-card'
12
-
13
- export default Card
14
- export { NewsroomCard, PersonCard, ResourceCard, UnifiedCard, PromoCard }
@@ -1,39 +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 { NewsroomCard } from '.'
8
-
9
- const defaultProps = {
10
- link: 'https://hashicorp.com',
11
- heading: 'Example heading',
12
- date: 'August 15, 2022',
13
- category: 'Post type',
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('<NewsroomCard />', () => {
21
- it('should render the provided metadata correctly', () => {
22
- const expectedMeta = [defaultProps.date, defaultProps.category]
23
-
24
- render(<NewsroomCard {...defaultProps} />)
25
-
26
- const metaElement = screen.getByTestId('wpl-card-meta')
27
-
28
- expectedMeta.forEach((item) => {
29
- expect(metaElement).toContainElement(screen.getByText(item))
30
- })
31
-
32
- expect(metaElement).toContainElement(screen.queryByText('|'))
33
- })
34
-
35
- it('should not render the logo thumbnail if no thumbnail data provided', () => {
36
- render(<NewsroomCard {...defaultProps} thumbnail={undefined} />)
37
- expect(screen.queryByTestId('wpl-card-logo-thumbnail')).toBeNull()
38
- })
39
- })
@@ -1,37 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import type { ThumbnailProps } from '../types'
7
- import { UnifiedCard } from '../unified-card'
8
- import s from './style.module.css'
9
-
10
- export interface NewsroomCardProps {
11
- heading: string
12
- date: string
13
- category: string
14
- link: string
15
- thumbnail?: ThumbnailProps
16
- withArrow?: boolean
17
- }
18
-
19
- export function NewsroomCard({
20
- heading,
21
- date,
22
- category,
23
- link,
24
- thumbnail,
25
- withArrow = false,
26
- }: NewsroomCardProps): JSX.Element {
27
- return (
28
- <UnifiedCard
29
- heading={heading}
30
- meta={[date, category]}
31
- link={link}
32
- thumbnail={thumbnail}
33
- withArrow={withArrow}
34
- className={s.newsroomCard}
35
- />
36
- )
37
- }
@@ -1,12 +0,0 @@
1
- .newsroomCard {
2
- & img {
3
- padding: var(--hdsplus-spacing-07);
4
- aspect-ratio: 16 / 9;
5
-
6
- /*
7
- ! HACK: Overrides object-fit set by Thumbnail primitive in Card component styles
8
- Ref: https://github.com/hashicorp/web/blob/main/packages/react-components/src/components/card/style.module.css#L75
9
- */
10
- object-fit: contain !important;
11
- }
12
- }
@@ -1,57 +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 { PartnerCard } from '.'
8
-
9
- const defaultProps = {
10
- logo: {
11
- width: 360,
12
- src: 'https://www.datocms-assets.com/2885/1506535057-black.svg',
13
- height: 97,
14
- alt: 'GitHub Logo',
15
- },
16
- link: '#',
17
- heading: 'Github',
18
- description:
19
- 'GitHub, Inc. is a provider of Internet hosting for software development and version control using Git.',
20
- meta: ['Tech Partner'],
21
- }
22
-
23
- describe('<PartnerCard />', () => {
24
- it('should not render badges when none are provided', () => {
25
- render(<PartnerCard {...defaultProps} />)
26
-
27
- const badgeElement = screen.queryByTestId('wpl-card-badges')
28
-
29
- expect(badgeElement).toBeNull()
30
- })
31
-
32
- it('should render badges when badges are provided', () => {
33
- const competencyBadges = ['Infrastructure', 'Security']
34
-
35
- render(
36
- <PartnerCard {...defaultProps} competencyBadges={competencyBadges} />
37
- )
38
-
39
- const badgeElement = screen.getByTestId('wpl-card-badges')
40
-
41
- competencyBadges.forEach((item) => {
42
- expect(badgeElement).toContainElement(screen.getByText(item))
43
- })
44
- })
45
-
46
- it('should render badges when product badges are provided', () => {
47
- const productBadges = ['vault' as const, 'terraform' as const]
48
-
49
- render(<PartnerCard {...defaultProps} productBadges={productBadges} />)
50
-
51
- const badgeElement = screen.getByTestId('wpl-card-badges')
52
-
53
- productBadges.forEach((item) => {
54
- expect(badgeElement).toContainElement(screen.getByText(item))
55
- })
56
- })
57
- })
@@ -1,69 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import Image, { type ImageProps } from 'next/image'
7
- import Badge from '@hashicorp/react-design-system-components/src/components/badge'
8
- import FlightIcon from '@hashicorp/react-design-system-components/src/components/flight-icon'
9
- import { TextPlus } from '@hashicorp/react-design-system-components/src/components/text'
10
- import * as CardPrimitives from '../primitives'
11
- import type { CardProps } from '../types'
12
- import s from './style.module.css'
13
-
14
- export interface PartnerCardProps {
15
- heading: string
16
- description: string
17
- meta: string[]
18
- link: string
19
- productBadges?: CardProps['productBadges']
20
- competencyBadges?: string[]
21
- logo: ImageProps
22
- className?: string
23
- }
24
-
25
- export function PartnerCard({
26
- heading,
27
- description,
28
- meta,
29
- link,
30
- productBadges,
31
- competencyBadges,
32
- logo,
33
- className,
34
- }: PartnerCardProps) {
35
- const hasProductBadges = productBadges && productBadges.length > 0
36
- const hasCompetencyBadges = competencyBadges && competencyBadges.length > 0
37
-
38
- return (
39
- <CardPrimitives.Card
40
- heading={heading}
41
- link={link}
42
- withArrow={false}
43
- isExternal={false}
44
- className={className}
45
- >
46
- <div className={s.logoContainer}>
47
- <Image {...logo} alt={logo.alt} className={s.logo} />
48
- </div>
49
- <CardPrimitives.Content>
50
- <CardPrimitives.Meta items={meta} />
51
- <TextPlus.Body tag="p" size="200" className={s.description}>
52
- {description}
53
- </TextPlus.Body>
54
- {hasProductBadges || hasCompetencyBadges ? (
55
- <CardPrimitives.ProductBadges badges={productBadges || []}>
56
- {hasCompetencyBadges &&
57
- competencyBadges.map((competencyBadge, stableIdx) => (
58
- <Badge
59
- key={stableIdx}
60
- text={competencyBadge}
61
- icon={<FlightIcon name="dot" stretched />}
62
- />
63
- ))}
64
- </CardPrimitives.ProductBadges>
65
- ) : null}
66
- </CardPrimitives.Content>
67
- </CardPrimitives.Card>
68
- )
69
- }
@@ -1,24 +0,0 @@
1
- .description {
2
- -webkit-box-orient: vertical;
3
- display: -webkit-box;
4
- -webkit-line-clamp: 4;
5
- max-width: 100%;
6
- overflow: hidden;
7
- }
8
-
9
- .logoContainer {
10
- position: relative;
11
- display: flex;
12
- aspect-ratio: 16 / 9;
13
- overflow: hidden;
14
- align-items: center;
15
- justify-content: center;
16
- background: var(--token-color-surface-faint);
17
- }
18
-
19
- .logo {
20
- max-width: 232px;
21
- max-height: 64px;
22
- height: auto;
23
- width: auto;
24
- }
@@ -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-design-system-components/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-design-system-components/src/components/card'
11
- import { TextPlus } from '@hashicorp/react-design-system-components/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
- <ul className={s.meta} data-testid="wpl-card-meta">
105
- {items.map((item, stableIdx) => {
106
- return (
107
- // eslint-disable-next-line react/no-array-index-key
108
- <li key={stableIdx}>
109
- <TextPlus.Label>
110
- {item}
111
- {stableIdx < items.length - 1 ? (
112
- <span className={s.metaSeparator} aria-hidden={true}>
113
- |
114
- </span>
115
- ) : null}
116
- </TextPlus.Label>
117
- </li>
118
- )
119
- })}
120
- </ul>
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
- }