diff --git a/src/js/slider.jsx b/src/js/slider.jsx index 67e73a5e97d12e..5f21d41b971fa3 100644 --- a/src/js/slider.jsx +++ b/src/js/slider.jsx @@ -1 +1,175 @@ -/** * @jsx React.DOM */ var React = require('react'), Paper = require('./paper.jsx'), Classable = require('./mixins/classable.js'), Draggable = require('react-draggable2'); var Slider = React.createClass({ propTypes: { required: React.PropTypes.bool, disabled: React.PropTypes.bool, min: React.PropTypes.number, max: React.PropTypes.number, step: React.PropTypes.number, error: React.PropTypes.string, description: React.PropTypes.string, name: React.PropTypes.string.isRequired, onChange: React.PropTypes.func }, mixins: [Classable], getDefaultProps: function() { return { required: true, disabled: false, defaultValue: 0, min: 0, max: 1, dragging: false }; }, getInitialState: function() { var value = this.props.value; if (value == null) value = this.props.defaultValue; var percent = value / this.props.max; if (isNaN(percent)) percent = 0; return { value: value, percent: percent } }, componentWillReceiveProps: function(nextProps) { if (nextProps.value != null) { this.setValue(nextProps.value); } }, render: function() { var classes = this.getClasses('mui-input', { 'mui-error': this.props.error != null }); var sliderClasses = this.getClasses('mui-slider', { 'mui-slider-zero': this.state.percent == 0, 'mui-disabled': this.props.disabled }); var percent = this.state.percent; if (percent > 1) percent = 1; else if (percent < 0) percent = 0; return (
{this.props.description} {this.props.error}
); }, getValue: function() { return this.state.value; }, setValue: function(i) { // calculate percentage var percent = (i - this.props.min) / (this.props.max - this.props.min); if (isNaN(percent)) percent = 0; // update state this.setState({ value: i, percent: percent }); }, getPercent: function() { return this.state.percent; }, setPercent: function (percent) { var value = percent * (this.props.max - this.props.min) + this.props.min; this.setState({value: value, percent: percent}); }, clearValue: function() { this.setValue(0); }, _onClick: function (e) { // let draggable handle the slider if (this.state.dragging || this.props.disabled) return; var node = this.refs.track.getDOMNode(); var boundingClientRect = node.getBoundingClientRect(); var offset = e.clientX - boundingClientRect.left; var percent = offset / node.clientWidth; this.setPercent(percent); }, _onDragStart: function(e, ui) { this.setState({ dragging: true }); }, _onDragStop: function(e, ui) { this.setState({ dragging: false }); }, _onDragUpdate: function(e, ui) { if (!this.state.dragging) return; var value = this.state.value; if (!this.props.disabled) this._dragX(ui.position.left); if (this.state.value != value && this.props.onChange) { this.props.onChange(e, this.state.value); } }, _dragX: function(pos) { var max = this.refs.track.getDOMNode().clientWidth; if (pos < 0) pos = 0; else if (pos > max) pos = max; this.setPercent(pos / max); } }); module.exports = Slider; \ No newline at end of file + +var React = require('react'), + Paper = require('./paper.jsx'), + Classable = require('./mixins/classable.js'), + Draggable = require('react-draggable2'); + +var Slider = React.createClass({ + + propTypes: { + required: React.PropTypes.bool, + disabled: React.PropTypes.bool, + min: React.PropTypes.number, + max: React.PropTypes.number, + step: React.PropTypes.number, + error: React.PropTypes.string, + description: React.PropTypes.string, + name: React.PropTypes.string.isRequired, + onChange: React.PropTypes.func + }, + + mixins: [Classable], + + getDefaultProps: function() { + return { + required: true, + disabled: false, + defaultValue: 0, + min: 0, + max: 1, + dragging: false + }; + }, + + getInitialState: function() { + var value = this.props.value; + if (value == null) value = this.props.defaultValue; + var percent = value / this.props.max; + if (isNaN(percent)) percent = 0; + return { + value: value, + percent: percent + } + }, + + componentWillReceiveProps: function(nextProps) { + if (nextProps.value != null) { + this.setValue(nextProps.value); + } + }, + + render: function() { + var classes = this.getClasses('mui-input', { + 'mui-error': this.props.error != null + }); + + var sliderClasses = this.getClasses('mui-slider', { + 'mui-slider-zero': this.state.percent == 0, + 'mui-disabled': this.props.disabled + }); + + var percent = this.state.percent; + if (percent > 1) percent = 1; else if (percent < 0) percent = 0; + + return ( +
+ + + {this.props.description} + {this.props.error} +
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+ ); + }, + + getValue: function() { + return this.state.value; + }, + + setValue: function(i) { + // calculate percentage + var percent = (i - this.props.min) / (this.props.max - this.props.min); + if (isNaN(percent)) percent = 0; + // update state + this.setState({ + value: i, + percent: percent + }); + }, + + getPercent: function() { + return this.state.percent; + }, + + setPercent: function (percent) { + var value = this._percentToValue(percent); + this.setState({value: value, percent: percent}); + }, + + clearValue: function() { + this.setValue(0); + }, + + _onClick: function (e) { + // let draggable handle the slider + if (this.state.dragging || this.props.disabled) return; + var value = this.state.value; + var node = this.refs.track.getDOMNode(); + var boundingClientRect = node.getBoundingClientRect(); + var offset = e.clientX - boundingClientRect.left; + this._updateWithChangeEvent(e, offset / node.clientWidth); + }, + + _onDragStart: function(e, ui) { + this.setState({ + dragging: true + }); + }, + + _onDragStop: function(e, ui) { + this.setState({ + dragging: false + }); + }, + + _onDragUpdate: function(e, ui) { + if (!this.state.dragging) return; + if (!this.props.disabled) this._dragX(e, ui.position.left); + }, + + _dragX: function(e, pos) { + var max = this.refs.track.getDOMNode().clientWidth; + if (pos < 0) pos = 0; else if (pos > max) pos = max; + this._updateWithChangeEvent(e, pos / max); + }, + + _updateWithChangeEvent: function(e, percent) { + if (this.state.percent === percent) return; + this.setPercent(percent); + var value = this._percentToValue(percent); + if (this.props.onChange) this.props.onChange(e, value); + }, + + _percentToValue: function(percent) { + return percent * (this.props.max - this.props.min) + this.props.min; + } + +}); + +module.exports = Slider;