forked from atom/github
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaccordion.js
107 lines (94 loc) · 2.68 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
import React, {Fragment} from 'react';
import PropTypes from 'prop-types';
import {autobind} from '../helpers';
export default class Accordion extends React.Component {
static propTypes = {
leftTitle: PropTypes.string.isRequired,
rightTitle: PropTypes.string,
results: PropTypes.arrayOf(PropTypes.any).isRequired,
total: PropTypes.number.isRequired,
isLoading: PropTypes.bool.isRequired,
loadingComponent: PropTypes.func,
emptyComponent: PropTypes.func,
moreComponent: PropTypes.func,
reviewsButton: PropTypes.func,
onClickItem: PropTypes.func,
children: PropTypes.func.isRequired,
};
static defaultProps = {
loadingComponent: () => null,
emptyComponent: () => null,
moreComponent: () => null,
onClickItem: () => {},
reviewsButton: () => null,
};
constructor(props) {
super(props);
autobind(this, 'toggle');
this.state = {
expanded: true,
};
}
render() {
return (
<details className="github-Accordion" open={this.state.expanded}>
<summary className="github-Accordion-header" onClick={this.toggle}>
{this.renderHeader()}
</summary>
<main className="github-Accordion-content">
{this.renderContent()}
</main>
</details>
);
}
renderHeader() {
return (
<Fragment>
<span className="github-Accordion--leftTitle">
{this.props.leftTitle}
</span>
{this.props.rightTitle && (
<span className="github-Accordion--rightTitle">
{this.props.rightTitle}
</span>
)}
{this.props.reviewsButton()}
</Fragment>
);
}
renderContent() {
if (this.props.isLoading) {
const Loading = this.props.loadingComponent;
return <Loading />;
}
if (this.props.results.length === 0) {
const Empty = this.props.emptyComponent;
return <Empty />;
}
if (!this.state.expanded) {
return null;
}
const More = this.props.moreComponent;
return (
<Fragment>
<ul className="github-Accordion-list">
{this.props.results.map((item, index) => {
const key = item.key !== undefined ? item.key : index;
return (
<li className="github-Accordion-listItem" key={key} onClick={() => this.props.onClickItem(item)}>
{this.props.children(item)}
</li>
);
})}
</ul>
{this.props.results.length < this.props.total && <More />}
</Fragment>
);
}
toggle(e) {
e.preventDefault();
return new Promise(resolve => {
this.setState(prevState => ({expanded: !prevState.expanded}), resolve);
});
}
}