-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathLegend.jsx
More file actions
123 lines (91 loc) · 3.19 KB
/
Legend.jsx
File metadata and controls
123 lines (91 loc) · 3.19 KB
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
import React, { PropTypes } from 'react';
import { PanoramaDispatcher, PanoramaEventTypes } from '../PanoramaDispatcher.js';
import './style.scss';
export default class Legend extends React.Component {
static propTypes = {
/**
* @type {Array[String]}
* List of items (Strings) to display.
*/
items: PropTypes.array.isRequired,
/**
* @type {String}
* Currently selected item.
* Either the string value of the item (as displayed on-screen) or the index of the item within the `items` array.
*/
selectedItem: PropTypes.string,
/**
* @type {Function}
* Callback invoked on selection of an item, e.g. a mouse click.
*/
onItemSelected: PropTypes.func
}
static defaultProps = {
items: [],
selectedItem: '',
onItemSelected: null
}
constructor (props) {
super(props);
// manually bind event handlers,
// since React ES6 doesn't do this automatically
this.onItemClick = this.onItemClick.bind(this);
this.onItemEnter = this.onItemEnter.bind(this);
this.onItemLeave = this.onItemLeave.bind(this);
}
componentDidMount () {}
componentWillUnmount () {}
componentDidUpdate () {}
onItemClick (event) {
// Defense.
if (!event.currentTarget || !event.currentTarget.dataset) { return; }
// Direct communication: call callback if it was passed in.
if (this.props.onItemSelected) {
this.props.onItemSelected(event.currentTarget.dataset.item, this.props.items.indexOf(event.currentTarget.dataset.item));
}
// Indirect communication: Notify any subscribers of item selection.
PanoramaDispatcher.Legend.selected(event.currentTarget.dataset.item, this.props.items.indexOf(event.currentTarget.dataset.item));
}
onItemEnter (event) {
// Defense.
if (!event.currentTarget || !event.currentTarget.dataset) { return; }
// Direct communication: call callback if it was passed in.
if (this.props.onItemEnter) {
this.props.onItemEnter(event.currentTarget.dataset.item, this.props.items.indexOf(event.currentTarget.dataset.item));
}
}
onItemLeave (event) {
// Defense.
if (!event.currentTarget || !event.currentTarget.dataset) { return; }
// Direct communication: call callback if it was passed in.
if (this.props.onItemLeave) {
this.props.onItemLeave(event.currentTarget.dataset.item, this.props.items.indexOf(event.currentTarget.dataset.item));
}
}
render () {
return (
<div className={ 'panorama legend ' + this.props.className }>
<ul>
{ this.props.items.map((item, i) => {
let selected = this.props.selectedItem === item || this.props.selectedItem == i;
return (
<li
className = { 'item' + (selected ? ' selected' : '') }
data-item = { item }
key = { item }
onClick = { this.onItemClick }
onMouseEnter = { this.onItemEnter }
onMouseLeave = { this.onItemLeave }
>
<span>{ this.capitalize(item) }</span>
</li>
);
}) }
</ul>
</div>
);
}
capitalize (str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
}