From 0f51c06c3bc7b44799facada84818a6214d08de0 Mon Sep 17 00:00:00 2001 From: adamhenson Date: Sun, 27 Aug 2017 17:17:53 -0400 Subject: [PATCH 1/4] IconMenu: active prop (fixes #1662). --- components/menu/IconMenu.js | 14 ++++++++--- components/menu/__test__/index.spec.js | 34 +++++++++++++++++++++++++- components/menu/readme.md | 1 + 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/components/menu/IconMenu.js b/components/menu/IconMenu.js index e82e7fd4..6f8ca080 100644 --- a/components/menu/IconMenu.js +++ b/components/menu/IconMenu.js @@ -9,6 +9,7 @@ import InjectMenu from './Menu'; const factory = (IconButton, Menu) => { class IconMenu extends Component { static propTypes = { + active: PropTypes.bool, children: PropTypes.node, className: PropTypes.string, icon: PropTypes.oneOfType([ @@ -32,6 +33,7 @@ const factory = (IconButton, Menu) => { }; static defaultProps = { + active: false, className: '', icon: 'more_vert', iconRipple: true, @@ -41,7 +43,13 @@ const factory = (IconButton, Menu) => { }; state = { - active: false, + active: this.props.active, + } + + componentWillReceiveProps(nextProps) { + if (nextProps.active !== this.props.active && this.state.active !== nextProps.active) { + this.setState({ active: nextProps.active }); + } } handleButtonClick = (event) => { @@ -56,8 +64,8 @@ const factory = (IconButton, Menu) => { render() { const { - children, className, icon, iconRipple, inverse, menuRipple, onHide, // eslint-disable-line - onSelect, onShow, position, selectable, selected, theme, ...other + active, children, className, icon, iconRipple, inverse, menuRipple, // eslint-disable-line + onHide, onSelect, onShow, position, selectable, selected, theme, ...other } = this.props; return (
diff --git a/components/menu/__test__/index.spec.js b/components/menu/__test__/index.spec.js index be98b943..f11ab1ef 100644 --- a/components/menu/__test__/index.spec.js +++ b/components/menu/__test__/index.spec.js @@ -1,8 +1,40 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { mount, shallow } from 'enzyme'; +import { IconMenu } from '../IconMenu'; import { Menu } from '../Menu'; import { MenuItem } from '../MenuItem'; +describe('IconMenu', () => { + describe('#on mount', () => { + describe('when \'active\' prop is not set', () => { + it('sets \'active\' Menu prop correctly', () => { + const wrapper = shallow(); + expect(wrapper.find('Menu').props().active).toBe(false); + }); + }); + + describe('when \'active\' prop is set to false', () => { + it('sets \'active\' Menu prop correctly', () => { + const wrapper = shallow(); + expect(wrapper.find('Menu').props().active).toBe(false); + }); + }); + + describe('when \'active\' prop is set to true', () => { + it('sets \'active\' Menu prop correctly', () => { + const wrapper = shallow(); + expect(wrapper.find('Menu').props().active).toBe(true); + }); + + it('sets \'active\' Menu prop correctly after IconButton click', () => { + const wrapper = mount(); + wrapper.find('IconButton').simulate('click'); + expect(wrapper.find('Menu').props().active).toBe(false); + }); + }); + }); +}); + describe('MenuItem', () => { describe('#onClick', () => { it('passes to listener the event', () => { diff --git a/components/menu/readme.md b/components/menu/readme.md index 8bf58b99..a897042f 100644 --- a/components/menu/readme.md +++ b/components/menu/readme.md @@ -61,6 +61,7 @@ As the most usual scenario will be to open the menu from a click in an Icon, we | Name | Type | Default | Description| |:-----|:-----|:-----|:-----| +| `active` | `Boolean` | `false` | If true, the inner `Menu` component will be active. | | `className` | `String` | `''` | Set a class to give custom styles to the icon wrapper.| | `icon` | `String` or `Element` | `more_vert` | Icon font key string or Element to display the opener icon. | | `iconRipple` | `Boolean` | `true` | If true, the icon will show a ripple when is clicked. | From 74bd2dc77bd0a09245694be15e479ae6722f11af Mon Sep 17 00:00:00 2001 From: adamhenson Date: Sun, 27 Aug 2017 19:10:01 -0400 Subject: [PATCH 2/4] IconMenu: active prop (#1662). --- components/menu/IconMenu.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/menu/IconMenu.js b/components/menu/IconMenu.js index 6f8ca080..2b3bad2d 100644 --- a/components/menu/IconMenu.js +++ b/components/menu/IconMenu.js @@ -64,8 +64,8 @@ const factory = (IconButton, Menu) => { render() { const { - active, children, className, icon, iconRipple, inverse, menuRipple, // eslint-disable-line - onHide, onSelect, onShow, position, selectable, selected, theme, ...other + active, children, className, icon, iconRipple, inverse, menuRipple, onHide, // eslint-disable-line + onSelect, onShow, position, selectable, selected, theme, ...other } = this.props; return (
From bf790d7b867076798297a031c65a0bc6412fc870 Mon Sep 17 00:00:00 2001 From: Adam Henson Date: Sun, 27 Aug 2017 23:47:09 -0400 Subject: [PATCH 3/4] IconMenu: active prop (#1662). more tests. --- components/menu/IconMenu.js | 2 +- components/menu/__test__/index.spec.js | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/components/menu/IconMenu.js b/components/menu/IconMenu.js index 2b3bad2d..d00fd3f5 100644 --- a/components/menu/IconMenu.js +++ b/components/menu/IconMenu.js @@ -47,7 +47,7 @@ const factory = (IconButton, Menu) => { } componentWillReceiveProps(nextProps) { - if (nextProps.active !== this.props.active && this.state.active !== nextProps.active) { + if (this.state.active !== nextProps.active) { this.setState({ active: nextProps.active }); } } diff --git a/components/menu/__test__/index.spec.js b/components/menu/__test__/index.spec.js index f11ab1ef..59624fcf 100644 --- a/components/menu/__test__/index.spec.js +++ b/components/menu/__test__/index.spec.js @@ -18,6 +18,19 @@ describe('IconMenu', () => { const wrapper = shallow(); expect(wrapper.find('Menu').props().active).toBe(false); }); + + it('sets \'active\' Menu prop correctly after IconButton click', () => { + const wrapper = mount(); + wrapper.find('IconButton').simulate('click'); + expect(wrapper.find('Menu').props().active).toBe(true); + }); + + it('sets \'active\' Menu prop correctly when prop is set after IconButton click', () => { + const wrapper = mount(); + wrapper.find('IconButton').simulate('click'); + wrapper.setProps({ active: false }); + expect(wrapper.find('Menu').props().active).toBe(false); + }); }); describe('when \'active\' prop is set to true', () => { @@ -31,6 +44,13 @@ describe('IconMenu', () => { wrapper.find('IconButton').simulate('click'); expect(wrapper.find('Menu').props().active).toBe(false); }); + + it('sets \'active\' Menu prop correctly when prop is set after IconButton click', () => { + const wrapper = mount(); + wrapper.find('IconButton').simulate('click'); + wrapper.setProps({ active: true }); + expect(wrapper.find('Menu').props().active).toBe(true); + }); }); }); }); From 0103d955b051f30ee48f56b0ab60371d23d4ba8c Mon Sep 17 00:00:00 2001 From: Adam Henson Date: Mon, 28 Aug 2017 00:00:21 -0400 Subject: [PATCH 4/4] IconMenu: active prop (#1662). --- components/menu/IconMenu.d.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/menu/IconMenu.d.ts b/components/menu/IconMenu.d.ts index 931bcfe0..f7140965 100644 --- a/components/menu/IconMenu.d.ts +++ b/components/menu/IconMenu.d.ts @@ -13,6 +13,11 @@ export interface IconMenuTheme { } export interface IconMenuProps extends ReactToolbox.Props { + /** + * If true, the inner Menu component will be active. + * @default false + */ + active?: boolean; /** * Children to pass through the component. */