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

WIP: Card component #159

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export { default as Emphasis } from './inline/Emphasis';
export { default as Strong } from './inline/Strong';

export { default as Button } from './ui/Button';
export { default as Card } from './ui/Card';
export { default as Heading } from './ui/Heading';
export { default as Icon } from './ui/Icon';
export { default as Link } from './ui/Link';
Expand Down
82 changes: 82 additions & 0 deletions src/components/ui/Card/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
A card is used to represent a descrete and self-contained piece of data, typically as part of a feed or series of related datum.

```jsx
import { Paragraph, Button, Heading, Tags, Icon } from '@octopusthink/nautilus';

<React.Fragment>
<Card title="Cards can be super simple">
<Icon name="star" />
<Heading level={1}>Cards should always have a title</Heading>
<Paragraph small>The Card can either have a title attribute, or you can pass it a heading. Not sure which is the best approach here.</Paragraph>
<Button>Choose this</Button>
<Button minimal navigation>Learn more</Button>
</Card>

<Card title="Cards can be super simple">
<Heading level={2}>Cards should always have a title</Heading>
<Paragraph>The Card can either have a title attribute, or you can pass it a heading. Not sure which is the best approach here.</Paragraph>
</Card>

<Card title="Cards can be super simple">
<Heading level={3}>Cards should always have a title</Heading>
<Paragraph large>The Card can either have a title attribute, or you can pass it a heading. Not sure which is the best approach here.</Paragraph>
</Card>
</React.Fragment>
```

```jsx
import { Paragraph } from '@octopusthink/nautilus';

<Card
orientation="landscape"
title="Fish & Chips & Vinegar"
metadata="Places I like to visit"
media="http://placekitten.com/400/800"
>
<Paragraph size="small">
By default, cards use a landscape orientation, but can also be swapped around.
All content is optional.
</Paragraph>
</Card>
```

```jsx
import { Paragraph } from '@octopusthink/nautilus';

<Card
orientation="portrait"
title="A card can go both ways"
metadata="Horizontal, or vertical?"
media="http://placekitten.com/800/400"
>
<Paragraph size="medium">
Dis convallis taciti molestie cum etiam mollis facilisis ligula ultricies, accumsan mattis phasellus malesuada in sollicitudin pulvinar quis, turpis pretium purus mi enim suspendisse nisl dolor. Egestas diam mollis bibendum integer est volutpat, quisque posuere cras eu. Eros enim maecenas tellus semper torquent platea pulvinar vulputate fermentum laoreet consequat vel purus, vitae rhoncus est sollicitudin lacus pretium id montes blandit phasellus nullam cras.
</Paragraph>
</Card>
```

```jsx
import { Paragraph, Button, Heading, Tags, Icon } from '@octopusthink/nautilus';

<Card orientation="landscape">
{/*
<Card.Header>
<img src="http://placekitten.com/400/800" />
<Heading>Fish & Chips & Vinegar</Heading>
<Tags><Tags.Tag>Places I like to visit</Tags.Tag></Tags>
</Card.Header>
*/}

<Paragraph size="small">
By default, cards use a landscape orientation, but can also be
swapped around. All content is optional.
</Paragraph>

{/*
<Card.Footer>
<Button>Learn more</Button>
<Button minimal>Hide this</Button>
</Card.Footer>
*/}
</Card>
```
45 changes: 45 additions & 0 deletions src/components/ui/Card/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Card should output card CSS 1`] = `
.emotion-0 {
background: white;
border: 1px solid #f8f9fa;
box-shadow: 0px 4px 8px rgba(0,0,0,0.125);
padding: 2.4rem;
margin-bottom: 3.2rem;
}

.emotion-0 .Nautilus-Heading-1,
.emotion-0 .Nautilus-Heading-2,
.emotion-0 .Nautilus-Heading-3,
.emotion-0 .Nautilus-Heading-4,
.emotion-0 .Nautilus-Heading-5,
.emotion-0 .Nautilus-Heading-6 {
font-family: -apple-system,BlinkMacSystemFont,San Francisco,Roboto,Segoe UI,Helvetica Neue,sans-serif;
font-weight: 600;
font-size: 2.7rem;
line-height: 1.3333333333333333;
color: #666c76;
}

.emotion-0 p {
font-family: -apple-system,BlinkMacSystemFont,San Francisco,Roboto,Segoe UI,Helvetica Neue,sans-serif;
font-weight: 400;
font-size: 1.7rem;
line-height: 1.6470588235294117;
}

.emotion-0 button {
font-family: -apple-system,BlinkMacSystemFont,San Francisco,Roboto,Segoe UI,Helvetica Neue,sans-serif;
font-weight: 500;
font-size: 1.7rem;
line-height: 1.411764705882353;
padding: 0.8rem 1.2rem;
}

<div
class="emotion-0"
>
My Blog Posts
</div>
`;
62 changes: 62 additions & 0 deletions src/components/ui/Card/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { css } from '@emotion/core';
import PropTypes from 'prop-types';
import React from 'react';

import { headingClassNameForLevel } from 'components/ui/Heading';
import { heading, body, interfaceUI, toUnits } from 'styles';
import { useTheme } from 'themes';

export const Card = (props) => {
const { children, ...otherProps } = props;
const theme = useTheme();

return (
<div
css={css`
background: white;
border: 1px solid ${theme.colors.neutral.grey0};
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.125);
padding: ${toUnits(theme.spacing.padding.large)};
margin-bottom: ${toUnits(theme.spacing.margin.medium)};

