@navinc/base-react-components
Version:
Nav's Pattern Library
285 lines (270 loc) • 9.83 kB
JavaScript
import React, { Fragment } from 'react'
import styled from 'styled-components'
import { action } from '@storybook/addon-actions'
import { MemoryRouter } from 'react-router-dom'
import readme from './standard-card.readme.md'
import Header from './header.js'
import Banner from './banner.js'
import Button from './button'
import Copy from './copy'
import Link from './link.js'
import AnimateHeight from './animate-height.js'
// Directly importing only so the proptypes docs work.
import Card, { CardHeader, CardFooter } from './standard-card.js'
const Stage = styled.article`
padding: 16px;
`
const Title = styled(Header)`
display: flex;
flex-wrap: wrap;
width: 100%;
margin-bottom: 8px;
border-bottom: 1px solid ${({ theme }) => theme.border};
&:not(:first-child) {
padding-top: 40px;
}
`
const A = styled(Copy).attrs((props) => ({ as: 'a', light: true, size: 'sm' }))`
margin-left: auto;
align-self: center;
text-decoration: none;
`
const P = styled(Copy).attrs((props) => ({ light: true, size: 'sm' }))`
flex: 1 1 100%;
`
const CenteredDiv = styled.div`
text-align: center;
justify-content: center;
align-content: center;
display: flex;
flex-wrap: wrap;
& > img {
margin-bottom: 24px;
}
`
const Div = styled.div`
display: flex;
& > img {
height: 120px;
margin-right: 24px;
}
`
const StandardCard = styled(Card)`
width: 100%;
`
export default {
title: 'General/StandardCard',
component: StandardCard,
parameters: {
info: {
text: readme,
source: false,
propTablesExclude: [
Banner,
Button,
Title,
StandardCard.Footer,
StandardCard.Header,
AnimateHeight,
Fragment,
P,
Div,
CenteredDiv,
A,
],
},
},
}
export const Basic = (args) => {
const label = args.label
const title = args.title
const onBack = args.onBack
const onAction = args.onAction
const actionHref = args.actionHref
const backHref = args.backHref
const actionText = args.actionText
const isActionDisabled = args.isActionDisabled
const isLoading = args.isLoading
const children = args.children
const hasError = args.hasError
const hasAdditionalButton = args.hasAdditionalButton
const hasLoadingContent = args.hasLoadingContent
return (
<Stage>
<MemoryRouter initialEntries={['/']}>
<Title>
Card: Persistent
<A href="https://navinc.invisionapp.com/d/main/#/console/15452082/321408664/preview">More Details Here</A>
<P>
This is the standard use case for StandardCard. If needed you can add additional Buttons by wrapping them in
Footer
</P>
</Title>
<StandardCard>
{(label || title) && <CardHeader label={label} title={title} />}
{hasLoadingContent ? (
<StandardCard.LoadingContent imageFilename="cats" />
) : (
<>
{children}
{(onAction || actionHref || onBack || backHref) && (
<CardFooter
actionText={actionText}
onAction={onAction && action(onAction)}
actionHref={actionHref}
isActionDisabled={isActionDisabled}
isLoading={isLoading}
onBack={onBack && action(onBack)}
backHref={backHref}
>
{hasAdditionalButton && <Button>Optional Additional Button</Button>}
</CardFooter>
)}
</>
)}
</StandardCard>
<Title>
Card: Persistent, with Banner and AnimateHeight
<P>
Banner is optional and is placed at the very top of the card. AnimateHeight wraps the children of the card.
If there is the need, it can also wrap the header and banner.
</P>
</Title>
<StandardCard>
<AnimateHeight>
{hasError && <Banner title="Yo dawg" copy="You done messed up this time" type="error" />}
{(label || title) && <StandardCard.Header label={label} title={title} />}
{children}
{(onAction || actionHref || onBack || backHref) && (
<StandardCard.Footer
actionText={actionText}
onAction={onAction && action(onAction)}
actionHref={actionHref}
isActionDisabled={isActionDisabled}
isLoading={isLoading}
onBack={onBack && action(onBack)}
backHref={backHref}
/>
)}
</AnimateHeight>
</StandardCard>
<Title>
Card: Focused
<A href="https://navinc.invisionapp.com/d/main/#/console/15452082/321409946/preview">More Details Here</A>
<P>
Use the focus card style when there is only 1 card on the screen or a focused experience (ie onboarding)
Header is centered via `focused` and doesn't have a label. Use StandardCard.FocusedContent to center the
content
</P>
</Title>
<StandardCard isFocused>
{(label || title) && <StandardCard.Header title={title} />}
<StandardCard.FocusedContent>
<img
src="https://s3-us-west-2.amazonaws.com/creditera-assets/design-assets/illustrations/business-credit-searching.png"
alt="Business Credit Searching"
/>
{children}
</StandardCard.FocusedContent>
{(onAction || actionHref || onBack || backHref) && (
<StandardCard.Footer
actionText={actionText}
onAction={onAction && action(onAction)}
actionHref={actionHref}
isActionDisabled={isActionDisabled}
isLoading={isLoading}
onBack={onBack && action(onBack)}
backHref={backHref}
/>
)}
</StandardCard>
<Title>
Card: Conditional
<A href="https://navinc.invisionapp.com/d/main/#/console/15452082/321408663/preview">More Details Here</A>
<P>
CTA, Conditional, only seen if user fits certain requirements. Header doesn't have a label, there is usually
an illustration to the left of the content.
</P>
</Title>
<StandardCard>
{(label || title) && <StandardCard.Header title={title} />}
<Div>
<img src="https://dxkdvuv3hanyu.cloudfront.net/design-assets/illustrations/phone.png" alt="Phone" />
{children}
</Div>
{(onAction || actionHref || onBack || backHref) && (
<StandardCard.Footer
actionText={actionText}
onAction={onAction && action(onAction)}
actionHref={actionHref}
isActionDisabled={isActionDisabled}
isLoading={isLoading}
backHref={backHref}
/>
)}
</StandardCard>
<Title>
Card: Terms Footer
<A href="https://navinc.invisionapp.com/d/#/console/16484049/349590397/preview">More Details Here</A>
<P>
Use the Terms Footer component for displaying disclaimer terms and such at the bottom of the StandardCard.
</P>
</Title>
<StandardCard>
{(label || title) && <StandardCard.Header title={title} />}
<Div>
<img src="https://dxkdvuv3hanyu.cloudfront.net/design-assets/illustrations/phone.png" alt="phone" />
{children}
</Div>
{(onAction || actionHref || onBack || backHref) && (
<StandardCard.Footer
actionText={actionText}
onAction={onAction && action(onAction)}
actionHref={actionHref}
isActionDisabled={isActionDisabled}
isLoading={isLoading}
backHref={backHref}
/>
)}
<StandardCard.TermsFooter>
<Copy strong size="xs">
Yo Dawg
</Copy>
<br />
<Copy size="xs" light>
You understand that by continuing, you are authorizing and consenting to the release of information by Nav
to lenders listed <Link href="https://www.nav.com/prequalify/">here</Link> for purposes of qualifying for
commercial financing. Additionally, you represent and warrant that you are the owner of the business for
which commercial financing is being obtained.
</Copy>
<br />
<Copy size="xs" light>
You also understand that by continuing, you acknowledge and agree to our{' '}
<Link href="https://www.nav.com/terms/">Terms and Conditions </Link>
and <Link href="https://www.nav.com/privacy/">Privacy Policy</Link>, and are authorizing and providing
"written instructions" to allow Nav and Nav's participating lenders to obtain information from your
personal credit report on your behalf from a credit reporting agency under the Fair Credit Reporting Act.
These are soft inquiries that will not impact your score.
</Copy>
<br />
</StandardCard.TermsFooter>
</StandardCard>
</MemoryRouter>
</Stage>
)
}
Basic.args = {
label: 'card label',
title: 'Card Title',
onBack: 'onBackFn()',
onAction: 'function()',
actionHref: 'Footer:actionHref',
backHref: '/2000bc',
actionText: 'Next',
isActionDisabled: false,
isLoading: false,
children: 'Body content goes here! La la la, things and stuff, important details, not important details, etc.!',
hasError: true,
hasAdditionalButton: true,
hasLoadingContent: false,
}