Skip to content
This repository has been archived by the owner on Mar 31, 2021. It is now read-only.

Feature/card #19

Merged
merged 6 commits into from
Nov 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/Card/Card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// @flow
import React, { type Element, type Node } from 'react';
import _Card from './styled';
import CardContent from './CardContent';
import CardHeader from './CardHeader';
import CardFooter from './CardFooter';
import CardTitle from './CardTitle';

type Props = {
a11yDescriptionId?: string,
a11yTitleId?: string,
children: Node,
className?: string,
footer?: string | Element<any>,
headerActions?: Element<any>,
isFullWidth?: boolean,
title?: string | Element<any>
};

const Card = ({ a11yDescriptionId, a11yTitleId, children, footer, headerActions, title, ...props }: Props) => (
<_Card aria-describedby={a11yDescriptionId} aria-labelledby={a11yTitleId} border="shadow" padding="medium" {...props}>
{title && (
<CardHeader>
{typeof title === 'string' ? <CardTitle id={a11yTitleId}>{title}</CardTitle> : title}
{headerActions && <div>{headerActions}</div>}
</CardHeader>
)}
<CardContent id={a11yDescriptionId}>{children}</CardContent>
{footer && <CardFooter>{footer}</CardFooter>}
</_Card>
);

Card.Header = CardHeader;
Card.Content = CardContent;
Card.Footer = CardFooter;
Card.Title = CardTitle;

Card.defaultProps = {
a11yDescriptionId: undefined,
a11yTitleId: undefined,
children: undefined,
className: undefined,
footer: undefined,
headerActions: undefined,
isFullWidth: false,
title: undefined
};

export default Card;
90 changes: 90 additions & 0 deletions src/Card/Card.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
name: Card
route: /components/card
menu: Components
---

import { Playground, PropsTable } from 'docz';
import Card from '../Card';
import Button, { ActionButtons } from '../Button';
import Set from '../Set';

# Card

## Import

`import { Card } from 'fannypack'`

## Basic Usage

<Playground>
<Card>Hello world</Card>
</Playground>

## Header

You can render a header for the card using the `title` prop.

<Playground>
<Card title="This is a title">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse diam ipsum, cursus id placerat congue, ultrices
eget lectus. Duis posuere, lacus sed tristique commodo, sapien turpis mollis nunc, vestibulum consectetur lectus
augue sit amet justo.
</Card>
</Playground>

## Header with actions

You can render a header with actions for the card using the `headerActions` prop.

<Playground>
<Card title="This is a title" headerActions={<Set><Button palette="primary" kind="link">Action 1</Button><Button palette="primary" kind="link">Action 2</Button></Set>}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse diam ipsum, cursus id placerat congue, ultrices
eget lectus. Duis posuere, lacus sed tristique commodo, sapien turpis mollis nunc, vestibulum consectetur lectus
augue sit amet justo.
</Card>
</Playground>

## Footer

You can render a footer for the card using the `footer` prop.

<Playground>
<Card title="This is a title" footer={<ActionButtons />}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse diam ipsum, cursus id placerat congue, ultrices
eget lectus. Duis posuere, lacus sed tristique commodo, sapien turpis mollis nunc, vestibulum consectetur lectus
augue sit amet justo.
</Card>
</Playground>

## Full width

<Playground>
<Card isFullWidth>Hello world</Card>
</Playground>

## Props

<PropsTable of={Card} />

## Theming

### Schema

```jsx
{
base: string | Object,
Header: {
base: string | Object
},
Content: {
base: string | Object
},
Footer: {
base: string | Object
},
Title: {
base: string | Object
}
}
```
17 changes: 17 additions & 0 deletions src/Card/CardContent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// @flow
import React, { type Node } from 'react';

import { CardContent as _CardContent } from './styled';

type Props = {
children: Node,
className?: string
};

const CardContent = ({ children, ...props }: Props) => <_CardContent {...props}>{children}</_CardContent>;

CardContent.defaultProps = {
className: undefined
};

export default CardContent;
17 changes: 17 additions & 0 deletions src/Card/CardFooter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// @flow
import React, { type Node } from 'react';

import { CardFooter as _CardFooter } from './styled';

type Props = {
children: Node,
className?: string
};

const CardFooter = ({ children, ...props }: Props) => <_CardFooter {...props}>{children}</_CardFooter>;

CardFooter.defaultProps = {
className: undefined
};

export default CardFooter;
17 changes: 17 additions & 0 deletions src/Card/CardHeader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// @flow
import React, { type Node } from 'react';

import { CardHeader as _CardHeader } from './styled';

type Props = {
children: Node,
className?: string
};

const CardHeader = ({ children, ...props }: Props) => <_CardHeader {...props}>{children}</_CardHeader>;

CardHeader.defaultProps = {
className: undefined
};

export default CardHeader;
21 changes: 21 additions & 0 deletions src/Card/CardTitle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React, { type Node } from 'react';

import { CardTitle as _CardTitle } from './styled';

type Props = {
children: Node,
className?: string
};

const DialogTitle = ({ children, ...props }: Props) => (
<_CardTitle as="h5" isSubHeading {...props}>
{children}
</_CardTitle>
);

DialogTitle.defaultProps = {
className: undefined
};

export default DialogTitle;
48 changes: 48 additions & 0 deletions src/Card/__tests__/Card.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import render from '../../_utils/tests/render';
import Card from '../Card';
import 'jest-styled-components';

it('renders correctly for a default card', () => {
const { container } = render(
<Card>
<Card.Header>
<Card.Title>This is a title</Card.Title>
</Card.Header>
<Card.Content>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse diam ipsum, cursus id placerat congue,
ultrices eget lectus. Duis posuere, lacus sed tristique commodo, sapien turpis mollis nunc, vestibulum
consectetur lectus augue sit amet justo.
</Card.Content>
</Card>
);
expect(container.firstChild).toMatchSnapshot();
});

it('renders correctly for a card with a footer', () => {
const { container } = render(
<Card>
<Card.Header>
<Card.Title>This is a title</Card.Title>
</Card.Header>
<Card.Content>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse diam ipsum, cursus id placerat congue,
ultrices eget lectus. Duis posuere, lacus sed tristique commodo, sapien turpis mollis nunc, vestibulum
consectetur lectus augue sit amet justo.
</Card.Content>
<Card.Footer>test</Card.Footer>
</Card>
);
expect(container.firstChild).toMatchSnapshot();
});

it('renders correctly for a card with a actions', () => {
const { container } = render(
<Card title="This is a title" headerActions={<div>test</div>}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse diam ipsum, cursus id placerat congue,
ultrices eget lectus. Duis posuere, lacus sed tristique commodo, sapien turpis mollis nunc, vestibulum consectetur
lectus augue sit amet justo.
</Card>
);
expect(container.firstChild).toMatchSnapshot();
});
Loading