From 9bd581fea66ee80b203bcc94dd930a3417b4a491 Mon Sep 17 00:00:00 2001 From: igorbt Date: Wed, 7 Oct 2015 13:23:10 +0300 Subject: [PATCH 1/4] removed react-draggable dependency --- .../components/pages/components/sliders.jsx | 8 +- package.json | 3 - src/slider.jsx | 131 ++++++++++++------ 3 files changed, 93 insertions(+), 49 deletions(-) diff --git a/docs/src/app/components/pages/components/sliders.jsx b/docs/src/app/components/pages/components/sliders.jsx index 77c8903770b84d..aa587d0b83bf49 100644 --- a/docs/src/app/components/pages/components/sliders.jsx +++ b/docs/src/app/components/pages/components/sliders.jsx @@ -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', diff --git a/package.json b/package.json index e0fce83ce7bff3..2f953280f1f2fe 100644 --- a/package.json +++ b/package.json @@ -29,9 +29,6 @@ "url": "https://github.com/callemall/material-ui/issues" }, "homepage": "http://material-ui.com/", - "dependencies": { - "react-draggable2": "^0.5.1" - }, "peerDependencies": { "react": ">=0.13", "react-tap-event-plugin": "^0.1.3" diff --git a/src/slider.jsx b/src/slider.jsx index c0b2cfce7a1c06..a982128aade269 100644 --- a/src/slider.jsx +++ b/src/slider.jsx @@ -1,6 +1,5 @@ const React = require('react'); 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'); @@ -153,7 +152,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', @@ -250,7 +249,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, @@ -275,6 +277,16 @@ const Slider = React.createClass({ color={rippleColor}/> ); } + + let handleDragProps = {}; + + if (!this.props.disabled) { + handleDragProps = { + onTouchStart: this._onHandleTouchStart, + onMouseDown: this._onHandleMouseDown, + } + } + return (
@@ -291,18 +303,9 @@ const Slider = React.createClass({
- -
- {focusRipple} -
-
+
+ {focusRipple} +
{ + 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; }, @@ -337,7 +396,9 @@ const Slider = React.createClass({ setPercent(percent) { let value = this._alignValue(this._percentToValue(percent)); - this.setState({value: value, percent: percent}); + let { min, max } = this.props; + let alignedPercent = (value - min) / (max - min); + this.setState({value: value, percent: alignedPercent}); }, clearValue() { @@ -350,19 +411,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 = React.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); @@ -385,39 +433,39 @@ const Slider = React.createClass({ this.setState({hovered: false}); }, + _getTrackLeft() { + return React.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 - React.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) { @@ -429,8 +477,7 @@ 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); + if (this.props.onChange) this.props.onChange(e, this.state.value); }, _percentToValue(percent) { From dea2c4dea852c640347af3a910e6abbf8f1f5cf8 Mon Sep 17 00:00:00 2001 From: igorbt Date: Fri, 9 Oct 2015 10:43:08 +0300 Subject: [PATCH 2/4] fixed wrong value in onChange when setState is async --- src/slider.jsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/slider.jsx b/src/slider.jsx index a982128aade269..8cbc1e1471bbf6 100644 --- a/src/slider.jsx +++ b/src/slider.jsx @@ -394,11 +394,11 @@ const Slider = React.createClass({ return this.state.percent; }, - setPercent(percent) { + setPercent(percent, callback) { let value = this._alignValue(this._percentToValue(percent)); let { min, max } = this.props; let alignedPercent = (value - min) / (max - min); - this.setState({value: value, percent: alignedPercent}); + this.setState({value: value, percent: alignedPercent}, callback); }, clearValue() { @@ -476,8 +476,9 @@ const Slider = React.createClass({ _updateWithChangeEvent(e, percent) { if (this.state.percent === percent) return; - this.setPercent(percent); - if (this.props.onChange) this.props.onChange(e, this.state.value); + this.setPercent(percent, () => { + if (this.props.onChange) this.props.onChange(e, this.state.value); + }); }, _percentToValue(percent) { From 3ca83aad051cd6fe9b1b510273fa0e18621518ce Mon Sep 17 00:00:00 2001 From: igorbt Date: Sat, 10 Oct 2015 08:49:40 +0300 Subject: [PATCH 3/4] updating value in state only if it really changes so avoiding unnecessary re-rendering and unnecessary calling of onChange from _updateWithChangeEvent. --- src/slider.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slider.jsx b/src/slider.jsx index 8cbc1e1471bbf6..3f6597028f181a 100644 --- a/src/slider.jsx +++ b/src/slider.jsx @@ -398,7 +398,9 @@ const Slider = React.createClass({ let value = this._alignValue(this._percentToValue(percent)); let { min, max } = this.props; let alignedPercent = (value - min) / (max - min); - this.setState({value: value, percent: alignedPercent}, callback); + if (this.state.value !== value) { + this.setState({value: value, percent: alignedPercent}, callback); + } }, clearValue() { From d2b53f34fad4569dc22e78583268129997c39528 Mon Sep 17 00:00:00 2001 From: igorbt Date: Sat, 10 Oct 2015 12:36:59 +0300 Subject: [PATCH 4/4] Removed unneded percent checking --- src/slider.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/slider.jsx b/src/slider.jsx index 3f6597028f181a..3ba4f552a1cc2c 100644 --- a/src/slider.jsx +++ b/src/slider.jsx @@ -477,7 +477,6 @@ const Slider = React.createClass({ }, _updateWithChangeEvent(e, percent) { - if (this.state.percent === percent) return; this.setPercent(percent, () => { if (this.props.onChange) this.props.onChange(e, this.state.value); });