diff --git a/src/atoms/Menu.js b/src/atoms/Menu.js new file mode 100644 index 0000000000000000000000000000000000000000..c7a34a0b41c6abcfad4348cd9d4997807e631cef --- /dev/null +++ b/src/atoms/Menu.js @@ -0,0 +1,75 @@ +import React from 'react' +import classnames from 'classnames' +import classes from './Menu.local.css' + +class Menu extends React.Component { + constructor (props) { + super(props) + + this.state = { + open: false, + selected: props.value + } + } + + toggleMenu = () => { + this.setState({ + open: !this.state.open + }) + } + + handleSelect = selected => { + this.setState({ + selected, + open: false + }) + + // TODO: fire "change" event + } + + optionLabel = value => { + const { options } = this.props + + return options.find(option => option.value === value).label + } + + render () { + const { options, placeholder = 'Choose in the list' } = this.props + const { open, selected } = this.state + + return ( + <div className={classes.root}> + <div> + <button + className={classes.opener} + onClick={this.toggleMenu}> + {selected ? ( + <span>{this.optionLabel(selected)}</span> + ) : ( + <span className={classes.placeholder}>{placeholder}</span> + )} + <span className={classes.arrow}>{ open ? 'â–²' : 'â–¼' }</span> + </button> + </div> + + <div className={classes.menuContainer}> + {open && ( + <div className={classes.menu}> + {options.map(option => ( + <div + key={option.value} + className={classnames(classes.option, { + [classes.active]: option.value === selected + })} + onClick={() => this.handleSelect(option.value)} + >{option.label || option.value}</div> + ))} + </div> + )} + </div> + </div> + ) + } +} + +export default Menu diff --git a/src/atoms/Menu.local.css b/src/atoms/Menu.local.css index 8f3d39ad1084859724f65cca310a050ad6c26432..ac7343c2f7266e08eb983ca9c3f0c7287dde26e8 100644 --- a/src/atoms/Menu.local.css +++ b/src/atoms/Menu.local.css @@ -41,6 +41,7 @@ .option { cursor: pointer; padding: 10px; + white-space: nowrap; } .option:hover { diff --git a/src/index.js b/src/index.js index b506e23840c74411a1874cd888ac3c4cfefd54b1..370bfa72d3e97a6ccb8c547bf623a38d19065ac4 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,4 @@ +export { default as Menu } from './atoms/Menu' export { default as Tags } from './atoms/Tags' export { default as AppBar } from './molecules/AppBar' export { default as YesOrNo } from './molecules/YesOrNo' diff --git a/test/Menu.test.js b/test/Menu.test.js new file mode 100644 index 0000000000000000000000000000000000000000..e575fef6adad697a69f6a20fb925e553c93cd17b --- /dev/null +++ b/test/Menu.test.js @@ -0,0 +1,29 @@ +import React from 'react' +import { shallow } from 'enzyme' +// import renderer from 'react-test-renderer' + +import Menu from '../src/atoms/Menu' + +const props = { + options: [ + { value: 'foo', label: 'Foo' }, + { value: 'bar', label: 'Bar' }, + ], + value: 'foo' +} + +const wrapper = shallow(<Menu {...props} />) + +describe('Menu', () => { + /*test('Snapshot', () => { + const tree = renderer.create( + <Menu {...props} /> + ).toJSON() + expect(tree).toMatchSnapshot() + })*/ + + test('Renders a Menu', () => { + expect(wrapper.is('div')).toBeTruthy() + expect(wrapper).toHaveLength(1) + }) +})