.${headingClassNameForLevel(1)},
.${headingClassNameForLevel(2)},
.${headingClassNameForLevel(3)},
.${headingClassNameForLevel(4)},
.${headingClassNameForLevel(5)},
.${headingClassNameForLevel(6)} {
${heading.small(theme)};
color: ${theme.colors.neutral.grey800};
}

/* TODO: Apply the small paragraph styling in a less brute-forcey sort of way.*/
p {
${body.small(theme)};
}

/* TODO: Create a small prop on the button, and pull that styling in here. */
button {
${interfaceUI.small(theme)};
padding: ${toUnits(theme.spacing.padding.small)}
${toUnits(theme.spacing.padding.medium)};
}
`}
{...otherProps}
>
{children}
</div>
);
};

Card.defaultProps = {
children: undefined,
};

Card.propTypes = {
/** @ignore */
children: PropTypes.node,
};

export const { defaultProps, propTypes } = Card;

export default Card;
37 changes: 37 additions & 0 deletions src/components/ui/Card/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';

import { axe, render } from 'utils/testing';

import Card from '.';

describe('Card', () => {
it('should render a <div>', () => {
const { container } = render(<Card>My Account</Card>);

expect(container.firstChild.tagName).toEqual('DIV');
});

it('should output its children', () => {
const { getByTestId } = render(
<Card>
<div data-testid="child" />
</Card>,
);

expect(getByTestId('child')).toBeDefined();
});

it('should output card CSS', () => {
const { container } = render(<Card>My Blog Posts</Card>);

expect(container.firstChild).toMatchSnapshot();
});

describe('accessibility', () => {
it('should pass aXe tests', async () => {
const { container } = render(<Card>My Blog Posts</Card>);

expect(await axe(container.innerHTML)).toHaveNoViolations();
});
});
});
6 changes: 3 additions & 3 deletions src/components/ui/Heading/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ dl + .emotion-0 {
}

<h2
class="emotion-0"
class="Nautilus-Heading-2 emotion-0"
>
Big heading
</h2>
Expand All @@ -38,7 +38,7 @@ dl + .emotion-0 {
}

<h3
class="emotion-0"
class="Nautilus-Heading-3 emotion-0"
>
So-so heading
</h3>
Expand All @@ -60,7 +60,7 @@ dl + .emotion-0 {
}

<h4
class="emotion-0"
class="Nautilus-Heading-4 emotion-0"
>
Tiny heading
</h4>
Expand Down
12 changes: 11 additions & 1 deletion src/components/ui/Heading/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { css } from '@emotion/core';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';

Expand All @@ -11,15 +12,21 @@ const LARGE = 2;
const MEDIUM = 3;
const SMALL = 4;

const ComponentClassName = 'Nautilus-Heading';
const HeadingLevels = [LARGE, MEDIUM, SMALL];

export const headingClassNameForLevel = (level) => {
return `${ComponentClassName}-${level}`;
};

export const Heading = (props) => {
const theme = useTheme();
const { children, level, ...otherProps } = props;
const { children, className, level, ...otherProps } = props;
const HeadingElement = `h${level}`;

return (
<HeadingElement
className={classnames(headingClassNameForLevel(level), className)}
css={css`
margin: 0 0 ${toUnits(theme.spacing.margin.medium)};
.${ListClassName} + &,
Expand All @@ -41,11 +48,14 @@ export const Heading = (props) => {
};

Heading.defaultProps = {
className: undefined,
children: undefined,
level: 2,
};

Heading.propTypes = {
/** @ignore */
className: PropTypes.string,
/** @ignore */
children: PropTypes.node,
/** Semantic hierarchy level of the `<h>` element in the markup (ex: `<h3>`). The more semantically important the level, the larger the heading will appear visually; an `<h2>` will be visually styled as "large" while an `<h4>` will be visually small. */
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/List/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ dl + .emotion-0 {

<div>
<h3
class="emotion-0"
class="Nautilus-Heading-3 emotion-0"
data-testid="description"
id="fruits"
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/Tabs/__snapshots__/Tab.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ dl + .emotion-0 {
tabindex="-1"
>
<h4
class="emotion-0"
class="Nautilus-Heading-4 emotion-0"
>
About
</h4>
Expand Down
6 changes: 3 additions & 3 deletions src/components/ui/Tabs/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ dl + .emotion-4 {
tabindex="-1"
>
<h4
class="emotion-4"
class="Nautilus-Heading-4 emotion-4"
>
About
</h4>
Expand All @@ -193,7 +193,7 @@ dl + .emotion-4 {
tabindex="-1"
>
<h4
class="emotion-4"
class="Nautilus-Heading-4 emotion-4"
>
History
</h4>
Expand All @@ -212,7 +212,7 @@ dl + .emotion-4 {
tabindex="-1"
>
<h4
class="emotion-4"
class="Nautilus-Heading-4 emotion-4"
>
Other
</h4>
Expand Down