Skip to content

Commit a325e20

Browse files
authored
Merge pull request react-toolbox#1663 from adamhenson/iconmenu-active-prop
IconMenu: New "active" Prop (fixes react-toolbox#1662)
2 parents a473c94 + c6a7301 commit a325e20

File tree

4 files changed

+69
-3
lines changed

4 files changed

+69
-3
lines changed

components/menu/IconMenu.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ export interface IconMenuTheme {
1313
}
1414

1515
export interface IconMenuProps extends ReactToolbox.Props {
16+
/**
17+
* If true, the inner Menu component will be active.
18+
* @default false
19+
*/
20+
active?: boolean;
1621
/**
1722
* Children to pass through the component.
1823
*/

components/menu/IconMenu.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import InjectMenu from './Menu';
99
const factory = (IconButton, Menu) => {
1010
class IconMenu extends Component {
1111
static propTypes = {
12+
active: PropTypes.bool,
1213
children: PropTypes.node,
1314
className: PropTypes.string,
1415
icon: PropTypes.oneOfType([
@@ -32,6 +33,7 @@ const factory = (IconButton, Menu) => {
3233
};
3334

3435
static defaultProps = {
36+
active: false,
3537
className: '',
3638
icon: 'more_vert',
3739
iconRipple: true,
@@ -41,7 +43,13 @@ const factory = (IconButton, Menu) => {
4143
};
4244

4345
state = {
44-
active: false,
46+
active: this.props.active,
47+
}
48+
49+
componentWillReceiveProps(nextProps) {
50+
if (this.state.active !== nextProps.active) {
51+
this.setState({ active: nextProps.active });
52+
}
4553
}
4654

4755
handleButtonClick = (event) => {
@@ -56,7 +64,7 @@ const factory = (IconButton, Menu) => {
5664

5765
render() {
5866
const {
59-
children, className, icon, iconRipple, inverse, menuRipple, onHide, // eslint-disable-line
67+
active, children, className, icon, iconRipple, inverse, menuRipple, onHide, // eslint-disable-line
6068
onSelect, onShow, position, selectable, selected, theme, ...other
6169
} = this.props;
6270
return (

components/menu/__test__/index.spec.js

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,60 @@
11
import React from 'react';
2-
import { shallow } from 'enzyme';
2+
import { mount, shallow } from 'enzyme';
3+
import { IconMenu } from '../IconMenu';
34
import { Menu } from '../Menu';
45
import { MenuItem } from '../MenuItem';
56

7+
describe('IconMenu', () => {
8+
describe('#on mount', () => {
9+
describe('when \'active\' prop is not set', () => {
10+
it('sets \'active\' Menu prop correctly', () => {
11+
const wrapper = shallow(<IconMenu />);
12+
expect(wrapper.find('Menu').props().active).toBe(false);
13+
});
14+
});
15+
16+
describe('when \'active\' prop is set to false', () => {
17+
it('sets \'active\' Menu prop correctly', () => {
18+
const wrapper = shallow(<IconMenu active={false} />);
19+
expect(wrapper.find('Menu').props().active).toBe(false);
20+
});
21+
22+
it('sets \'active\' Menu prop correctly after IconButton click', () => {
23+
const wrapper = mount(<IconMenu active={false} />);
24+
wrapper.find('IconButton').simulate('click');
25+
expect(wrapper.find('Menu').props().active).toBe(true);
26+
});
27+
28+
it('sets \'active\' Menu prop correctly when prop is set after IconButton click', () => {
29+
const wrapper = mount(<IconMenu active={false} />);
30+
wrapper.find('IconButton').simulate('click');
31+
wrapper.setProps({ active: false });
32+
expect(wrapper.find('Menu').props().active).toBe(false);
33+
});
34+
});
35+
36+
describe('when \'active\' prop is set to true', () => {
37+
it('sets \'active\' Menu prop correctly', () => {
38+
const wrapper = shallow(<IconMenu active />);
39+
expect(wrapper.find('Menu').props().active).toBe(true);
40+
});
41+
42+
it('sets \'active\' Menu prop correctly after IconButton click', () => {
43+
const wrapper = mount(<IconMenu active />);
44+
wrapper.find('IconButton').simulate('click');
45+
expect(wrapper.find('Menu').props().active).toBe(false);
46+
});
47+
48+
it('sets \'active\' Menu prop correctly when prop is set after IconButton click', () => {
49+
const wrapper = mount(<IconMenu active />);
50+
wrapper.find('IconButton').simulate('click');
51+
wrapper.setProps({ active: true });
52+
expect(wrapper.find('Menu').props().active).toBe(true);
53+
});
54+
});
55+
});
56+
});
57+
658
describe('MenuItem', () => {
759
describe('#onClick', () => {
860
it('passes to listener the event', () => {

components/menu/readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ As the most usual scenario will be to open the menu from a click in an Icon, we
6161

6262
| Name | Type | Default | Description|
6363
|:-----|:-----|:-----|:-----|
64+
| `active` | `Boolean` | `false` | If true, the inner `Menu` component will be active. |
6465
| `className` | `String` | `''` | Set a class to give custom styles to the icon wrapper.|
6566
| `icon` | `String` or `Element` | `more_vert` | Icon font key string or Element to display the opener icon. |
6667
| `iconRipple` | `Boolean` | `true` | If true, the icon will show a ripple when is clicked. |

0 commit comments

Comments
 (0)