Skip to content

Commit 5bd2b3f

Browse files
authored
Merge pull request #15 from react-storefront-community/feature/breadcrumbs
feat: Add Breadcrumbs component
2 parents 5d525db + c065dc1 commit 5bd2b3f

File tree

3 files changed

+112
-1
lines changed

3 files changed

+112
-1
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-storefront",
3-
"version": "7.0.0-alpha.8",
3+
"version": "7.0.0",
44
"description": "Build and deploy e-commerce progressive web apps (PWAs) in record time.",
55
"module": "./index.js",
66
"license": "Apache-2.0",

src/Breadcrumbs.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React from 'react'
2+
import { KeyboardArrowRight as ArrowRight } from '@material-ui/icons'
3+
import Link from './link/Link'
4+
import clsx from 'clsx'
5+
import { Typography, Container } from '@material-ui/core'
6+
import { makeStyles } from '@material-ui/core/styles'
7+
import PropTypes from 'prop-types'
8+
9+
export const styles = theme => ({
10+
breadcrumbs: {
11+
backgroundColor: '#F4F2F1',
12+
padding: '12px 0',
13+
14+
'& a': {
15+
color: theme.palette.text.primary,
16+
textDecoration: 'none',
17+
},
18+
},
19+
20+
separator: {
21+
height: '12px',
22+
position: 'relative',
23+
top: '2px',
24+
width: '16px',
25+
},
26+
27+
current: {
28+
fontWeight: 'bold',
29+
color: theme.palette.text.primary,
30+
},
31+
})
32+
33+
const useStyles = makeStyles(styles, 'RSFBreadcrumbs')
34+
35+
export default function Breadcrumbs({ items, classes }) {
36+
classes = useStyles({ classes })
37+
38+
return (
39+
<Typography display="block" className={classes.breadcrumbs} variant="caption">
40+
<Container>
41+
{items &&
42+
items.map((item, i) => {
43+
const arrow = i > 0 ? <ArrowRight className={classes.separator} /> : null
44+
const isLastItem = items.length - 1 === i
45+
46+
if (item.href) {
47+
return (
48+
<span key={i} className={clsx(isLastItem && classes.current)}>
49+
{arrow}
50+
<Link href={item.href} as={item.as}>
51+
{item.text}
52+
</Link>
53+
</span>
54+
)
55+
} else {
56+
return (
57+
<span key={i} className={clsx(isLastItem && classes.current)}>
58+
{arrow}
59+
{item.text}
60+
</span>
61+
)
62+
}
63+
})}
64+
<span>&nbsp;</span>
65+
</Container>
66+
</Typography>
67+
)
68+
}
69+
70+
Breadcrumbs.propTypes = {
71+
/**
72+
* The items to display, each with url, text, and state.
73+
*/
74+
items: PropTypes.arrayOf(PropTypes.objectOf),
75+
}

test/BreadCrumbs.test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from 'react'
2+
import { mount } from 'enzyme'
3+
import Breadcrumbs from 'react-storefront/Breadcrumbs'
4+
import { Typography, Container } from '@material-ui/core'
5+
6+
describe('Breadcrumbs', () => {
7+
let wrapper
8+
9+
afterEach(() => {
10+
wrapper.unmount()
11+
})
12+
13+
it('should render empty span when no items provided', () => {
14+
wrapper = mount(<Breadcrumbs items={null} />)
15+
16+
expect(wrapper.find(Container).children.length).toBe(1)
17+
})
18+
19+
it('should apply bold style to last item', () => {
20+
const items = [{ text: 'test1' }, { text: 'test2' }]
21+
wrapper = mount(<Breadcrumbs items={items} />)
22+
23+
expect(
24+
wrapper
25+
.findWhere(item => item.type() === 'span' && item.text() === 'test2')
26+
.prop('className'),
27+
).toContain('current')
28+
})
29+
30+
it('should render items with href as a link', () => {
31+
const items = [{ text: 'test1', href: '/test' }]
32+
wrapper = mount(<Breadcrumbs items={items} />)
33+
34+
expect(wrapper.find('a').text()).toBe('test1')
35+
})
36+
})

0 commit comments

Comments
 (0)