-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Initial button refactor * Set the label correctly * Reorganize and start field guide modal * Try out grid * Basic FieldGuide UI * Restructure components. Scaffold tests * Fix locale. Add tests for FieldGuideItem * Fix FieldGuideItem specs. Add FieldGuideContainer specs * Add tests for FieldGuideItemButton * Add tests for FieldGuideItems * Add tests for FieldGuide, FieldGuideButton, HelpIcon. Fix store tests. * Tweak the hover state styles and modal width. * Apply suggestions from code review Co-Authored-By: srallen <srallen@users.noreply.github.com> * Use an anchor instead of a button for field guide items list * Rename activeItem and associated action to activeItemIndex * Update locale * Fix connected component to use renamed action * Fix renamings. Support setting pad on Modal body. Use CSS grid correctly * Update tests * Be clear about what actions are doing. Set href on anchor. * Fix bug with setting active item index compared to items list length * Remove leftover only
- Loading branch information
1 parent
bd0f331
commit 59ac933
Showing
35 changed files
with
929 additions
and
140 deletions.
There are no files selected for viewing
58 changes: 58 additions & 0 deletions
58
...ges/lib-classifier/src/components/Classifier/components/FieldGuide/FieldGuideContainer.js
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,58 @@ | ||
import { Modal } from '@zooniverse/react-components' | ||
import counterpart from 'counterpart' | ||
import React from 'react' | ||
import PropTypes from 'prop-types' | ||
import { inject, observer } from 'mobx-react' | ||
import FieldGuideButton from './components/FieldGuideButton' | ||
import FieldGuide from './components/FieldGuide' | ||
import en from './locales/en' | ||
|
||
counterpart.registerTranslations('en', en) | ||
|
||
function storeMapper(stores) { | ||
const { setModalVisibility, showModal } = stores.classifierStore.fieldGuide | ||
return { | ||
setModalVisibility, | ||
showModal | ||
} | ||
} | ||
|
||
@inject(storeMapper) | ||
@observer | ||
class FieldGuideContainer extends React.Component { | ||
onClose () { | ||
const { setModalVisibility } = this.props | ||
setModalVisibility(false) | ||
} | ||
|
||
render () { | ||
const { | ||
showModal | ||
} = this.props | ||
|
||
return ( | ||
<> | ||
<FieldGuideButton /> | ||
<Modal | ||
active={showModal} | ||
closeFn={this.onClose.bind(this)} | ||
pad='small' | ||
title={counterpart('FieldGuide.title')} | ||
> | ||
<FieldGuide /> | ||
</Modal> | ||
</> | ||
) | ||
} | ||
} | ||
|
||
FieldGuideContainer.wrappedComponent.defaultProps = { | ||
showModal: false | ||
} | ||
|
||
FieldGuideContainer.wrappedComponent.propTypes = { | ||
setModalVisibility: PropTypes.func.isRequired, | ||
showModal: PropTypes.bool | ||
} | ||
|
||
export default FieldGuideContainer |
26 changes: 26 additions & 0 deletions
26
...ib-classifier/src/components/Classifier/components/FieldGuide/FieldGuideContainer.spec.js
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,26 @@ | ||
import { shallow, mount } from 'enzyme' | ||
import React from 'react' | ||
import sinon from 'sinon' | ||
import { Modal } from '@zooniverse/react-components' | ||
import FieldGuideContainer from './FieldGuideContainer' | ||
|
||
describe('Component > FieldGuideContainer', function () { | ||
it('should render without crashing', function () { | ||
const wrapper = shallow(<FieldGuideContainer.wrappedComponent setModalVisibility={() => {}} />) | ||
expect(wrapper).to.be.ok | ||
}) | ||
|
||
it('should set the Modal active prop with the showModal prop', function () { | ||
const wrapper = shallow(<FieldGuideContainer.wrappedComponent setModalVisibility={() => { }} showModal={false} />) | ||
expect(wrapper.find(Modal).props().active).to.be.false | ||
wrapper.setProps({ showModal: true }) | ||
expect(wrapper.find(Modal).props().active).to.be.true | ||
}) | ||
|
||
it('should call setModalVisibility onClose of the modal', function () { | ||
const setModalVisibilitySpy = sinon.spy() | ||
const wrapper = shallow(<FieldGuideContainer.wrappedComponent setModalVisibility={setModalVisibilitySpy} showModal={true} />) | ||
wrapper.instance().onClose() | ||
expect(setModalVisibilitySpy).to.have.been.calledOnceWith(false) | ||
}) | ||
}) |
49 changes: 49 additions & 0 deletions
49
...ifier/src/components/Classifier/components/FieldGuide/components/FieldGuide/FieldGuide.js
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,49 @@ | ||
import { Box } from 'grommet' | ||
import React from 'react' | ||
import PropTypes from 'prop-types' | ||
import { ResponsiveContext } from 'grommet' | ||
import { inject, observer } from 'mobx-react' | ||
import FieldGuideItems from './components/FieldGuideItems' | ||
import FieldGuideItem from './components/FieldGuideItem' | ||
|
||
function storeMapper(stores) { | ||
const { active: fieldGuide, activeItemIndex } = stores.classifierStore.fieldGuide | ||
return { | ||
activeItemIndex, | ||
items: fieldGuide.items | ||
} | ||
} | ||
|
||
@inject(storeMapper) | ||
@observer | ||
class FieldGuide extends React.Component { | ||
render () { | ||
const { activeItemIndex, className, items } = this.props | ||
return ( | ||
<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 = { | ||
activeItemIndex: -1, | ||
className: '', | ||
} | ||
|
||
FieldGuide.wrappedComponent.propTypes = { | ||
activeItemIndex: PropTypes.number, | ||
className: PropTypes.string, | ||
items: PropTypes.arrayOf(PropTypes.object).isRequired | ||
} | ||
|
||
export default FieldGuide |
51 changes: 51 additions & 0 deletions
51
.../src/components/Classifier/components/FieldGuide/components/FieldGuide/FieldGuide.spec.js
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,51 @@ | ||
import { shallow, mount } from 'enzyme' | ||
import React from 'react' | ||
import FieldGuide from './FieldGuide' | ||
import FieldGuideItem from './components/FieldGuideItem' | ||
import FieldGuideItems from './components/FieldGuideItems' | ||
import { FieldGuideFactory, FieldGuideMediumFactory } from '../../../../../../../test/factories' | ||
|
||
const medium = FieldGuideMediumFactory.build() | ||
const items = [ | ||
{ | ||
title: 'Cat', | ||
icon: medium.id, | ||
content: 'lorem ipsum' | ||
}, | ||
{ | ||
title: 'Dog', | ||
content: 'Foo bar' | ||
}, | ||
{ title: 'Iguana', content: 'hello' }, | ||
{ title: 'Koala', content: '' }, | ||
{ title: 'Dragon', content: 'Why is this here?' } | ||
] | ||
|
||
describe('Component > FieldGuide', function () { | ||
it('should render without crashing', function () { | ||
const wrapper = shallow( | ||
<FieldGuide.wrappedComponent | ||
items={items} | ||
/>) | ||
expect(wrapper).to.be.ok | ||
}) | ||
|
||
xit('should render FieldGuideItems if there is not an active item', function () { | ||
const wrapper = shallow( | ||
<FieldGuide.wrappedComponent | ||
items={items} | ||
/>) | ||
expect(wrapper.find(FieldGuideItems)).to.have.lengthOf(1) | ||
expect(wrapper.find(FieldGuideItem)).to.have.lengthOf(0) | ||
}) | ||
|
||
xit('should render FieldGuideItem if there is an active item', function () { | ||
const wrapper = mount( | ||
<FieldGuide.wrappedComponent | ||
activeItemIndex={0} | ||
items={items} | ||
/>) | ||
expect(wrapper.find(FieldGuideItems)).to.have.lengthOf(0) | ||
expect(wrapper.find(FieldGuideItem)).to.have.lengthOf(1) | ||
}) | ||
}) |
83 changes: 83 additions & 0 deletions
83
...r/components/FieldGuide/components/FieldGuide/components/FieldGuideItem/FieldGuideItem.js
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,83 @@ | ||
import { Button, Box } from 'grommet' | ||
import { FormPrevious } from 'grommet-icons' | ||
import styled from 'styled-components' | ||
import React from 'react' | ||
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 { setActiveItemIndex, attachedMedia: icons } = stores.classifierStore.fieldGuide | ||
return { | ||
icons, | ||
setActiveItemIndex | ||
} | ||
} | ||
|
||
@inject(storeMapper) | ||
@observer | ||
class FieldGuideItem extends React.Component { | ||
render () { | ||
const { className, icons, item, setActiveItemIndex } = this.props | ||
const icon = icons.get(item.icon) | ||
|
||
return ( | ||
<Box className={className}> | ||
<FieldGuideItemHeader align='center' direction='row' margin={{ bottom: 'small' }}> | ||
<StyledButton | ||
a11yTitle={counterpart("FieldGuideItem.ariaTitle")} | ||
icon={<FormPrevious color='light-5' />} | ||
margin={{ right: 'small' }} | ||
onClick={() => setActiveItemIndex()} | ||
plain | ||
/> | ||
<Markdownz> | ||
{`### ${item.title}`} | ||
</Markdownz> | ||
</FieldGuideItemHeader> | ||
<Box direction='column'> | ||
<FieldGuideItemIcon icon={icon} height='140' viewBox='0 0 200 100' /> | ||
<Markdownz> | ||
{item.content} | ||
</Markdownz> | ||
</Box> | ||
</Box> | ||
) | ||
} | ||
} | ||
|
||
FieldGuideItem.wrappedComponent.defaultProps = { | ||
className: '', | ||
icons: observable.map() | ||
} | ||
|
||
FieldGuideItem.wrappedComponent.propTypes = { | ||
className: PropTypes.string, | ||
icons: MobXPropTypes.observableMap, | ||
item: PropTypes.object.isRequired, | ||
setActiveItemIndex: PropTypes.func.isRequired | ||
} | ||
|
||
export default FieldGuideItem |
75 changes: 75 additions & 0 deletions
75
...ponents/FieldGuide/components/FieldGuide/components/FieldGuideItem/FieldGuideItem.spec.js
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,75 @@ | ||
import { shallow, mount } from 'enzyme' | ||
import sinon from 'sinon' | ||
import React from 'react' | ||
import { observable } from 'mobx' | ||
import { Button } from 'grommet' | ||
import { Markdownz, Media } from '@zooniverse/react-components' | ||
import FieldGuideItem from './FieldGuideItem' | ||
import FieldGuideItemIcon from '../FieldGuideItemIcon' | ||
import { FieldGuideMediumFactory } from '../../../../../../../../../test/factories' | ||
|
||
const medium = FieldGuideMediumFactory.build() | ||
const attachedMedia = observable.map() | ||
attachedMedia.set(medium.id, medium) | ||
const item = { | ||
title: 'Cat', | ||
icon: medium.id, | ||
content: 'lorem ipsum' | ||
} | ||
|
||
describe('Component > FieldGuideItem', function () { | ||
it('should render without crashing', function () { | ||
const wrapper = shallow( | ||
<FieldGuideItem.wrappedComponent | ||
icons={attachedMedia} | ||
item={item} | ||
setActiveItemIndex={() => { }} | ||
/>) | ||
expect(wrapper).to.be.ok | ||
}) | ||
|
||
it('should call setActiveItemIndex when the previous button is clicked', function () { | ||
const setActiveItemIndexSpy = sinon.spy() | ||
const wrapper = mount( | ||
<FieldGuideItem.wrappedComponent | ||
icons={attachedMedia} | ||
item={item} | ||
setActiveItemIndex={setActiveItemIndexSpy} | ||
/>) | ||
wrapper.find(Button).simulate('click') | ||
expect(setActiveItemIndexSpy).to.have.been.calledOnceWith() | ||
}) | ||
|
||
it('should render the item title as markdown', function () { | ||
const wrapper = shallow( | ||
<FieldGuideItem.wrappedComponent | ||
icons={attachedMedia} | ||
item={item} | ||
setActiveItemIndex={() => {}} | ||
/>) | ||
|
||
expect(wrapper.find(Markdownz).first().contains(`### ${item.title}`)).to.be.true | ||
}) | ||
|
||
it('should render the item content as markdown', function () { | ||
const wrapper = shallow( | ||
<FieldGuideItem.wrappedComponent | ||
icons={attachedMedia} | ||
item={item} | ||
setActiveItemIndex={() => { }} | ||
/>) | ||
|
||
expect(wrapper.find(Markdownz).last().contains(item.content)).to.be.true | ||
}) | ||
|
||
it('should render a FieldGuideItemIcon component for the icon', function () { | ||
const wrapper = shallow( | ||
<FieldGuideItem.wrappedComponent | ||
icons={attachedMedia} | ||
item={item} | ||
setActiveItemIndex={() => { }} | ||
/>) | ||
|
||
expect(wrapper.find(FieldGuideItemIcon)).to.have.lengthOf(1) | ||
}) | ||
}) |
1 change: 1 addition & 0 deletions
1
...Classifier/components/FieldGuide/components/FieldGuide/components/FieldGuideItem/index.js
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 @@ | ||
export { default } from './FieldGuideItem' |
5 changes: 5 additions & 0 deletions
5
...ier/components/FieldGuide/components/FieldGuide/components/FieldGuideItem/locales/en.json
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,5 @@ | ||
{ | ||
"FieldGuideItem": { | ||
"ariaTitle": "Go back to Field Guide items list" | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
...ents/FieldGuide/components/FieldGuide/components/FieldGuideItemIcon/FieldGuideItemIcon.js
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,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 | ||
} |
Oops, something went wrong.