Skip to content

Commit

Permalink
Merge pull request mui#1825 from igorbt/slider-fix
Browse files Browse the repository at this point in the history
[Slider] removed react-draggable dependency (fixes IE!)
  • Loading branch information
shaurya947 committed Oct 15, 2015
2 parents fa4a019 + 1bf46f4 commit 1e0a4a5
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 53 deletions.
8 changes: 4 additions & 4 deletions docs/src/app/components/pages/components/sliders.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,15 @@ class SlidersPage extends React.Component {
},
{
name: 'onDragStart',
type: 'function(e, ui)',
type: 'function(e)',
header: 'optional',
desc: 'Callback function that is fired when the slider has begun to move. ui contains the position information.'
desc: 'Callback function that is fired when the slider has begun to move.'
},
{
name: 'onDragStop',
type: 'function(e, ui)',
type: 'function(e)',
header: 'optional',
desc: 'Callback function that is fried when teh slide has stopped moving. ui contains the position information.'
desc: 'Callback function that is fried when teh slide has stopped moving.'
},
{
name: 'onFocus',
Expand Down
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@
"url": "https://github.com/callemall/material-ui/issues"
},
"homepage": "http://material-ui.com/",
"dependencies": {
"react-draggable2": "^0.7.0-alpha1"
},
"peerDependencies": {
"react": "^0.14.0",
"react-dom": "^0.14.0",
Expand Down
140 changes: 94 additions & 46 deletions src/slider.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const React = require('react');
const ReactDOM = require('react-dom');
const StylePropable = require('./mixins/style-propable');
const Draggable = require('react-draggable2');
const Transitions = require('./styles/transitions');
const FocusRipple = require('./ripples/focus-ripple');
const DefaultRawTheme = require('./styles/raw-themes/light-raw-theme');
Expand Down Expand Up @@ -155,7 +154,7 @@ const Slider = React.createClass({
position: 'absolute',
cursor: 'pointer',
pointerEvents: 'inherit',
top: ((this.getTheme().handleSizeActive - this.getTheme().trackSize) / 2) + 'px',
top: 0,
left: '0%',
zIndex: 1,
margin: (this.getTheme().trackSize / 2) + 'px 0 0 0',
Expand Down Expand Up @@ -252,7 +251,10 @@ const Slider = React.createClass({
styles.handle,
this.state.active && styles.handleWhenActive,
this.state.focused && {outline: 'none'},
this.props.disabled && styles.handleWhenDisabled
this.props.disabled && styles.handleWhenDisabled,
{
left: (percent * 100) + '%',
}
);
let rippleStyle = this.mergeAndPrefix(
styles.ripple,
Expand All @@ -277,6 +279,16 @@ const Slider = React.createClass({
color={rippleColor}/>
);
}

let handleDragProps = {};

if (!this.props.disabled) {
handleDragProps = {
onTouchStart: this._onHandleTouchStart,
onMouseDown: this._onHandleMouseDown,
}
}

return (
<div {...others } style={this.prepareStyles(this.props.style)}>
<span className="mui-input-highlight"></span>
Expand All @@ -293,18 +305,9 @@ const Slider = React.createClass({
<div ref="track" style={this.prepareStyles(styles.track)}>
<div style={this.prepareStyles(styles.filled)}></div>
<div style={this.prepareStyles(remainingStyles)}></div>
<Draggable axis="x" bound="point"
cancel={this.props.disabled ? '*' : null}
start={{x: (percent * 100) + '%'}}
constrain={this._constrain()}
onStart={this._onDragStart}
onStop={this._onDragStop}
onDrag={this._onDragUpdate}
onMouseDown={this._onMouseDownKnob}>
<div style={handleStyles} tabIndex={0}>
{focusRipple}
</div>
</Draggable>
<div style={handleStyles} tabIndex={0} {...handleDragProps}>
{focusRipple}
</div>
</div>
</div>
<input ref="input" type="hidden"
Expand All @@ -318,6 +321,62 @@ const Slider = React.createClass({
);
},

_onHandleTouchStart(e) {
if (document) {
document.addEventListener('touchmove', this._dragTouchHandler, false);
document.addEventListener('touchup', this._dragTouchEndHandler, false);
document.addEventListener('touchend', this._dragTouchEndHandler, false);
document.addEventListener('touchcancel', this._dragTouchEndHandler, false);
}
this._onDragStart(e);
},

_onHandleMouseDown(e) {
if (document) {
document.addEventListener('mousemove', this._dragHandler, false);
document.addEventListener('mouseup', this._dragEndHandler, false);
}
this._onDragStart(e);
},

_dragHandler(e) {
if (this._dragRunning) { return; }
this._dragRunning = true;
requestAnimationFrame(() => {
this._onDragUpdate(e, e.clientX - this._getTrackLeft());
this._dragRunning = false;
});
},

_dragTouchHandler(e) {
if (this._dragRunning) { return; }
this._dragRunning = true;
requestAnimationFrame(() => {
this._onDragUpdate(e, e.touches[0].clientX - this._getTrackLeft());
this._dragRunning = false;
});
},

_dragEndHandler(e) {
if (document) {
document.removeEventListener('mousemove', this._dragHandler, false);
document.removeEventListener('mouseup', this._dragEndHandler, false);
}

this._onDragStop(e);
},

_dragTouchEndHandler(e) {
if (document) {
document.removeEventListener('touchmove', this._dragTouchHandler, false);
document.removeEventListener('touchup', this._dragTouchEndHandler, false);
document.removeEventListener('touchend', this._dragTouchEndHandler, false);
document.removeEventListener('touchcancel', this._dragTouchEndHandler, false);
}

this._onDragStop(e);
},

getValue() {
return this.state.value;
},
Expand All @@ -337,9 +396,13 @@ const Slider = React.createClass({
return this.state.percent;
},

setPercent(percent) {
setPercent(percent, callback) {
let value = this._alignValue(this._percentToValue(percent));
this.setState({value: value, percent: percent});
let { min, max } = this.props;
let alignedPercent = (value - min) / (max - min);
if (this.state.value !== value) {
this.setState({value: value, percent: alignedPercent}, callback);
}
},

clearValue() {
Expand All @@ -352,20 +415,6 @@ const Slider = React.createClass({
return parseFloat(alignValue.toFixed(5));
},

_constrain() {
let { min, max, step } = this.props;
let steps = (max - min) / step;
return (pos) => {
let pixelMax = ReactDOM.findDOMNode(this.refs.track).clientWidth;
let pixelStep = pixelMax / steps;
let cursor = Math.round(pos.left / pixelStep) * pixelStep;

return {
left: cursor,
};
};
},

_onFocus(e) {
this.setState({focused: true});
if (this.props.onFocus) this.props.onFocus(e);
Expand All @@ -388,39 +437,39 @@ const Slider = React.createClass({
this.setState({hovered: false});
},

_getTrackLeft() {
return ReactDOM.findDOMNode(this.refs.track).getBoundingClientRect().left;
},

_onMouseUp(e) {
if (!this.props.disabled) this.setState({active: false});
if (!this.state.dragging && Math.abs(this._pos - e.clientX) < 5) {
let pos = e.clientX - ReactDOM.findDOMNode(this).getBoundingClientRect().left;
let pos = e.clientX - this._getTrackLeft();
this._dragX(e, pos);
}

this._pos = undefined;
},

_onMouseDownKnob() {
if (!this.props.disabled) this.setState({active: true});
},

_onDragStart(e, ui) {
_onDragStart(e) {
this.setState({
dragging: true,
active: true,
});
if (this.props.onDragStart) this.props.onDragStart(e, ui);
if (this.props.onDragStart) this.props.onDragStart(e);
},

_onDragStop(e, ui) {
_onDragStop(e) {
this.setState({
dragging: false,
active: false,
});
if (this.props.onDragStop) this.props.onDragStop(e, ui);
if (this.props.onDragStop) this.props.onDragStop(e);
},

_onDragUpdate(e, ui) {
_onDragUpdate(e, pos) {
if (!this.state.dragging) return;
if (!this.props.disabled) this._dragX(e, ui.position.left);
if (!this.props.disabled) this._dragX(e, pos);
},

_dragX(e, pos) {
Expand All @@ -430,10 +479,9 @@ const Slider = React.createClass({
},

_updateWithChangeEvent(e, percent) {
if (this.state.percent === percent) return;
this.setPercent(percent);
let value = this._alignValue(this._percentToValue(percent));
if (this.props.onChange) this.props.onChange(e, value);
this.setPercent(percent, () => {
if (this.props.onChange) this.props.onChange(e, this.state.value);
});
},

_percentToValue(percent) {
Expand Down

0 comments on commit 1e0a4a5

Please sign in to comment.