diff --git a/example/src/ListAccordionExample.js b/example/src/ListAccordionExample.js index 57abfb1..73e8a01 100644 --- a/example/src/ListAccordionExample.js +++ b/example/src/ListAccordionExample.js @@ -9,15 +9,28 @@ type Props = { theme: Theme, }; -class ListAccordionExample extends React.Component { +type State = { + expanded: boolean, +}; + +class ListAccordionExample extends React.Component { static title = 'List.Accordion'; + state = { + expanded: true, + }; + + _handlePress = () => { + this.setState({ expanded: !this.state.expanded }); + }; + render() { const { theme: { colors: { background }, }, } = this.props; + return ( @@ -28,6 +41,14 @@ class ListAccordionExample extends React.Component { + } + title="Start expanded" + expanded={this.state.expanded} + onPress={this._handlePress} + > + + diff --git a/src/components/List/ListAccordion.js b/src/components/List/ListAccordion.js index 5359634..788d4b2 100644 --- a/src/components/List/ListAccordion.js +++ b/src/components/List/ListAccordion.js @@ -22,6 +22,16 @@ type Props = { * Callback which returns a React element to display on the left side. */ left?: (props: { color: string }) => React.Node, + /** + * Whether the accordion is expanded + * If this prop is provided, the accordion will behave as a "controlled component". + * You'll need to update this prop when you want to toggle the component or on `onPress`. + */ + expanded?: boolean, + /** + * Function to execute on press. + */ + onPress?: () => mixed, /** * Content of the section. */ @@ -51,15 +61,40 @@ type State = { * import * as React from 'react'; * import { List, Checkbox } from 'react-native-paper'; * - * const MyComponent = () => ( - * } - * > - * - * - * - * ); + * class MyComponent extends React.Component { + * state = { + * expanded: true + * } + * + * _handlePress = () => + * this.setState({ + * expanded: !this.state.expanded + * }); + * + * render() { + * return ( + * + * } + * > + * + * + * + * + * } + * expanded={this.state.expanded} + * onPress={this._handlePress} + * > + * + * + * + * + * ); + * } + * } * * export default MyComponent; * ``` @@ -68,13 +103,20 @@ class ListAccordion extends React.Component { static displayName = 'List.Accordion'; state = { - expanded: false, + expanded: this.props.expanded || false, }; - _handlePress = () => - this.setState(state => ({ - expanded: !state.expanded, - })); + _handlePress = () => { + this.props.onPress && this.props.onPress(); + + if (this.props.expanded === undefined) { + // Only update state of the `expanded` prop was not passed + // If it was passed, the component will act as a controlled component + this.setState(state => ({ + expanded: !state.expanded, + })); + } + }; render() { const { left, title, description, children, theme, style } = this.props; @@ -87,6 +129,11 @@ class ListAccordion extends React.Component { .rgb() .string(); + const expanded = + this.props.expanded !== undefined + ? this.props.expanded + : this.state.expanded; + return ( { {left ? left({ - color: this.state.expanded - ? theme.colors.primary - : descriptionColor, + color: expanded ? theme.colors.primary : descriptionColor, }) : null} @@ -110,9 +155,7 @@ class ListAccordion extends React.Component { style={[ styles.title, { - color: this.state.expanded - ? theme.colors.primary - : titleColor, + color: expanded ? theme.colors.primary : titleColor, }, ]} > @@ -134,18 +177,14 @@ class ListAccordion extends React.Component { - {this.state.expanded + {expanded ? React.Children.map(children, child => { if ( left && diff --git a/src/components/__tests__/ListAccordion.test.js b/src/components/__tests__/ListAccordion.test.js index 62d877c..0906812 100644 --- a/src/components/__tests__/ListAccordion.test.js +++ b/src/components/__tests__/ListAccordion.test.js @@ -53,3 +53,15 @@ it('renders list accordion with left items', () => { expect(tree).toMatchSnapshot(); }); + +it('renders expanded accordion', () => { + const tree = renderer + .create( + + + + ) + .toJSON(); + + expect(tree).toMatchSnapshot(); +}); diff --git a/src/components/__tests__/__snapshots__/ListAccordion.test.js.snap b/src/components/__tests__/__snapshots__/ListAccordion.test.js.snap index 8a633c5..d6cdb82 100644 --- a/src/components/__tests__/__snapshots__/ListAccordion.test.js.snap +++ b/src/components/__tests__/__snapshots__/ListAccordion.test.js.snap @@ -1,5 +1,240 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`renders expanded accordion 1`] = ` + + + + + + Accordion item 1 + + + + +  + + + + + + + + + List item 1 + + + + + +`; + exports[`renders list accordion with children 1`] = ` any; left?: (props: { color: string }) => React.ReactNode; children: React.ReactNode; theme?: ThemeShape;