-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Homepage
<IoHomeCard />
component (#13151)
* init <Card /> component * fixes heading color * adds product logos and hover styles * update naming * simplifies inset spacing * use ternary and add key * removes repo link * removes need for camelCase package
- Loading branch information
1 parent
06d9068
commit 88ed132
Showing
4 changed files
with
465 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import * as React from 'react' | ||
import Link from 'next/link' | ||
import InlineSvg from '@hashicorp/react-inline-svg' | ||
import classNames from 'classnames' | ||
import { IconArrowRight16 } from '@hashicorp/flight-icons/svg-react/arrow-right-16' | ||
import { IconExternalLink16 } from '@hashicorp/flight-icons/svg-react/external-link-16' | ||
import { productLogos } from './product-logos' | ||
import s from './style.module.css' | ||
|
||
interface IoHomeCardProps { | ||
variant?: 'light' | 'gray' | 'dark' | ||
products?: Array<keyof typeof productLogos> | ||
link: { | ||
url: string | ||
type: 'inbound' | 'outbound' | ||
} | ||
inset?: 'none' | 'sm' | 'md' | ||
eyebrow?: string | ||
heading?: string | ||
description?: string | ||
children?: React.ReactNode | ||
} | ||
|
||
function IoHomeCard({ | ||
variant = 'light', | ||
products, | ||
link, | ||
inset = 'md', | ||
eyebrow, | ||
heading, | ||
description, | ||
children, | ||
}: IoHomeCardProps) { | ||
const LinkWrapper = ({ className, children }) => | ||
link.type === 'inbound' ? ( | ||
<Link href={link.url}> | ||
<a className={className}>{children}</a> | ||
</Link> | ||
) : ( | ||
<a | ||
className={className} | ||
href={link.url} | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
{children} | ||
</a> | ||
) | ||
|
||
return ( | ||
<article className={classNames(s.card)}> | ||
<LinkWrapper className={classNames(s[variant], s[inset])}> | ||
{children ? ( | ||
children | ||
) : ( | ||
<> | ||
{eyebrow ? <Eyebrow>{eyebrow}</Eyebrow> : null} | ||
{heading ? <Heading>{heading}</Heading> : null} | ||
{description ? <Description>{description}</Description> : null} | ||
</> | ||
)} | ||
<footer className={s.footer}> | ||
{products && ( | ||
<ul className={s.products}> | ||
{products.map((product, index) => { | ||
return ( | ||
<li key={index}> | ||
<InlineSvg className={s.logo} src={productLogos[product]} /> | ||
</li> | ||
) | ||
})} | ||
</ul> | ||
)} | ||
<span className={s.linkType}> | ||
{link.type === 'inbound' ? ( | ||
<IconArrowRight16 /> | ||
) : ( | ||
<IconExternalLink16 /> | ||
)} | ||
</span> | ||
</footer> | ||
</LinkWrapper> | ||
</article> | ||
) | ||
} | ||
|
||
interface EyebrowProps { | ||
children: string | ||
} | ||
|
||
function Eyebrow({ children }: EyebrowProps) { | ||
return <p className={s.eyebrow}>{children}</p> | ||
} | ||
|
||
interface HeadingProps { | ||
as?: 'h2' | 'h3' | 'h4' | ||
children: React.ReactNode | ||
} | ||
|
||
function Heading({ as: Component = 'h2', children }: HeadingProps) { | ||
return <Component className={s.heading}>{children}</Component> | ||
} | ||
|
||
interface DescriptionProps { | ||
children: string | ||
} | ||
|
||
function Description({ children }: DescriptionProps) { | ||
return <p className={s.description}>{children}</p> | ||
} | ||
|
||
IoHomeCard.Eyebrow = Eyebrow | ||
IoHomeCard.Heading = Heading | ||
IoHomeCard.Description = Description | ||
|
||
export default IoHomeCard |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export const productLogos = { | ||
boundary: require('@hashicorp/mktg-logos/product/boundary/logomark/color.svg?include'), | ||
consul: require('@hashicorp/mktg-logos/product/consul/logomark/color.svg?include'), | ||
nomad: require('@hashicorp/mktg-logos/product/nomad/logomark/color.svg?include'), | ||
packer: require('@hashicorp/mktg-logos/product/packer/logomark/color.svg?include'), | ||
terraform: require('@hashicorp/mktg-logos/product/terraform/logomark/color.svg?include'), | ||
vagrant: require('@hashicorp/mktg-logos/product/vagrant/logomark/color.svg?include'), | ||
vault: require('@hashicorp/mktg-logos/product/vault/logomark/color.svg?include'), | ||
waypoint: require('@hashicorp/mktg-logos/product/waypoint/logomark/color.svg?include'), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
.card { | ||
/* Radii */ | ||
--token-radius: 6px; | ||
|
||
/* Spacing */ | ||
--token-spacing-03: 8px; | ||
--token-spacing-04: 16px; | ||
--token-spacing-05: 24px; | ||
--token-spacing-06: 32px; | ||
|
||
/* Elevations */ | ||
--token-elevation-mid: 0 2px 3px rgba(101, 106, 118, 0.1), | ||
0 8px 16px -10px rgba(101, 106, 118, 0.2); | ||
--token-elevation-high: 0 2px 3px rgba(101, 106, 118, 0.15), | ||
0 16px 16px -10px rgba(101, 106, 118, 0.2); | ||
|
||
/* Transition */ | ||
--token-transition: ease-in-out 0.2s; | ||
|
||
display: flex; | ||
flex-direction: column; | ||
flex-grow: 1; | ||
min-height: 300px; | ||
|
||
& a { | ||
display: flex; | ||
flex-direction: column; | ||
flex-grow: 1; | ||
border-radius: var(--token-radius); | ||
box-shadow: 0 0 0 1px rgba(38, 53, 61, 0.1), var(--token-elevation-mid); | ||
transition: var(--token-transition); | ||
transition-property: background-color, box-shadow; | ||
|
||
&:hover { | ||
box-shadow: 0 0 0 2px rgba(38, 53, 61, 0.15), var(--token-elevation-high); | ||
cursor: pointer; | ||
} | ||
|
||
/* Variants */ | ||
&.dark { | ||
background-color: var(--gray-1); | ||
|
||
&:hover { | ||
background-color: var(--gray-2); | ||
} | ||
} | ||
|
||
&.gray { | ||
background-color: #f9f9fa; | ||
} | ||
|
||
&.light { | ||
background-color: var(--white); | ||
} | ||
|
||
/* Spacing */ | ||
&.none { | ||
padding: 0; | ||
} | ||
|
||
&.sm { | ||
padding: var(--token-spacing-05); | ||
} | ||
|
||
&.md { | ||
padding: var(--token-spacing-06); | ||
} | ||
} | ||
} | ||
|
||
.eyebrow { | ||
margin: 0; | ||
composes: g-type-label-small from global; | ||
color: var(--gray-3); | ||
|
||
@nest .dark & { | ||
color: var(--gray-5); | ||
} | ||
} | ||
|
||
.heading { | ||
margin: 0; | ||
composes: g-type-display-5 from global; | ||
color: var(--black); | ||
|
||
@nest * + & { | ||
margin-top: var(--token-spacing-05); | ||
} | ||
|
||
@nest .dark & { | ||
color: var(--white); | ||
} | ||
} | ||
|
||
.description { | ||
margin: 0; | ||
composes: g-type-body-small from global; | ||
color: var(--gray-3); | ||
|
||
@nest * + & { | ||
margin-top: var(--token-spacing-03); | ||
} | ||
|
||
@nest .dark & { | ||
color: var(--gray-5); | ||
} | ||
} | ||
|
||
.footer { | ||
margin-top: auto; | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: flex-end; | ||
padding-top: 32px; | ||
} | ||
|
||
.products { | ||
display: flex; | ||
gap: 8px; | ||
margin: 0; | ||
padding: 0; | ||
|
||
& > li { | ||
width: 32px; | ||
height: 32px; | ||
display: grid; | ||
place-items: center; | ||
} | ||
|
||
& .logo { | ||
display: flex; | ||
|
||
& svg { | ||
width: 32px; | ||
height: 32px; | ||
} | ||
} | ||
} | ||
|
||
.linkType { | ||
margin-left: auto; | ||
display: flex; | ||
color: var(--black); | ||
|
||
@nest .dark & { | ||
color: var(--white); | ||
} | ||
} |
Oops, something went wrong.