-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(community-preview-card): added the preview card component
- Loading branch information
1 parent
496ef0d
commit 091bcd1
Showing
10 changed files
with
689 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# TDS Community: PreviewCard |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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') | ||
}) | ||
}) |
Oops, something went wrong.