Skip to content

Commit

Permalink
Movable field guide (#1968)
Browse files Browse the repository at this point in the history
* Beginning of implementing the movable field guide

* Update rendering logic

* Fix position

* Beginning of implementing the movable field guide

* Update rendering logic

* Fix position

* Field guide refactoring (#1975)

* Refactor to use context API for store connection. Remove redundant SpacedHeading.

* Add connector specs

* Update container props and specs

* Rewrite FieldGuide specs

* Fix FieldGuideItemAnchor specs'

* Fix FieldGuideButton specs

* Remove cruft

* Make field guide optional with null default to account for projects without a field guide

* Fix story. Fix resizability. Use standard Modal on small window sizes

* Refactor to use Modal at small sizes and update tests

* Fix return from context consumer. Use mount in tests

* Control the height of the react-rnd container on resize

* Refactor container component to separate out local component state usage. Fix resizing by manually setting it
  • Loading branch information
srallen authored Feb 15, 2021
1 parent cbdada7 commit 78b017f
Show file tree
Hide file tree
Showing 26 changed files with 736 additions and 336 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import zooTheme from '@zooniverse/grommet-theme'
import { Box, Grommet } from 'grommet'
import { Provider } from 'mobx-react'
import FieldGuideContainer from './FieldGuideContainer'
import FieldGuideConnector from './FieldGuideConnector'
import FieldGuideStore from '@store/FieldGuideStore'
import {
FieldGuideFactory,
Expand Down Expand Up @@ -42,7 +42,7 @@ const mockStore = {

export default {
title: 'Help Resources/Field Guide',
component: FieldGuideContainer,
component: FieldGuideConnector,
parameters: {
viewport: {
defaultViewport: 'responsive'
Expand All @@ -63,7 +63,7 @@ function FieldGuideStoryContext (props) {
themeMode={(props.darkMode) ? 'dark' : 'light'}
>
<Box height='60px' width='60px'>
<FieldGuideContainer />
<FieldGuideConnector />
</Box>
</Grommet>
</Provider>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react'
import { MobXProviderContext, observer } from 'mobx-react'
import FieldGuideWrapper from './FieldGuideWrapper'

function useStores() {
const stores = React.useContext(MobXProviderContext)

const {
active: fieldGuide,
attachedMedia: icons,
activeItemIndex,
setActiveItemIndex,
setModalVisibility,
showModal
} = stores.classifierStore.fieldGuide

return {
activeItemIndex,
fieldGuide,
icons,
setActiveItemIndex,
setModalVisibility,
showModal
}
}

function FieldGuideConnector(props) {
const {
activeItemIndex,
fieldGuide,
icons,
setActiveItemIndex,
setModalVisibility,
showModal
} = useStores()

return (
<FieldGuideWrapper
activeItemIndex={activeItemIndex}
fieldGuide={fieldGuide}
icons={icons}
setActiveItemIndex={setActiveItemIndex}
setModalVisibility={setModalVisibility}
showModal={showModal}
{...props}
/>
)
}

export default observer(FieldGuideConnector)
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { shallow } from 'enzyme'
import React from 'react'
import sinon from 'sinon'
import FieldGuideConnector from './FieldGuideConnector'
import FieldGuideWrapper from './FieldGuideWrapper'

const mockStoreSnapshot = {
classifierStore: {
fieldGuide: {
active: '1',
attachedMedia: {
2: {
id: '2',
src: 'media.jpg'
}
},
activeItemIndex: -1,
setActiveItemIndex: () => {},
setModalVisibility: () => {},
showModal: false
}
}
}

describe('FieldGuideConnector', function () {
let wrapper, useContextMock, containerProps
before(function () {
useContextMock = sinon.stub(React, 'useContext').callsFake(() => mockStoreSnapshot)
wrapper = shallow(
<FieldGuideConnector foo='bar' />
)
containerProps = wrapper.find(FieldGuideWrapper).props()
})

after(function () {
useContextMock.restore()
})

it('should render without crashing', function () {
expect(wrapper).to.be.ok()
})

it('should pass the active field guide as a prop', function () {
expect(containerProps.fieldGuide).to.deep.equal(mockStoreSnapshot.classifierStore.fieldGuide.active)
})

it('should pass the attached media as the icons prop', function () {
expect(containerProps.icons).to.deep.equal(mockStoreSnapshot.classifierStore.fieldGuide.attachedMedia)
})

it('should pass the activeItemIndex as a prop', function () {
expect(containerProps.activeItemIndex).to.deep.equal(mockStoreSnapshot.classifierStore.fieldGuide.activeItemIndex)
})

it('should pass the setActiveItemIndex function', function () {
expect(containerProps.setActiveItemIndex).to.deep.equal(mockStoreSnapshot.classifierStore.fieldGuide.setActiveItemIndex)
})

it('should pass the setModalVisibility function', function () {
expect(containerProps.setModalVisibility).to.deep.equal(mockStoreSnapshot.classifierStore.fieldGuide.setModalVisibility)
})

it('should pass the showModal boolean as a prop', function () {
expect(containerProps.showModal).to.deep.equal(mockStoreSnapshot.classifierStore.fieldGuide.showModal)
})

it('should pass along any other props', function () {
expect(containerProps.foo).to.equal('bar')
})
})

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react'
import PropTypes from 'prop-types'
import { observable } from 'mobx'
import { PropTypes as MobXPropTypes } from 'mobx-react'
import { ResponsiveContext } from 'grommet'
import FieldGuideButton from './components/FieldGuideButton'
import FieldGuide from './components/FieldGuide'

function FieldGuideWrapper (props) {
const {
fieldGuide,
setModalVisibility,
showModal
} = props

return (
<>
<FieldGuideButton fieldGuide={fieldGuide} onOpen={() => setModalVisibility(true)} />
{showModal &&
<ResponsiveContext.Consumer>
{size => (
<FieldGuide
onClose={() => setModalVisibility(false)}
size={size}
{...props}
/>
)}
</ResponsiveContext.Consumer>
}
</>
)
}

FieldGuideWrapper.defaultProps = {
activeItemIndex: -1,
fieldGuide: null,
icons: observable.map(),
showModal: false
}

FieldGuideWrapper.propTypes = {
activeItemIndex: PropTypes.number,
fieldGuide: PropTypes.object,
icons: MobXPropTypes.observableMap,
setActiveItemIndex: PropTypes.func.isRequired,
setModalVisibility: PropTypes.func.isRequired,
showModal: PropTypes.bool
}

export default FieldGuideWrapper
Loading

0 comments on commit 78b017f

Please sign in to comment.