forked from diogofcunha/react-virtualized-tree
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FilteringContainer.js
101 lines (83 loc) · 2.69 KB
/
FilteringContainer.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
import React from 'react';
import PropTypes from 'prop-types';
import { debounce } from 'lodash';
import classNames from 'classnames';
import DefaultGroupRenderer from './filtering/DefaultGroupRenderer';
import { Node } from './shapes/nodeShapes';
import { filterNodes } from './selectors/filtering';
const nameMatchesSearchTerm = (searchTerm) => ({ name }) => {
const upperCaseName = name.toUpperCase();
const upperCaseSearchTerm = searchTerm.toUpperCase();
return upperCaseName.indexOf(upperCaseSearchTerm.trim()) > -1
}
export default class FilteringContainer extends React.Component {
state = {
filterText: '',
filterTerm: ''
}
getChildContext = () => {
return { unfilteredNodes: this.props.nodes };
}
static childContextTypes = {
unfilteredNodes: PropTypes.arrayOf(PropTypes.shape(Node)).isRequired
}
static defaultProps = {
debouncer: debounce,
groupRenderer: DefaultGroupRenderer
}
constructor(props) {
super(props);
this.setFilterTerm = props.debouncer(this.setFilterTerm, 300);
}
setFilterTerm() {
this.setState(ps => ({ filterTerm: ps.filterText }));
}
handleFilterTextChange = e => {
const filterText = e.target.value;
this.setState({ filterText });
this.setFilterTerm();
}
render() {
const { filterTerm, filterText } = this.state;
const {
nodes,
children: treeRenderer,
groups,
selectedGroup,
groupRenderer: GroupRenderer,
onSelectedGroupChange } = this.props;
const relevantNodes = groups && selectedGroup && groups[selectedGroup] ?
filterNodes(groups[selectedGroup].filter, nodes) :
{ nodes, nodeParentMappings: [] };
const { nodes: filteredNodes, nodeParentMappings } = filterTerm ?
filterNodes(nameMatchesSearchTerm(filterTerm), relevantNodes.nodes) :
relevantNodes;
return (
<div className="tree-filter-container">
<div className={classNames('tree-lookup-input', { group: !!groups })}>
<input
value={filterText}
onChange={this.handleFilterTextChange}
placeholder="Search..."/>
<i aria-hidden="true" className="mi mi-11 mi-search"></i>
{ groups &&
<GroupRenderer
groups={groups}
selectedGroup={selectedGroup}
onChange={onSelectedGroupChange}
/>
}
</div>
{ treeRenderer({ nodes: filteredNodes, nodeParentMappings }) }
</div>
)
}
}
FilteringContainer.propTypes = {
children: PropTypes.func.isRequired,
debouncer: PropTypes.func,
groups: PropTypes.object,
selectedGroup: PropTypes.string,
groupRenderer: PropTypes.func,
onSelectedGroupChange: PropTypes.func
}