Skip to content

Commit 85a2a84

Browse files
Julia Dufresnejraff
authored andcommitted
feat(community-story-card): add functionality and design for storycard
1 parent 52b02b1 commit 85a2a84

File tree

11 files changed

+381
-15
lines changed

11 files changed

+381
-15
lines changed

package-lock.json

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/StoryCard/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# TDS Community: StoryCard

packages/StoryCard/StoryCard.jsx

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import React from 'react'
2+
import PropTypes from 'prop-types'
3+
import { News, Headset, Play, Clipboard } from '@tds/core-decorative-icon'
4+
import {
5+
StyledCard,
6+
StyledTextBox,
7+
StyledInfoBox,
8+
StyledType,
9+
StyledDate,
10+
StyledHeadingBox,
11+
StyledHeading,
12+
StyledDescription,
13+
StyledIconTypeBox,
14+
StyledLink,
15+
StyledIconBox,
16+
StyledImageContainer,
17+
StyledImage,
18+
} from './style'
19+
20+
const StoryCard = ({ storyType, date, title, description, imgUrl, href }) => {
21+
const selectIcon = type => {
22+
if (type !== undefined) {
23+
const normalizedType = type.toLowerCase()
24+
if (normalizedType === 'article') {
25+
return <News size={20} />
26+
} else if (normalizedType === 'podcast') {
27+
return <Headset size={20} />
28+
} else if (normalizedType === 'video') {
29+
return <Play size={20} />
30+
} else if (normalizedType === 'case study') {
31+
return <Clipboard size={20} />
32+
}
33+
}
34+
return undefined
35+
}
36+
37+
return (
38+
<StyledLink href={href} title={title}>
39+
<StyledCard>
40+
<StyledTextBox>
41+
<StyledInfoBox>
42+
<StyledIconTypeBox>
43+
{selectIcon(storyType) !== undefined && (
44+
<StyledIconBox>{selectIcon(storyType)}</StyledIconBox>
45+
)}
46+
<StyledType>{storyType}</StyledType>
47+
</StyledIconTypeBox>
48+
<StyledDate>{date}</StyledDate>
49+
</StyledInfoBox>
50+
<StyledHeadingBox>
51+
<StyledHeading>{title}</StyledHeading>
52+
</StyledHeadingBox>
53+
<StyledDescription>{description}</StyledDescription>
54+
</StyledTextBox>
55+
<StyledImageContainer>
56+
<StyledImage src={imgUrl} alt={description} width="100%" />
57+
</StyledImageContainer>
58+
</StyledCard>
59+
</StyledLink>
60+
)
61+
}
62+
63+
StoryCard.propTypes = {
64+
/**
65+
* The title of the story
66+
*/
67+
title: PropTypes.string.isRequired,
68+
/**
69+
* The description of the story
70+
*/
71+
description: PropTypes.string.isRequired,
72+
/**
73+
* The URL for the image to be displayed
74+
*/
75+
imgUrl: PropTypes.string.isRequired,
76+
/**
77+
* The href for the story
78+
*/
79+
href: PropTypes.string.isRequired,
80+
/**
81+
* The type of story, if it is one of Article, Podcast or Video, an icon will render beside it. If it is something else, there will be no icon.
82+
*/
83+
storyType: PropTypes.string,
84+
/**
85+
* The date of when the story was published
86+
*/
87+
date: PropTypes.string,
88+
}
89+
90+
StoryCard.defaultProps = {
91+
storyType: undefined,
92+
date: undefined,
93+
}
94+
95+
export default StoryCard

