Skip to content

Commit

Permalink
feat(community-preview-card): added the preview card component
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew-K-Lam authored and theetrain committed May 13, 2019
1 parent 496ef0d commit 091bcd1
Show file tree
Hide file tree
Showing 10 changed files with 689 additions and 0 deletions.
130 changes: 130 additions & 0 deletions packages/PreviewCard/PreviewCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'

import safeRest from '@tds/shared-safe-rest'
import Box from '@tds/core-box'
import Text from '@tds/core-text'
import { componentWithName } from '@tds/util-prop-types'
import { colorTelusPurple, colorWhiteLilac } from '@tds/core-colours'

/**
* The PreviewCard component creates the appearance of a page snippet, and can be used in a list format.
* @version ./package.json
*/
const PreviewCard = ({ category, other, image, body, footer, ...rest }) => {
let header = category || other
if (category && other) {
header = `${category} \u00B7 ${other}`
}

let newBody = body
if (body.length > 70) {
newBody = `${body.substr(0, 70)}...`
}

const Anchor = styled.a`
text-decoration: none;
cursor: pointer;
`

const BoxContainer = styled.div`
opacity: 1;
border: 1px solid ${colorWhiteLilac};
border-radius: 4px;
width: ${header || footer ? '100%' : '269px'};
max-width: 346px;
height: ${header || footer ? '465px' : '305px'};
@media (max-width: 576px) {
height: auto;
width: 100%;
}
overflow: hidden;
&:hover {
box-shadow: 0 0 16px 0 rgba(213, 213, 213, 0.5);
}
`

const ContentContainer = styled.div`
line-height: ${header && footer && '21px'};
`

const ImageContainer = styled.div`
border-radius: 4px 4px 0 0;
width: ${header || footer ? '100%' : '268px'};
overflow: hidden;
line-height: 0px;
& > img {
transition: all 0.3s ease-in-out;
&:hover {
transform: scale(1.03);
}
}
`

const P = styled.p`
color: ${colorTelusPurple};
`

return (
<Anchor {...safeRest(rest)}>
<BoxContainer>
{image && <ImageContainer>{image}</ImageContainer>}
<Box horizontal={header || footer ? 4 : 3} vertical={header || footer ? 5 : 3}>
<ContentContainer id="contentContainer">
{header && (
<Box>
<Text size="small" bold>
{header}
</Text>
</Box>
)}
<Box vertical={header && 3}>
<P alt={body}>{newBody}</P>
</Box>
{footer && (
<Box>
<Text size="small">{footer}</Text>
</Box>
)}
</ContentContainer>
</Box>
</BoxContainer>
</Anchor>
)
}

PreviewCard.propTypes = {
/**
* Image component that will appear at the top of the card, above the content section. Recommended dimensions is 369x269px.
*/
image: componentWithName('Image').isRequired,
/**
* Text that will appear at the top of the content section. Recommended to be only one or two words.
*/
category: PropTypes.string,
/**
* Text that will appear at the top of the content section, next to category seperated by a dot. Recommended to be 3 or less words.
*/
other: PropTypes.string,
/**
* Purple text that will appear in the middle of the content section. Recommended amount of characters is 70 or less.
*/
body: PropTypes.string.isRequired,
/**
* Text that will appear at the bottom of the content section. Recommended to be 3 or less words.
*/
footer: PropTypes.string,
/**
* Target URL.
*/
href: PropTypes.string.isRequired,
}

PreviewCard.defaultProps = {
category: undefined,
other: undefined,
footer: undefined,
}

export default PreviewCard
35 changes: 35 additions & 0 deletions packages/PreviewCard/PreviewCard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
### Usage Criteria

- Use when you want to showcase and guide your users to a webpage.

```jsx
<FlexGrid limitWidth={false} gutter={true}>
<FlexGrid.Row>
<FlexGrid.Col xs={12} md={6} lg={4}>
<PreviewCard
category="Data Intelligence"
other="March 21, 2019"
image={<img src="blog-example.jpg" alt="Image of co-workers collaborating" width="100%" />}
body="Hello world, this preview card has all the props and has text that is over 70 characters in length"
footer="By Emelyn Ticong"
href="#"
/>
</FlexGrid.Col>
<FlexGrid.Col xs={12} md={6} lg={4}>
<PreviewCard
category="Data Intelligence"
image={<Image src="blog-example.jpg" alt="Image of co-workers collaborating" />}
body="Hello world, this preview card has a category"
href="#"
/>
</FlexGrid.Col>
<FlexGrid.Col xs={12} md={6} lg={4}>
<PreviewCard
image={<Image src="blog-example.jpg" alt="Image of co-workers collaborating" />}
body="Hello world, this preview card has no category nor footer"
href="#"
/>
</FlexGrid.Col>
</FlexGrid.Row>
</FlexGrid>
```
1 change: 1 addition & 0 deletions packages/PreviewCard/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# TDS Community: PreviewCard
111 changes: 111 additions & 0 deletions packages/PreviewCard/__tests__/PreviewCard.spec.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React from 'react'
import { shallow, mount } from 'enzyme'
import 'jest-styled-components'

import Image from '@tds/core-image'

import PreviewCard from '../PreviewCard'

describe('PreviewCard', () => {
const doShallow = (props = {}) => shallow(<PreviewCard {...props} />)

const requiredProps = {
body: 'Hello world!',
image: (
<Image
src="blog-example.jpg"
alt="Image of co-workers collaborating"
width={300}
height={300}
/>
),
href: '#',
}

it('renders with only Required props', () => {
const previewCard = doShallow({ ...requiredProps })

expect(previewCard).toMatchSnapshot()
})

it('renders with category and other', () => {
const previewCard = doShallow({
...requiredProps,
category: 'development',
other: 'April 1st, 2019',
})

expect(previewCard).toMatchSnapshot()
})

it('renders with footer', () => {
const previewCard = doShallow({ ...requiredProps, footer: 'By Halo' })

expect(previewCard).toMatchSnapshot()
})

it('renders with all props', () => {
const previewCard = doShallow({
...requiredProps,
category: 'development',
other: 'April 1st, 2019',
footer: 'By Halo',
})

expect(previewCard).toMatchSnapshot()
})

it('renders with long body text', () => {
const previewCard = shallow(
<PreviewCard
image={
<Image
src="blog-example.jpg"
alt="Image of co-workers collaborating"
width={300}
height={300}
/>
}
body="Hello world, this preview card has all the props and has text that is over 70 characters in length"
href="#"
/>
)

expect(previewCard).toMatchSnapshot()
})

it('passes additional attributes to the element', () => {
const previewCard = doShallow({
...requiredProps,
id: 'the-id',
'data-some-attr': 'some value',
})

expect(previewCard).toHaveProp('id', 'the-id')
expect(previewCard).toHaveProp('data-some-attr', 'some value')
})

it('does not allow custom CSS', () => {
const previewCard = doShallow({
...requiredProps,
className: 'my-custom-class',
style: { color: 'hotpink' },
})

expect(previewCard).not.toHaveProp('className', 'my-custom-class')
expect(previewCard).not.toHaveProp('style')
})

it('renders with line height of 21px', () => {
const previewCard = mount(
<PreviewCard
category="development"
other="April 1st, 2019"
footer="By Halo"
{...requiredProps}
/>
)

expect(previewCard.find('#contentContainer')).toHaveStyleRule('line-height', '21px')
})
})
Loading

0 comments on commit 091bcd1

Please sign in to comment.