material-ui
Version:
Material Design UI components built with React
1 lines • 4.74 kB
JSX
/**
* @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 (
<div className={classes}>
<span className="mui-input-highlight"></span>
<span className="mui-input-bar"></span>
<span className="mui-input-description">{this.props.description}</span>
<span className="mui-input-error">{this.props.error}</span>
<div className={sliderClasses} onClick={this._onClick}>
<div ref="track" className="mui-slider-track">
<Draggable axis="x" bound="point"
cancel={this.props.disabled ? '*' : null}
start={{x: (percent * 100) + '%'}}
onStart={this._onDragStart}
onStop={this._onDragStop}
onDrag={this._onDragUpdate}>
<div className="mui-slider-handle" tabIndex={0}></div>
</Draggable>
<div className="mui-slider-selection mui-slider-selection-low"
style={{width: (percent * 100) + '%'}}>
<div className="mui-slider-selection-fill"></div>
</div>
<div className="mui-slider-selection mui-slider-selection-high"
style={{width: ((1 - percent) * 100) + '%'}}>
<div className="mui-slider-selection-fill"></div>
</div>
</div>
</div>
<input ref="input" type="hidden"
name={this.props.name}
value={this.state.value}
required={this.props.required}
min={this.props.min}
max={this.props.max}
step={this.props.step} />
</div>
);
},
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;