piano/js/components/UI/Selector.js

96 lines
2.6 KiB
JavaScript

/*globals jQuery, React, App */
(function ($) {
'use strict';
/**
* Display a value that can be changed on click
*
* @prop {values: array} List of values
* @prop {value: number} Current value
* @prop {onChange: function} Called whenever value changes
*/
App.components.create('UI', {
displayName: 'Selector',
mixins: [React.addons.PureRenderMixin],
propTypes: {
values: React.PropTypes.array.isRequired,
value: React.PropTypes.number,
onChange: React.PropTypes.func
},
getDefaultProps: function () {
return {
value: null,
onChange: function () {}
};
},
getInitialState: function () {
return {
value: null,
index: null
};
},
componentDidMount: function () {
if (this.props.value === null) {
this.setState({
value: this.props.values[0],
index: 0
});
} else {
this.setState({
value: this.props.value,
index: this.props.values.indexOf(this.props.value)
});
}
},
componentWillReceiveProps: function (nextProps) {
if (nextProps.value !== this.state.value) {
this.setState({
value: nextProps.value,
index: nextProps.values.indexOf(nextProps.value)
});
}
},
/**
* Change value on click
*/
click: function () {
var values = this.props.values,
index = this.state.index;
if (index + 1 < values.length) {
index += 1;
} else {
index = 0;
}
this.setState({
value: values[index],
index: index
}, function () {
this.props.onChange(values[index]);
}.bind(this));
},
/**
* Render handle
*/
render: function () {
var props = $.extend({}, this.props);
delete props.value;
delete props.index;
props.onClick = this.click;
props.className = 'selector ' +
((props.className) ? props.className : '');
return React.DOM.button(props, this.state.value);
}
});
}(jQuery));