@@ -22,6 +22,16 @@ type Props = {
22
22
* Callback which returns a React element to display on the left side.
23
23
*/
24
24
left ?: ( props : { color : string } ) => React . Node ,
25
+ /**
26
+ * Whether the accordion is expanded
27
+ * If this prop is provided, the accordion will behave as a "controlled component".
28
+ * You'll need to update this prop when you want to toggle the component or on `onPress`.
29
+ */
30
+ expanded ?: boolean ,
31
+ /**
32
+ * Function to execute on press.
33
+ */
34
+ onPress ?: ( ) => mixed ,
25
35
/**
26
36
* Content of the section.
27
37
*/
@@ -51,15 +61,40 @@ type State = {
51
61
* import * as React from 'react';
52
62
* import { List, Checkbox } from 'react-native-paper';
53
63
*
54
- * const MyComponent = () => (
55
- * <List.Accordion
56
- * title="Accordion"
57
- * left={props => <List.Icon {...props} icon="folder" />}
58
- * >
59
- * <List.Item title="First item" />
60
- * <List.Item title="Second item" />
61
- * </List.Accordion>
62
- * );
64
+ * class MyComponent extends React.Component {
65
+ * state = {
66
+ * expanded: true
67
+ * }
68
+ *
69
+ * _handlePress = () =>
70
+ * this.setState({
71
+ * expanded: !this.state.expanded
72
+ * });
73
+ *
74
+ * render() {
75
+ * return (
76
+ * <List.Section title="Accordions">
77
+ * <List.Accordion
78
+ * title="Uncontrolled Accordion"
79
+ * left={props => <List.Icon {...props} icon="folder" />}
80
+ * >
81
+ * <List.Item title="First item" />
82
+ * <List.Item title="Second item" />
83
+ * </List.Accordion>
84
+ *
85
+ * <List.Accordion
86
+ * title="Controlled Accordion"
87
+ * left={props => <List.Icon {...props} icon="folder" />}
88
+ * expanded={this.state.expanded}
89
+ * onPress={this._handlePress}
90
+ * >
91
+ * <List.Item title="First item" />
92
+ * <List.Item title="Second item" />
93
+ * </List.Accordion>
94
+ * </List.Section>
95
+ * );
96
+ * }
97
+ * }
63
98
*
64
99
* export default MyComponent;
65
100
* ```
@@ -68,13 +103,20 @@ class ListAccordion extends React.Component<Props, State> {
68
103
static displayName = 'List.Accordion' ;
69
104
70
105
state = {
71
- expanded : false ,
106
+ expanded : this . props . expanded || false ,
72
107
} ;
73
108
74
- _handlePress = ( ) =>
75
- this . setState ( state => ( {
76
- expanded : ! state . expanded ,
77
- } ) ) ;
109
+ _handlePress = ( ) => {
110
+ this . props . onPress && this . props . onPress ( ) ;
111
+
112
+ if ( this . props . expanded === undefined ) {
113
+ // Only update state of the `expanded` prop was not passed
114
+ // If it was passed, the component will act as a controlled component
115
+ this . setState ( state => ( {
116
+ expanded : ! state . expanded ,
117
+ } ) ) ;
118
+ }
119
+ } ;
78
120
79
121
render ( ) {
80
122
const { left , title, description, children, theme, style } = this . props ;
@@ -87,6 +129,11 @@ class ListAccordion extends React.Component<Props, State> {
87
129
. rgb ( )
88
130
. string ( ) ;
89
131
132
+ const expanded =
133
+ this . props . expanded !== undefined
134
+ ? this . props . expanded
135
+ : this . state . expanded ;
136
+
90
137
return (
91
138
< View >
92
139
< TouchableRipple
@@ -99,9 +146,7 @@ class ListAccordion extends React.Component<Props, State> {
99
146
< View style = { styles . row } pointerEvents = "none" >
100
147
{ left
101
148
? left ( {
102
- color : this . state . expanded
103
- ? theme . colors . primary
104
- : descriptionColor ,
149
+ color : expanded ? theme . colors . primary : descriptionColor ,
105
150
} )
106
151
: null }
107
152
< View style = { [ styles . item , styles . content ] } >
@@ -110,9 +155,7 @@ class ListAccordion extends React.Component<Props, State> {
110
155
style = { [
111
156
styles . title ,
112
157
{
113
- color : this . state . expanded
114
- ? theme . colors . primary
115
- : titleColor ,
158
+ color : expanded ? theme . colors . primary : titleColor ,
116
159
} ,
117
160
] }
118
161
>
@@ -134,18 +177,14 @@ class ListAccordion extends React.Component<Props, State> {
134
177
</ View >
135
178
< View style = { [ styles . item , description && styles . multiline ] } >
136
179
< Icon
137
- source = {
138
- this . state . expanded
139
- ? 'keyboard-arrow-up'
140
- : 'keyboard-arrow-down'
141
- }
180
+ source = { expanded ? 'keyboard-arrow-up' : 'keyboard-arrow-down' }
142
181
color = { titleColor }
143
182
size = { 24 }
144
183
/>
145
184
</ View >
146
185
</ View >
147
186
</ TouchableRipple >
148
- { this . state . expanded
187
+ { expanded
149
188
? React . Children . map ( children , child => {
150
189
if (
151
190
left &&
0 commit comments