Skip to content

Commit

Permalink
Add functionality for renderBack on menus, and fix implementations …
Browse files Browse the repository at this point in the history
…of `renderHeader` and `renderFooter` (#70)
  • Loading branch information
kevhender authored Apr 21, 2020
1 parent 3296621 commit 6b83c99
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 7 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-storefront",
"version": "7.11.2",
"version": "7.12.0",
"description": "Build and deploy e-commerce progressive web apps (PWAs) in record time.",
"module": "./index.js",
"license": "Apache-2.0",
Expand Down
12 changes: 12 additions & 0 deletions src/menu/Menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const Menu = React.memo(props => {
onClose,
renderFooter,
renderHeader,
renderBack,
renderItem,
renderItemContent,
renderDrawer,
Expand Down Expand Up @@ -84,6 +85,7 @@ const Menu = React.memo(props => {
goBack,
renderFooter,
renderHeader,
renderBack,
renderItem,
renderItemContent,
close: onClose,
Expand Down Expand Up @@ -170,6 +172,16 @@ Menu.propTypes = {
*/
renderFooter: PropTypes.func,

/**
* A function to render a custom back navigation for menu cards. It is passed
* an object with:
*
* - item: The menu item record being rendered
*
* The function should return a React element or fragment.
*/
renderBack: PropTypes.func,

/**
* Set to true to display the menu
*/
Expand Down
8 changes: 6 additions & 2 deletions src/menu/MenuBack.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ListItem, ListItemIcon, ListItemText } from '@material-ui/core'
import { ChevronLeft } from '@material-ui/icons'

export default function MenuBack({ goBack, item, backButtonProps }) {
const { classes } = useContext(MenuContext)
const { classes, renderBack } = useContext(MenuContext)

return (
<ListItem divider button onClick={goBack} {...backButtonProps}>
Expand All @@ -14,7 +14,11 @@ export default function MenuBack({ goBack, item, backButtonProps }) {
</ListItemIcon>
<ListItemText
classes={{ root: classes.headerText }}
primary={<div className={classes.headerText}>{item.text} </div>}
primary={
<div className={classes.headerText}>
{typeof renderBack === 'function' ? renderBack(item) : item.text}
</div>
}
/>
</ListItem>
)
Expand Down
10 changes: 8 additions & 2 deletions src/menu/MenuFooter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState, useEffect, useContext } from 'react'
import makeStyles from '@material-ui/core/styles/makeStyles'
import PropTypes from 'prop-types'
import CmsSlot from '../CmsSlot'
import MenuContext from './MenuContext'

export const styles = theme => ({
root: {
Expand All @@ -12,16 +13,21 @@ const useStyles = makeStyles(styles, { name: 'RSFMenuFooter' })

export default function MenuFooter({ classes, item }) {
classes = useStyles({ classes })
const { renderFooter } = useContext(MenuContext)

if (typeof renderFooter === 'function') {
return <div className={classes.root}>{renderFooter(item)}</div>
}

if (item.footer) {
return (
<div className={classes.root}>
<CmsSlot>{item.footer}</CmsSlot>
</div>
)
} else {
return null
}

return null
}

MenuFooter.propTypes = {
Expand Down
10 changes: 8 additions & 2 deletions src/menu/MenuHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState, useEffect, useContext } from 'react'
import makeStyles from '@material-ui/core/styles/makeStyles'
import PropTypes from 'prop-types'
import CmsSlot from '../CmsSlot'
import MenuContext from './MenuContext'

export const styles = theme => ({
root: {
Expand All @@ -13,16 +14,21 @@ const useStyles = makeStyles(styles, { name: 'RSFMenuHeader' })

export default function MenuHeader({ classes, item }) {
classes = useStyles({ classes })
const { renderHeader } = useContext(MenuContext)

if (typeof renderHeader === 'function') {
return <div className={classes.root}>{renderHeader(item)}</div>
}

if (item.header) {
return (
<div className={classes.root}>
<CmsSlot>{item.header}</CmsSlot>
</div>
)
} else {
return null
}

return null
}

MenuHeader.propTypes = {
Expand Down
64 changes: 64 additions & 0 deletions test/menu/Menu.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ describe('Menu', () => {
expect(wrapper.find(MenuFooter).length).toBe(1)
})

it('should render custom footer', () => {
wrapper = mount(
<Menu
root={{
text: 'root',
items: [{ text: 'item1', href: '/item1', as: '/item1', items: [] }],
}}
renderFooter={item => `${item.text} footer`}
/>,
)
expect(wrapper.find(MenuFooter).text()).toBe('root footer')
})

it('should render header', () => {
wrapper = mount(
<Menu
Expand All @@ -47,6 +60,19 @@ describe('Menu', () => {
expect(wrapper.find(MenuHeader).length).toBe(1)
})

it('should render custom header', () => {
wrapper = mount(
<Menu
root={{
text: 'root',
items: [{ text: 'item1', href: '/item1', as: '/item1', items: [] }],
}}
renderHeader={item => `${item.text} header`}
/>,
)
expect(wrapper.find(MenuHeader).text()).toBe('root header')
})

it('should navigate to submenu', () => {
wrapper = mount(
<Menu
Expand Down Expand Up @@ -198,4 +224,42 @@ describe('Menu', () => {
.simulate('click')
expect(wrapper.find(ChevronLeft).length).toBe(1)
})

it('should render custom text for back button in secondary menu', () => {
wrapper = mount(
<Menu
open
renderBack={() => 'Back'}
root={{
text: 'foo',
items: [
{
text: 'foo',
href: '/foo',
as: '/foo',
items: [
{
text: 'bar',
href: '/bar',
as: '/bar',
items: [
{
text: 'foo3',
href: '/foo3',
as: '/foo3',
},
],
},
],
},
],
}}
/>,
)
wrapper
.find(ListItem)
.at(0)
.simulate('click')
expect(wrapper.find(MenuBack).text()).toBe('Back')
})
})

0 comments on commit 6b83c99

Please sign in to comment.