Skip to content

Commit

Permalink
Homepage redesign (#13159)
Browse files Browse the repository at this point in the history
* homepage setup

* [Homepage] `<IoHomeHero />` component (#13160)

* init <Hero /> component

* adds loading animation

* updates variable naming

* makes index optional

* Update hero-pattern.svg

* prefix with IoHome

* updates usage

* [Homepage] `<IoHomePreFooter />` component (#13182)

* adds <IoHomePreFooter />

* adds interfaces

* [Homepage] `<IoHomeHero />` component (#13160)

* init <Hero /> component

* adds loading animation

* updates variable naming

* makes index optional

* Update hero-pattern.svg

* prefix with IoHome

* updates usage

* adds <IoHomePreFooter />

* adds interfaces

* adds key

* [Homepage] `<IoHomeCallToAction />` component (#13164)

* adding brand to cta

* cleanup homepage

* [Homepage] `<IoHomeVideo />` component (#13161)

* init <Video /> component

* adjusts sizing and border radius

* responsive styling

* fix hover svg gitter

* adjust play icon sizing

* include temp thumbnail

* dialog implementation

* conditionally display person and show helpers

* rename component

* updates dialog naming

* add homepage styling

* simplify background color

* page level styling

* [Homepage] `<IoHomeCaseStudies />` (#13190)

* adds <IoHomeCaseStudies />

* adds interface

* animate gradient

* update min-heights

* 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

* adds keys

* adds in practice cards

* adds in practice background

* use case cards

* update min col sizing

* adds feature component (#13203)

* fixes card hover bug

* [Homepage] connect homepage to dato content (#13227)

* connect homepage to dato

* Check for internal link

* fix return types

* adds youtube video

* hook up meta tags and chunk cards

* removes chunking

* fix ts return

* fix prop naming

* fix return type

* mobile sizing adjustments

* [Homepage] Usecase pages (#13240)

* init usecase page

* updates use case call to action

* card container component

* themeing

* convert to using strictly props

* responsive spacing

* reworking sections component

* adds callout and hero patterns

* adds priority

* makes feature link optional

* [Homepage] connect use case template to dato (#13295)

* Start connecting to dato

* Fix spacing when no video is present

* Remove log

* adds images

* hook up cards

* pass eyebrow and products

* Delete index.tsx

* Use card container on homepage

* use react video player

* [Homepage] fix mobile video (#13309)

* Removing attributes

* update url

* spacing adjustments

* Allow previewing draft content (#13312)

* fix heading width

* fix feature max width

* adjust in practice padding

* increase icon sizing

* adjust icon alignment

* update eyebrow

* update hero pattern

* update usecase hero pattern

* add hover scale

* [Homepage] populate use case dropdown from use case pages (#13325)

* create standard layout

* removes unused subnav data

* removes static use case pages

* removes use cases style

* bump subnav and use hashicorp vault logo

* fixes use cases paths

* removes hashistack menu

* removes subnav top border

* conditionally render video callout avatar

* hook up data and conditionals

* update components to work with other products

* extract in practice section for reuse

* use Products type

* fix type error

* rework cta logic

* removes type

* updates accent method

* fix button prop

* refactor customer case study

* refactor case studies component

* cleanup margin

* refactor data props

* Spacing updates and introduce intro component

* adds intro interface

* Delete style.css

* fix intro description color

* add revalidate code to homepage

* bump subnav

* make stats optional

* adjust border radius based on customer story

* cleanup temp files

* redirect /home to homepage

* reorder resources

* fix: move heading and description

* fix: logo alignment

* fix: section background color

* feat: optional tutorial and docs links

* fix: removes case studies background

* formatting

* feat: sort use cases in nav

* fix: card overflow (#13429)

* fix: adjust overflow method

* fix: padding on desktop

* fix: scroll padding-right on mobile

* remove debugger

* increase last item width

* card container overflow method (#13434)

* use flex

* formatting

* add comment
  • Loading branch information
alexcarpenter authored and joatmon08 committed Jan 25, 2022
1 parent 88a02c8 commit 68c2330
Show file tree
Hide file tree
Showing 66 changed files with 22,385 additions and 20,705 deletions.
82 changes: 82 additions & 0 deletions website/components/io-card-container/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import * as React from 'react'
import classNames from 'classnames'
import Button from '@hashicorp/react-button'
import IoCard, { IoCardProps } from 'components/io-card'
import s from './style.module.css'

interface IoCardContaianerProps {
theme?: 'light' | 'dark'
heading?: string
description?: string
label?: string
cta?: {
url: string
text: string
}
cardsPerRow: 3 | 4
cards: Array<IoCardProps>
}

export default function IoCardContaianer({
theme = 'light',
heading,
description,
label,
cta,
cardsPerRow = 3,
cards,
}: IoCardContaianerProps): React.ReactElement {
return (
<div className={classNames(s.cardContainer, s[theme])}>
{heading || description ? (
<header className={s.header}>
{heading ? <h2 className={s.heading}>{heading}</h2> : null}
{description ? <p className={s.description}>{description}</p> : null}
</header>
) : null}
{cards.length ? (
<>
{label || cta ? (
<header className={s.subHeader}>
{label ? <h3 className={s.label}>{label}</h3> : null}
{cta ? (
<Button
title={cta.text}
url={cta.url}
linkType="inbound"
theme={{
brand: 'neutral',
variant: 'tertiary',
background: theme,
}}
/>
) : null}
</header>
) : null}
<ul
className={classNames(
s.cardList,
cardsPerRow === 3 && s.threeUp,
cardsPerRow === 4 && s.fourUp
)}
style={
{
'--length': cards.length,
} as React.CSSProperties
}
>
{cards.map((card, index) => {
return (
// Index is stable
// eslint-disable-next-line react/no-array-index-key
<li key={index}>
<IoCard variant={theme} {...card} />
</li>
)
})}
</ul>
</>
) : null}
</div>
)
}
114 changes: 114 additions & 0 deletions website/components/io-card-container/style.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
.cardContainer {
position: relative;

& + .cardContainer {
margin-top: 64px;

@media (--medium-up) {
margin-top: 132px;
}
}
}

.header {
margin: 0 auto 64px;
text-align: center;
max-width: 600px;
}

.heading {
margin: 0;
composes: g-type-display-2 from global;

@nest .dark & {
color: var(--white);
}
}

.description {
margin: 8px 0 0;
composes: g-type-body-large from global;

@nest .dark & {
color: var(--gray-5);
}
}

.subHeader {
margin: 0 0 32px;
display: flex;
align-items: center;
justify-content: space-between;

@nest .dark & {
color: var(--gray-5);
}
}

.label {
margin: 0;
composes: g-type-display-4 from global;
}

.cardList {
list-style: none;

--minCol: 250px;
--columns: var(--length);

position: relative;
gap: 32px;
padding: 0;

@media (--small) {
display: flex;
overflow-x: auto;
-ms-overflow-style: none;
scrollbar-width: none;
margin: 0;
padding: 6px 24px;
left: 50%;
margin-left: -50vw;
width: 100vw;

/* This is to ensure there is overflow padding right on mobile. */
&::after {
content: '';
display: block;
width: 1px;
flex-shrink: 0;
}
}

@media (--medium-up) {
display: grid;
grid-template-columns: repeat(var(--columns), minmax(var(--minCol), 1fr));
}

&.threeUp {
@media (--medium-up) {
--columns: 3;
--minCol: 0;
}
}

&.fourUp {
@media (--medium-up) {
--columns: 3;
--minCol: 0;
}

@media (--large) {
--columns: 4;
}
}

& > li {
display: flex;

@media (--small) {
flex-shrink: 0;
width: 250px;
}
}
}
124 changes: 124 additions & 0 deletions website/components/io-card/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import * as React from 'react'
import Link from 'next/link'
import InlineSvg from '@hashicorp/react-inline-svg'
import classNames from 'classnames'
import { IconArrowRight24 } from '@hashicorp/flight-icons/svg-react/arrow-right-24'
import { IconExternalLink24 } from '@hashicorp/flight-icons/svg-react/external-link-24'
import { productLogos } from './product-logos'
import s from './style.module.css'

export interface IoCardProps {
variant?: 'light' | 'gray' | 'dark'
products?: Array<{
name: keyof typeof productLogos
}>
link: {
url: string
type: 'inbound' | 'outbound'
}
inset?: 'none' | 'sm' | 'md'
eyebrow?: string
heading?: string
description?: string
children?: React.ReactNode
}

function IoCard({
variant = 'light',
products,
link,
inset = 'md',
eyebrow,
heading,
description,
children,
}: IoCardProps): React.ReactElement {
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(({ name }, index) => {
const key = name.toLowerCase()
const version = variant === 'dark' ? 'neutral' : 'color'
return (
// eslint-disable-next-line react/no-array-index-key
<li key={index}>
<InlineSvg
className={s.logo}
src={productLogos[key][version]}
/>
</li>
)
})}
</ul>
)}
<span className={s.linkType}>
{link.type === 'inbound' ? (
<IconArrowRight24 />
) : (
<IconExternalLink24 />
)}
</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>
}

IoCard.Eyebrow = Eyebrow
IoCard.Heading = Heading
IoCard.Description = Description

export default IoCard
34 changes: 34 additions & 0 deletions website/components/io-card/product-logos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const productLogos = {
boundary: {
color: require('@hashicorp/mktg-logos/product/boundary/logomark/color.svg?include'),
neutral: require('@hashicorp/mktg-logos/product/boundary/logomark/white.svg?include'),
},
consul: {
color: require('@hashicorp/mktg-logos/product/consul/logomark/color.svg?include'),
neutral: require('@hashicorp/mktg-logos/product/consul/logomark/white.svg?include'),
},
nomad: {
color: require('@hashicorp/mktg-logos/product/nomad/logomark/color.svg?include'),
neutral: require('@hashicorp/mktg-logos/product/nomad/logomark/white.svg?include'),
},
packer: {
color: require('@hashicorp/mktg-logos/product/packer/logomark/color.svg?include'),
neutral: require('@hashicorp/mktg-logos/product/packer/logomark/white.svg?include'),
},
terraform: {
color: require('@hashicorp/mktg-logos/product/terraform/logomark/color.svg?include'),
neutral: require('@hashicorp/mktg-logos/product/terraform/logomark/white.svg?include'),
},
vagrant: {
color: require('@hashicorp/mktg-logos/product/vagrant/logomark/color.svg?include'),
neutral: require('@hashicorp/mktg-logos/product/vagrant/logomark/white.svg?include'),
},
vault: {
color: require('@hashicorp/mktg-logos/product/vault/logomark/color.svg?include'),
neutral: require('@hashicorp/mktg-logos/product/vault/logomark/white.svg?include'),
},
waypoint: {
color: require('@hashicorp/mktg-logos/product/waypoint/logomark/color.svg?include'),
neutral: require('@hashicorp/mktg-logos/product/waypoint/logomark/white.svg?include'),
},
}
Loading

0 comments on commit 68c2330

Please sign in to comment.