packages/StoryCard/StoryCard.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
The StoryCard component is meant to display a snippet of an Article, Podcast or Video. The whole card is clickable, to take you to the destination of said story.
2+
3+
### Usage criteria
4+
5+
- Typical usage of this component will be to display a snippet of an Article, Podcast or Video
6+
- This component is completely dynamic, so it can likely be modified to suit other needs
7+
8+
```jsx
9+
<StoryCard
10+
storyType="Article"
11+
date="May 11th, 2021"
12+
title="Crisis Text Line provides mental health support for youth during lockdown"
13+
description="With the help of a Foundation grant, Kids Help Line was able to expand its mental health resources to include a Crisis Text Line in greater Edmonton."
14+
imgUrl="blog-example.jpg"
15+
href="kids-help-line"
16+
/>
17+
```
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react'
2+
import { shallow, mount } from 'enzyme'
3+
4+
import StoryCard from '../StoryCard'
5+
6+
describe('StoryCard', () => {
7+
const allProps = {
8+
storyType: 'Article',
9+
date: 'May 11th, 2021',
10+
title: 'Crisis Text Line provides mental health support for youth during lockdown',
11+
description: 'With the help of a Foundation grant',
12+
imgUrl: 'blog-example.jpg',
13+
href: 'kids-help-line',
14+
}
15+
const doShallow = () => shallow(<StoryCard {...allProps} />)
16+
17+
it('renders with all props', () => {
18+
const storyCard = doShallow()
19+
20+
expect(storyCard).toMatchSnapshot()
21+
})
22+
23+
it('passes additional attributes to the element', () => {
24+
const props = {
25+
...allProps,
26+
id: 'the-id',
27+
'data-some-attr': 'some value',
28+
}
29+
const previewCard = mount(<StoryCard {...props} />)
30+
31+
expect(previewCard).toHaveProp('id', 'the-id')
32+
expect(previewCard).toHaveProp('data-some-attr', 'some value')
33+
})
34+
35+
it('does not allow custom CSS', () => {
36+
const storyCard = doShallow({
37+
className: 'my-custom-class',
38+
style: { color: 'hotpink' },
39+
})
40+
41+
expect(storyCard).not.toHaveProp('className', 'my-custom-class')
42+
expect(storyCard).not.toHaveProp('style')
43+
})
44+
45+
it('renders without required prop', () => {
46+
const allRequiredProps = {
47+
storyType: undefined,
48+
date: undefined,
49+
title: 'Crisis Text Line provides mental health support for youth during lockdown',
50+
description: 'With the help of a Foundation grant',
51+
imgUrl: 'blog-example.jpg',
52+
href: 'kids-help-line',
53+
}
54+
const doShallowRequiredProps = () => shallow(<StoryCard {...allRequiredProps} />)
55+
const storyCard = doShallowRequiredProps()
56+
57+
expect(storyCard).toMatchSnapshot()
58+
})
59+
})
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`StoryCard renders with all props 1`] = `
4+
<style__StyledLink
5+
href="kids-help-line"
6+
title="Crisis Text Line provides mental health support for youth during lockdown"
7+
>
8+
<style__StyledCard>
9+
<style__StyledTextBox>
10+
<style__StyledInfoBox>
11+
<style__StyledIconTypeBox>
12+
<style__StyledIconBox>
13+
<DecorativeIcon
14+
size={20}
15+
/>
16+
</style__StyledIconBox>
17+
<style__StyledType>
18+
Article
19+
</style__StyledType>
20+
</style__StyledIconTypeBox>
21+
<style__StyledDate>
22+
May 11th, 2021
23+
</style__StyledDate>
24+
</style__StyledInfoBox>
25+
<style__StyledHeadingBox>
26+
<style__StyledHeading>
27+
Crisis Text Line provides mental health support for youth during lockdown
28+
</style__StyledHeading>
29+
</style__StyledHeadingBox>
30+
<style__StyledDescription>
31+
With the help of a Foundation grant
32+
</style__StyledDescription>
33+
</style__StyledTextBox>
34+
<style__StyledImageContainer>
35+
<style__StyledImage
36+
alt="With the help of a Foundation grant"
37+
src="blog-example.jpg"
38+
width="100%"
39+
/>
40+
</style__StyledImageContainer>
41+
</style__StyledCard>
42+
</style__StyledLink>
43+
`;
44+
45+
exports[`StoryCard renders without required prop 1`] = `
46+
<style__StyledLink
47+
href="kids-help-line"
48+
title="Crisis Text Line provides mental health support for youth during lockdown"
49+
>
50+
<style__StyledCard>
51+
<style__StyledTextBox>
52+
<style__StyledInfoBox>
53+
<style__StyledIconTypeBox>
54+
<style__StyledType />
55+
</style__StyledIconTypeBox>
56+
<style__StyledDate />
57+
</style__StyledInfoBox>
58+
<style__StyledHeadingBox>
59+
<style__StyledHeading>
60+
Crisis Text Line provides mental health support for youth during lockdown
61+
</style__StyledHeading>
62+
</style__StyledHeadingBox>
63+
<style__StyledDescription>
64+
With the help of a Foundation grant
65+
</style__StyledDescription>
66+
</style__StyledTextBox>
67+
<style__StyledImageContainer>
68+
<style__StyledImage
69+
alt="With the help of a Foundation grant"
70+
src="blog-example.jpg"
71+
width="100%"
72+
/>
73+
</style__StyledImageContainer>
74+
</style__StyledCard>
75+
</style__StyledLink>
76+
`;

packages/StoryCard/index.cjs.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const StoryCard = require('./dist/index.cjs')
2+
3+
module.exports = StoryCard

packages/StoryCard/index.es.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import StoryCard from './dist/index.es'
2+
3+
export default StoryCard

packages/StoryCard/package.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "@tds/community-story-card",
3+
"version": "1.0.0-0",
4+
"description": "",
5+
"main": "index.cjs.js",
6+
"module": "index.es.js",
7+
"license": "MIT",
8+
"repository": {
9+
"type": "git",
10+
"url": "git+https://github.com/telus/tds-community.git"
11+
},
12+
"publishConfig": {
13+
"access": "public"
14+
},
15+
"author": "TELUS digital",
16+
"engines": {
17+
"node": ">=8"
18+
},
19+
"bugs": {
20+
"url": "https://github.com/telus/tds-community/issues"
21+
},
22+
"homepage": "http://tds.telus.com",
23+
"peerDependencies": {
24+
"react": "^16.8.2",
25+
"react-dom": "^16.8.2",
26+
"styled-components": "^4.1.3"
27+
},
28+
"dependencies": {
29+
"@tds/util-helpers": "^1.2.0",
30+
"prop-types": "^15.6.2"
31+
}
32+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import configure from '../../config/rollup.config'
2+
import { dependencies } from './package.json'
3+
4+
export default configure({
5+
input: './StoryCard.jsx',
6+
dependencies,
7+
})

0 commit comments

Comments
 (0)