From 482c9d4d1ec2998beafbb00da866d46ebbcfc645 Mon Sep 17 00:00:00 2001 From: David Madner Date: Fri, 29 Jul 2016 15:11:26 +0200 Subject: [PATCH 1/4] Toggle open state of nested list dynamically after component did mount. ref #4803 --- .../pages/components/List/ExampleNested.js | 104 ++++++++++++------ src/List/ListItem.js | 10 ++ 2 files changed, 81 insertions(+), 33 deletions(-) diff --git a/docs/src/app/components/pages/components/List/ExampleNested.js b/docs/src/app/components/pages/components/List/ExampleNested.js index 0ee790c33c01d9..209c5c27158459 100644 --- a/docs/src/app/components/pages/components/List/ExampleNested.js +++ b/docs/src/app/components/pages/components/List/ExampleNested.js @@ -1,42 +1,80 @@ import React from 'react'; import MobileTearSheet from '../../../MobileTearSheet'; -import {List, ListItem} from 'material-ui/List'; +import { List, ListItem } from 'material-ui/List'; import ActionGrade from 'material-ui/svg-icons/action/grade'; import ContentInbox from 'material-ui/svg-icons/content/inbox'; import ContentDrafts from 'material-ui/svg-icons/content/drafts'; import ContentSend from 'material-ui/svg-icons/content/send'; import Subheader from 'material-ui/Subheader'; +import Toggle from 'material-ui/Toggle' -const ListExampleNested = () => ( - - - Nested List Items - } /> - } /> - } - initiallyOpen={true} - primaryTogglesNestedList={true} - nestedItems={[ - } - />, - } - disabled={true} - nestedItems={[ - } />, - ]} - />, - ]} - /> - - -); +export default class ListExampleNested extends React.Component { -export default ListExampleNested; + state = { + open: false + }; + + handleToggle = () => { + this.setState({ + open: !this.state.open + }); + }; + + syncState = (item) => { + this.setState({ + open: item.state.open + }); + }; + + render() { + return ( +
+
+ + + Nested List Items + } /> + } /> + } + initiallyOpen={true} + primaryTogglesNestedList={true} + nestedItems={[ + } + />, + } + disabled={true} + nestedItems={[ + } />, + ]} + />, + } + open={this.state.open} + onNestedListToggle={this.syncState} + nestedItems={[ + } />, + ]} + /> + ]} + /> + + +
+ ); + } +} diff --git a/src/List/ListItem.js b/src/List/ListItem.js index 7840aefd4f931a..de08874b29f66c 100644 --- a/src/List/ListItem.js +++ b/src/List/ListItem.js @@ -223,6 +223,10 @@ class ListItem extends Component { onTouchStart: PropTypes.func, /** @ignore */ onTouchTap: PropTypes.func, + /** + * Control toggle state of nested list. + */ + open: PropTypes.bool, /** * This is the block element that contains the primary text. * If a string is passed in, a div tag will be rendered. @@ -305,6 +309,12 @@ class ListItem extends Component { } } + componentWillReceiveProps(nextProps) { + if (this.props.open !== nextProps.open) { + this.setState({open: nextProps.open}); + } + } + shouldComponentUpdate(nextProps, nextState, nextContext) { return ( !shallowEqual(this.props, nextProps) || From d5fe3537b1d97c78c2e647fdbe7a1e208277f295 Mon Sep 17 00:00:00 2001 From: David Madner Date: Fri, 29 Jul 2016 15:24:59 +0200 Subject: [PATCH 2/4] Fix eslint errors. --- .../pages/components/List/ExampleNested.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/src/app/components/pages/components/List/ExampleNested.js b/docs/src/app/components/pages/components/List/ExampleNested.js index 209c5c27158459..539aef945c8f9d 100644 --- a/docs/src/app/components/pages/components/List/ExampleNested.js +++ b/docs/src/app/components/pages/components/List/ExampleNested.js @@ -1,28 +1,28 @@ import React from 'react'; import MobileTearSheet from '../../../MobileTearSheet'; -import { List, ListItem } from 'material-ui/List'; +import {List, ListItem} from 'material-ui/List'; import ActionGrade from 'material-ui/svg-icons/action/grade'; import ContentInbox from 'material-ui/svg-icons/content/inbox'; import ContentDrafts from 'material-ui/svg-icons/content/drafts'; import ContentSend from 'material-ui/svg-icons/content/send'; import Subheader from 'material-ui/Subheader'; -import Toggle from 'material-ui/Toggle' +import Toggle from 'material-ui/Toggle'; export default class ListExampleNested extends React.Component { state = { - open: false + open: false, }; handleToggle = () => { this.setState({ - open: !this.state.open + open: !this.state.open, }); }; - syncState = (item) => { + handleNestedListToggle = (item) => { this.setState({ - open: item.state.open + open: item.state.open, }); }; @@ -34,7 +34,8 @@ export default class ListExampleNested extends React.Component { onToggle={this.handleToggle} labelPosition="right" label="This toggle controls the expanded state of the submenu item." - />
+ /> +
Nested List Items @@ -65,11 +66,11 @@ export default class ListExampleNested extends React.Component { primaryText="Inbox" leftIcon={} open={this.state.open} - onNestedListToggle={this.syncState} + onNestedListToggle={this.handleNestedListToggle} nestedItems={[ } />, ]} - /> + />, ]} /> From 30287d5dabbd1e1cd76cf2a1da043c7697e48a31 Mon Sep 17 00:00:00 2001 From: David Madner Date: Sun, 31 Jul 2016 14:13:24 +0200 Subject: [PATCH 3/4] adding tests, consider open prop when mounting --- .../pages/components/List/ExampleNested.js | 1 + src/List/ListItem.js | 11 +++--- src/List/ListItem.spec.js | 39 +++++++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/docs/src/app/components/pages/components/List/ExampleNested.js b/docs/src/app/components/pages/components/List/ExampleNested.js index 539aef945c8f9d..4f4514918b73c3 100644 --- a/docs/src/app/components/pages/components/List/ExampleNested.js +++ b/docs/src/app/components/pages/components/List/ExampleNested.js @@ -64,6 +64,7 @@ export default class ListExampleNested extends React.Component { } open={this.state.open} onNestedListToggle={this.handleNestedListToggle} diff --git a/src/List/ListItem.js b/src/List/ListItem.js index de08874b29f66c..8d849f8441605e 100644 --- a/src/List/ListItem.js +++ b/src/List/ListItem.js @@ -286,6 +286,7 @@ class ListItem extends Component { onMouseLeave: () => {}, onNestedListToggle: () => {}, onTouchStart: () => {}, + open: null, primaryTogglesNestedList: false, secondaryTextLines: 1, }; @@ -304,15 +305,15 @@ class ListItem extends Component { }; componentWillMount() { - if (this.props.initiallyOpen) { - this.setState({open: true}); - } + this.setState({ + open: this.props.open === null ? this.props.initiallyOpen === true : this.props.open, + }); } componentWillReceiveProps(nextProps) { - if (this.props.open !== nextProps.open) { + // update the state when the component is controlled. + if (nextProps.open !== null) this.setState({open: nextProps.open}); - } } shouldComponentUpdate(nextProps, nextState, nextContext) { diff --git a/src/List/ListItem.spec.js b/src/List/ListItem.spec.js index 0d79ccfcbe6e04..938011e1d55f4e 100644 --- a/src/List/ListItem.spec.js +++ b/src/List/ListItem.spec.js @@ -73,4 +73,43 @@ describe('', () => { assert.ok(wrapper.find('.test-checkbox').length); assert.strictEqual(wrapper.find(`.${testClass}`).length, 1, 'should have a div with the test class'); }); + + it('should initially open nested list', () => { + const testClass = 'test-class'; + const wrapper = shallowWithContext( + , + ]} + /> + ); + + assert.ok(wrapper.find('NestedList').length); + assert.ok(wrapper.find('.test-class').parent().children().nodes[1].props.open === true); + }); + + it('should toggle nested list', () => { + const testClass = 'test-class'; + const wrapper = shallowWithContext( + , + ]} + /> + ); + + assert.ok(wrapper.find('.test-class').parent().children().nodes[1].props.open === false); + wrapper.setProps({ + open: true, + }); + assert.ok(wrapper.find('.test-class').parent().children().nodes[1].props.open === true); + }); }); From 6052ee369b7b58ea5c01b7303b6432fb9ed0d236 Mon Sep 17 00:00:00 2001 From: David Madner Date: Sun, 31 Jul 2016 14:52:36 +0200 Subject: [PATCH 4/4] remove unneeded className attribute --- docs/src/app/components/pages/components/List/ExampleNested.js | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/app/components/pages/components/List/ExampleNested.js b/docs/src/app/components/pages/components/List/ExampleNested.js index 4f4514918b73c3..539aef945c8f9d 100644 --- a/docs/src/app/components/pages/components/List/ExampleNested.js +++ b/docs/src/app/components/pages/components/List/ExampleNested.js @@ -64,7 +64,6 @@ export default class ListExampleNested extends React.Component { } open={this.state.open} onNestedListToggle={this.handleNestedListToggle}