Skip to content

Commit

Permalink
Fix renamings. Support setting pad on Modal body. Use CSS grid correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
Sarah Allen committed Apr 3, 2019
1 parent 016552e commit f0b57a6
Show file tree
Hide file tree
Showing 13 changed files with 122 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class FieldGuideContainer extends React.Component {
<Modal
active={showModal}
closeFn={this.onClose.bind(this)}
pad='small'
title={counterpart('FieldGuide.title')}
>
<FieldGuide />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
import { Box } from 'grommet'
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { ResponsiveContext } from 'grommet'
import { inject, observer } from 'mobx-react'
import FieldGuideItems from './components/FieldGuideItems'
import FieldGuideItem from './components/FieldGuideItem'

const StyledBox = styled(Box)`
max-height: 415px;
max-width: 490px;
overflow: auto;
`


function storeMapper(stores) {
const { active: fieldGuide, activeItem } = stores.classifierStore.fieldGuide
const { active: fieldGuide, activeItemIndex } = stores.classifierStore.fieldGuide
return {
activeItem,
activeItemIndex,
items: fieldGuide.items
}
}
Expand All @@ -25,24 +18,30 @@ function storeMapper(stores) {
@observer
class FieldGuide extends React.Component {
render () {
const { activeItem, className, items } = this.props
const { activeItemIndex, className, items } = this.props
return (
<StyledBox className={className}>
{items[activeItem] ?
<FieldGuideItem item={items[activeItem]} /> :
<FieldGuideItems items={items} />}
</StyledBox>
<ResponsiveContext.Consumer>
{size => {
const height = (size === 'small') ? '100%' : '415px'
const width = (size === 'small') ? '100%' : '490px'
return (
<Box className={className} height={height} overflow='auto' width={width}>
{items[activeItemIndex] ?
<FieldGuideItem item={items[activeItemIndex]} /> :
<FieldGuideItems items={items} />}
</Box>)}}
</ResponsiveContext.Consumer>
)
}
}

FieldGuide.wrappedComponent.defaultProps = {
activeItem: -1,
activeItemIndex: -1,
className: '',
}

FieldGuide.wrappedComponent.propTypes = {
activeItem: PropTypes.number,
activeItemIndex: PropTypes.number,
className: PropTypes.string,
items: PropTypes.arrayOf(PropTypes.object).isRequired
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,63 @@ import { Button, Box } from 'grommet'
import { FormPrevious } from 'grommet-icons'
import styled from 'styled-components'
import React from 'react'
import { Markdownz, Media } from '@zooniverse/react-components'
import { Markdownz } from '@zooniverse/react-components'
import zooTheme from '@zooniverse/grommet-theme'
import PropTypes from 'prop-types'
import { observable } from 'mobx'
import { inject, observer, PropTypes as MobXPropTypes } from 'mobx-react'
import FieldGuideItemIcon from '../FieldGuideItemIcon'
import counterpart from 'counterpart'
import en from './locales/en'

counterpart.registerTranslations('en', en)

const StyledButton = styled(Button)`
padding: 0;
&:hover > svg, &:focus > svg {
fill: ${zooTheme.global.colors['dark-5']};
stroke: ${zooTheme.global.colors['dark-5']};
}
`

const FieldGuideItemHeader = styled(Box)`
> h3 {
margin: 0;
}
`

function storeMapper(stores) {
const { setActiveItem, attachedMedia: icons } = stores.classifierStore.fieldGuide
const { setActiveItemIndex, attachedMedia: icons } = stores.classifierStore.fieldGuide
return {
icons,
setActiveItem
setActiveItemIndex
}
}

@inject(storeMapper)
@observer
class FieldGuideItem extends React.Component {
render () {
const { className, icons, item, setActiveItem } = this.props
const { className, icons, item, setActiveItemIndex } = this.props
const icon = icons.get(item.icon)

return (
<Box className={className}>
<FieldGuideItemHeader align='center' direction='row'>
<Button
<FieldGuideItemHeader align='center' direction='row' margin={{ bottom: 'small' }}>
<StyledButton
a11yTitle={counterpart("FieldGuideItem.ariaTitle")}
icon={<FormPrevious />}
onClick={() => setActiveItem()}
icon={<FormPrevious color='light-5' />}
margin={{ right: 'small' }}
onClick={() => setActiveItemIndex()}
plain
/>
<Markdownz>
{`### ${item.title}`}
</Markdownz>
</FieldGuideItemHeader>
<Box direction='column'>
{icon && Object.keys(icon).length > 0 &&
<Media fit='contain' height={140} src={icon.src} />}
<FieldGuideItemIcon icon={icon} height='140' viewBox='0 0 200 100' />
<Markdownz>
{item.content}
</Markdownz>
Expand All @@ -66,7 +77,7 @@ FieldGuideItem.wrappedComponent.propTypes = {
className: PropTypes.string,
icons: MobXPropTypes.observableMap,
item: PropTypes.object.isRequired,
setActiveItem: PropTypes.func.isRequired
setActiveItemIndex: PropTypes.func.isRequired
}

export default FieldGuideItem
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,29 @@ describe('Component > FieldGuideItem', function () {
<FieldGuideItem.wrappedComponent
icons={attachedMedia}
item={item}
setActiveItem={() => { }}
setActiveItemIndex={() => { }}
/>)
expect(wrapper).to.be.ok
})

it('should call setActiveItem when the previous button is clicked', function () {
const setActiveItemSpy = sinon.spy()
it('should call setActiveItemIndex when the previous button is clicked', function () {
const setActiveItemIndexSpy = sinon.spy()
const wrapper = mount(
<FieldGuideItem.wrappedComponent
icons={attachedMedia}
item={item}
setActiveItem={setActiveItemSpy}
setActiveItemIndex={setActiveItemIndexSpy}
/>)
wrapper.find(Button).simulate('click')
expect(setActiveItemSpy).to.have.been.calledOnceWith()
expect(setActiveItemIndexSpy).to.have.been.calledOnceWith()
})

it('should render the item title as markdown', function () {
const wrapper = shallow(
<FieldGuideItem.wrappedComponent
icons={attachedMedia}
item={item}
setActiveItem={() => {}}
setActiveItemIndex={() => {}}
/>)

expect(wrapper.find(Markdownz).first().contains(`### ${item.title}`)).to.be.true
Expand All @@ -55,7 +55,7 @@ describe('Component > FieldGuideItem', function () {
<FieldGuideItem.wrappedComponent
icons={attachedMedia}
item={item}
setActiveItem={() => { }}
setActiveItemIndex={() => { }}
/>)

expect(wrapper.find(Markdownz).last().contains(item.content)).to.be.true
Expand All @@ -66,7 +66,7 @@ describe('Component > FieldGuideItem', function () {
<FieldGuideItem.wrappedComponent
icons={attachedMedia}
item={item}
setActiveItem={() => { }}
setActiveItemIndex={() => { }}
/>)

expect(wrapper.find(Media)).to.have.lengthOf(1)
Expand All @@ -78,7 +78,7 @@ describe('Component > FieldGuideItem', function () {
<FieldGuideItem.wrappedComponent
icons={observable.map()}
item={item}
setActiveItem={() => { }}
setActiveItemIndex={() => { }}
/>)

expect(wrapper.find(Media)).to.have.lengthOf(0)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import zooTheme from '@zooniverse/grommet-theme'
import React from 'react'
import { Media } from '@zooniverse/react-components'
import PropTypes from 'prop-types'

export default function FieldGuideItemIcon({ alt, className, height, icon, viewBox, width }) {
if (icon && Object.keys(icon).length > 0) {
return (
<Media alt={alt} className={className} fit='contain' height={height} src={icon.src} width={width} />
)
}

return (
<svg className={className} viewBox={viewBox}>
<rect fill={zooTheme.global.colors['accent-2']} height={height} width={width} />
</svg>
)
}

FieldGuideItemIcon.defaultProps = {
alt: '',
className: '',
height: '100%',
icon: {},
viewBox: '0 0 100 100',
width: '100%'
}

FieldGuideItemIcon.propTypes = {
alt: PropTypes.string,
className: PropTypes.string,
height: PropTypes.string,
icon: PropTypes.object,
viewBox: PropTypes.string,
width: PropTypes.string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './FieldGuideItemIcon'
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
import zooTheme from '@zooniverse/grommet-theme'
import { Anchor, Box } from 'grommet'
import styled from 'styled-components'
import React from 'react'
import { observable } from 'mobx'
import { Markdownz, Media } from '@zooniverse/react-components'
import { Markdownz } from '@zooniverse/react-components'
import PropTypes from 'prop-types'
import { inject, observer, PropTypes as MobXPropTypes } from 'mobx-react'
import FieldGuideItemIcon from '../FieldGuideItemIcon'
import counterpart from 'counterpart'
import en from './locales/en'

counterpart.registerTranslations('en', en)

export function Icon({ className, icon }) {
if (icon && Object.keys(icon).length > 0) {
return (
<Media className={className} src={icon.src} />
)
}

return (
<svg className={className} viewBox='0 0 100 100'>
<rect fill={zooTheme.global.colors['accent-2']} height='100' width='100' />
</svg>
)
}

export function AnchorLabel({ className, icons, item }) {
const icon = icons.get(item.icon)
return (
Expand All @@ -34,7 +19,7 @@ export function AnchorLabel({ className, icons, item }) {
direction='column'
width='100px'
>
<Icon icon={icon} />
<FieldGuideItemIcon alt={item.title} height='100' icon={icon} width='100' />
<Markdownz>
{item.title}
</Markdownz>
Expand All @@ -60,23 +45,18 @@ class FieldGuideItemAnchor extends React.Component {
}

render () {
const { className, icons, row } = this.props
const { className, icons, item } = this.props
const label = <AnchorLabel icons={icons} item={item} />

return (
row.map((item) => {
const label = <AnchorLabel icons={icons} item={item} />
return (
<Anchor
a11yTitle={counterpart('FieldGuideItemAnchor.ariaTitle', { title: item.title })}
className={className}
color='dark-5'
href=''
key={item.title}
label={label}
onClick={(event) => this.onClick(event, item)}
/>
)
})
<Anchor
a11yTitle={counterpart('FieldGuideItemAnchor.ariaTitle', { title: item.title })}
className={className}
color='dark-5'
href=''
label={label}
onClick={(event) => this.onClick(event, item)}
/>
)
}
}
Expand All @@ -89,7 +69,7 @@ FieldGuideItemAnchor.wrappedComponent.defaultProps = {
FieldGuideItemAnchor.wrappedComponent.propTypes = {
className: PropTypes.string,
icons: MobXPropTypes.observableMap,
row: PropTypes.arrayOf(PropTypes.object).isRequired,
item: PropTypes.object.isRequired,
setActiveItemIndex: PropTypes.func.isRequired
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
import { Box, Grid } from 'grommet'
import { Grid } from 'grommet'
import React from 'react'
import PropTypes from 'prop-types'
import chunk from 'lodash/chunk'
import FieldGuideItemAnchor from './FieldGuideItemAnchor'

export default function FieldGuideItems({ className, items }) {
const gridRows = chunk(items, 4)
return (
<Box basis='full' className={className} direction='row' wrap>
{gridRows.map((row, index) => {
return (
<Grid
columns={['100px', '100px', '100px', '100px']}
key={index}
margin={{ bottom: 'small' }}
gap='medium'
rows={['150px']}
>
<FieldGuideItemAnchor row={row} />
</Grid>
)
})}
</Box>
<Grid
className={className}
columns={{ count: 'fill', size: '100px' }}
margin={{ bottom: 'small' }}
gap='medium'
rows='150px'
width='100%'
>
{items.map((item) => {
return (<FieldGuideItemAnchor key={item.title} item={item} />)})}
</Grid>
)
}

Expand Down
1 change: 1 addition & 0 deletions packages/lib-classifier/src/store/FieldGuideStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ const FieldGuideStore = types
}

function setActiveItemIndex (item) {
console.log('calling')
const fieldGuide = self.active
if (fieldGuide) {
const { items } = fieldGuide
Expand Down
Loading

0 comments on commit f0b57a6

Please sign in to comment.