forked from oblador/react-native-collapsible
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAccordion.js
125 lines (110 loc) · 3.58 KB
/
Accordion.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { View, TouchableHighlight } from 'react-native';
import Collapsible from './Collapsible';
import { ViewPropTypes } from './config';
const COLLAPSIBLE_PROPS = Object.keys(Collapsible.propTypes);
const VIEW_PROPS = Object.keys(ViewPropTypes);
export default class Accordion extends Component {
static propTypes = {
sections: PropTypes.array.isRequired,
renderHeader: PropTypes.func.isRequired,
renderContent: PropTypes.func.isRequired,
renderSectionTitle: PropTypes.func,
activeSections: PropTypes.arrayOf(PropTypes.number).isRequired,
onChange: PropTypes.func.isRequired,
align: PropTypes.oneOf(['top', 'center', 'bottom']),
duration: PropTypes.number,
easing: PropTypes.string,
underlayColor: PropTypes.string,
touchableComponent: PropTypes.func,
touchableProps: PropTypes.object,
disabled: PropTypes.bool,
expandFromBottom: PropTypes.bool,
expandMultiple: PropTypes.bool,
onAnimationEnd: PropTypes.func,
sectionContainerStyle: ViewPropTypes.style,
containerStyle: ViewPropTypes.style,
};
static defaultProps = {
underlayColor: 'black',
disabled: false,
expandFromBottom: false,
expandMultiple: false,
touchableComponent: TouchableHighlight,
renderSectionTitle: () => null,
onAnimationEnd: () => null,
sectionContainerStyle: {},
};
_toggleSection(section) {
if (!this.props.disabled) {
const { activeSections, expandMultiple, onChange } = this.props;
let updatedSections = [];
if (activeSections.includes(section)) {
updatedSections = activeSections.filter(a => a !== section);
} else if (expandMultiple) {
updatedSections = [...activeSections, section];
} else {
updatedSections = [section];
}
onChange && onChange(updatedSections);
}
}
render() {
let viewProps = {};
let collapsibleProps = {};
Object.keys(this.props).forEach(key => {
if (COLLAPSIBLE_PROPS.includes(key)) {
collapsibleProps[key] = this.props[key];
} else if (VIEW_PROPS.includes(key)) {
viewProps[key] = this.props[key];
}
});
const {
activeSections,
containerStyle,
sectionContainerStyle,
expandFromBottom,
sections,
underlayColor,
touchableProps,
touchableComponent: Touchable,
onAnimationEnd,
renderContent,
renderHeader,
renderSectionTitle,
} = this.props;
const renderCollapsible = (section, key) => (
<Collapsible
collapsed={!activeSections.includes(key)}
{...collapsibleProps}
onAnimationEnd={() => onAnimationEnd(section, key)}
>
{renderContent(section, key, activeSections.includes(key), sections)}
</Collapsible>
);
return (
<View style={containerStyle} {...viewProps}>
{sections.map((section, key) => (
<View key={key} style={sectionContainerStyle}>
{renderSectionTitle(section, key, activeSections.includes(key))}
{expandFromBottom && renderCollapsible(section, key)}
<Touchable
onPress={() => this._toggleSection(key)}
underlayColor={underlayColor}
{...touchableProps}
>
{renderHeader(
section,
key,
activeSections.includes(key),
sections
)}
</Touchable>
{!expandFromBottom && renderCollapsible(section, key)}
</View>
))}
</View>
);
}
}