-
Notifications
You must be signed in to change notification settings - Fork 0
/
Sidebar.jsx
115 lines (101 loc) · 3.27 KB
/
Sidebar.jsx
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
import React from 'react/addons';
const {LinkedStateMixin} = React.addons;
const Sidebar = React.createClass({
mixins: [LinkedStateMixin],
propTypes: {
items: React.PropTypes.arrayOf(React.PropTypes.shape({
id: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
]).isRequired,
title: React.PropTypes.string.isRequired,
subtitle: React.PropTypes.string.isRequired,
icon: React.PropTypes.string,
iconBackground: React.PropTypes.string,
indicator: React.PropTypes.number,
})).isRequired,
selectedId: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
]),
onChange: React.PropTypes.func,
},
getDefaultProps() {
return {
onChange: () => {},
};
},
getInitialState() {
return {
search: '',
};
},
filterItemForSearch(search, item) {
if (!item.title) {
console.log('item without title');
return false;
}
if (search.length === 0 && search[0] === '') {
return true;
}
return search.every(word => (item.title.toLowerCase().indexOf(word) > -1) || (item.subtitle.toLowerCase().indexOf(word) > -1));
},
onMouseEnter(e) {
let {target} = e;
while (target.className.indexOf('list-group-item') === -1) {
target = target.parentElement;
if (!target) return;
}
target.className += ' hover';
},
onMouseLeave(e) {
let {target} = e;
while (target.className.indexOf('list-group-item') === -1) {
target = target.parentElement;
if (!target) return;
}
target.className = target.className.replace(/\shover/g, '');
},
render() {
const search = this.state.search.toLowerCase().split(' ');
return (
<div className="pane pane-one-fourth sidebar">
<ul className="list-group">
<li className="list-group-header">
<input className="form-control" type="text" placeholder="Search for someone" valueLink={this.linkState('search')} />
</li>
{this.props.items.filter(this.filterItemForSearch.bind(null, search)).map(this.renderItem)}
</ul>
</div>
);
},
renderItem(item) {
const iconStyle = {
width: 32, height: 32, textAlign: 'center', fontSize: 16, borderRadius: '50%', lineHeight: '32px', fontWeight: '600',
background: item.iconBackground || '#ccc',
};
const indicatorStyle = {
width: 20, height: 20, textAlign: 'center', fontSize: 10, borderRadius: '50%', lineHeight: '20px',
margin: '8px 0 0',
background: item.indicator ? '#ccc' : 'transparent',
};
let className = 'list-group-item';
if (this.props.selectedId === item.id) {
className += ' selected';
}
return (
<li className={className} key={item.id}
onClick={() => this.props.onChange(item)}
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}>
<span className="img-circle media-object pull-left" style={iconStyle}>{item.icon}</span>
<span className="img-circle media-object pull-right" style={indicatorStyle}>{item.indicator}</span>
<div className="media-body">
<strong>{item.title}</strong>
<p>{item.subtitle}</p>
</div>
</li>
);
},
});
export default Sidebar;