From 14f65cc23b96ae4712e70235f6c74275690d9a9d Mon Sep 17 00:00:00 2001 From: felipethome Date: Sat, 13 Feb 2016 18:18:38 -0200 Subject: [PATCH 1/4] [Slider] Remove style-propable mixin and react-dom [Slider] Fix css calc for calcDisabledSpacing [Slider] Fix css calc for calcDisabledSpacing [Slider] Copy this.props.style directly in the div that uses it --- src/slider.jsx | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/slider.jsx b/src/slider.jsx index 62c87dbab9f4f3..b090b4e181e6ca 100644 --- a/src/slider.jsx +++ b/src/slider.jsx @@ -1,6 +1,4 @@ import React from 'react'; -import ReactDOM from 'react-dom'; -import StylePropable from './mixins/style-propable'; import Transitions from './styles/transitions'; import FocusRipple from './ripples/focus-ripple'; import getMuiTheme from './styles/getMuiTheme'; @@ -142,10 +140,6 @@ const Slider = React.createClass({ muiTheme: React.PropTypes.object, }, - mixins: [ - StylePropable, - ], - getDefaultProps() { return { disabled: false, @@ -199,7 +193,7 @@ const Slider = React.createClass({ getStyles() { const fillGutter = this.getTheme().handleSize / 2; const disabledGutter = this.getTheme().trackSize + this.getTheme().handleSizeDisabled / 2; - const calcDisabledSpacing = this.props.disabled ? ` -${disabledGutter}px` : ''; + const calcDisabledSpacing = this.props.disabled ? ` - ${disabledGutter}px` : ''; const styles = { root: { touchCallout: 'none', @@ -287,7 +281,7 @@ const Slider = React.createClass({ left: -this.getTheme().handleSize, }, }; - styles.filled = this.mergeStyles(styles.filledAndRemaining, { + styles.filled = Object.assign({}, styles.filledAndRemaining, { left: 0, backgroundColor: (this.props.disabled) ? this.getTheme().trackColor : @@ -295,7 +289,7 @@ const Slider = React.createClass({ marginRight: fillGutter, width: `calc(${(this.state.percent * 100)}%${calcDisabledSpacing})`, }); - styles.remaining = this.mergeStyles(styles.filledAndRemaining, { + styles.remaining = Object.assign({}, styles.filledAndRemaining, { right: 0, backgroundColor: this.getTheme().trackColor, marginLeft: fillGutter, @@ -437,7 +431,7 @@ const Slider = React.createClass({ }, _getTrackLeft() { - return ReactDOM.findDOMNode(this.refs.track).getBoundingClientRect().left; + return this.refs.track.getBoundingClientRect().left; }, handleMouseUp(e) { @@ -472,7 +466,7 @@ const Slider = React.createClass({ }, _dragX(e, pos) { - const max = ReactDOM.findDOMNode(this.refs.track).clientWidth; + const max = this.refs.track.clientWidth; if (pos < 0) pos = 0; else if (pos > max) pos = max; this._updateWithChangeEvent(e, pos / max); }, @@ -493,8 +487,9 @@ const Slider = React.createClass({ if (percent > 1) percent = 1; else if (percent < 0) percent = 0; const styles = this.getStyles(); - const sliderStyles = this.mergeStyles(styles.root, this.props.style); - const handleStyles = percent === 0 ? this.mergeStyles( + const sliderStyles = Object.assign({}, styles.root, this.props.style); + const handleStyles = percent === 0 ? Object.assign( + {}, styles.handle, styles.handleWhenPercentZero, this.state.active && styles.handleWhenActive, @@ -502,7 +497,8 @@ const Slider = React.createClass({ (this.state.hovered || this.state.focused) && !this.props.disabled && styles.handleWhenPercentZeroAndFocused, this.props.disabled && styles.handleWhenPercentZeroAndDisabled - ) : this.mergeStyles( + ) : Object.assign( + {}, styles.handle, this.state.active && styles.handleWhenActive, this.state.focused && {outline: 'none'}, @@ -511,7 +507,8 @@ const Slider = React.createClass({ left: `${(percent * 100)}%`, } ); - const rippleStyle = this.mergeStyles( + const rippleStyle = Object.assign( + {}, styles.ripple, percent === 0 && styles.rippleWhenPercentZero ); @@ -528,7 +525,7 @@ const Slider = React.createClass({ +
{this.props.description} {this.props.error}
-
-
-
-
+
+
+
+
{focusRipple}
From 2aa64efa86d2bd724420d7c2cf08a9ae7e35b090 Mon Sep 17 00:00:00 2001 From: felipethome Date: Sun, 14 Feb 2016 21:02:19 -0200 Subject: [PATCH 2/4] [Slider] Move getStyles to outside the component class --- src/slider.jsx | 251 ++++++++++++++++++++++++------------------------- 1 file changed, 121 insertions(+), 130 deletions(-) diff --git a/src/slider.jsx b/src/slider.jsx index b090b4e181e6ca..ff95958672b920 100644 --- a/src/slider.jsx +++ b/src/slider.jsx @@ -38,6 +38,122 @@ const valueInRangePropType = (props, propName, componentName) => { } }; +const getStyles = (props, state) => { + const { + slider, + } = state.muiTheme; + + const fillGutter = slider.handleSize / 2; + const disabledGutter = slider.trackSize + slider.handleSizeDisabled / 2; + const calcDisabledSpacing = props.disabled ? ` - ${disabledGutter}px` : ''; + + const styles = { + root: { + touchCallout: 'none', + userSelect: 'none', + cursor: 'default', + height: slider.handleSizeActive, + position: 'relative', + marginTop: 24, + marginBottom: 48, + }, + track: { + position: 'absolute', + top: (slider.handleSizeActive - slider.trackSize) / 2, + left: 0, + width: '100%', + height: slider.trackSize, + }, + filledAndRemaining: { + position: 'absolute', + top: 0, + height: '100%', + transition: Transitions.easeOut(null, 'margin'), + }, + handle: { + boxSizing: 'border-box', + position: 'absolute', + cursor: 'pointer', + pointerEvents: 'inherit', + top: 0, + left: '0%', + zIndex: 1, + margin: `${(slider.trackSize / 2)}px 0 0 0`, + width: slider.handleSize, + height: slider.handleSize, + backgroundColor: slider.selectionColor, + backgroundClip: 'padding-box', + border: '0px solid transparent', + borderRadius: '50%', + transform: 'translate(-50%, -50%)', + transition: + `${Transitions.easeOut('450ms', 'background')}, ${ + Transitions.easeOut('450ms', 'border-color')}, ${ + Transitions.easeOut('450ms', 'width')}, ${ + Transitions.easeOut('450ms', 'height')}`, + overflow: 'visible', + outline: 'none', + }, + handleWhenDisabled: { + boxSizing: 'content-box', + cursor: 'not-allowed', + backgroundColor: slider.trackColor, + width: slider.handleSizeDisabled, + height: slider.handleSizeDisabled, + border: 'none', + }, + handleWhenPercentZero: { + border: `${slider.trackSize}px solid ${slider.handleColorZero}`, + backgroundColor: slider.handleFillColor, + boxShadow: 'none', + }, + handleWhenPercentZeroAndDisabled: { + cursor: 'not-allowed', + width: slider.handleSizeDisabled, + height: slider.handleSizeDisabled, + }, + handleWhenPercentZeroAndFocused: { + border: `${slider.trackSize}px solid ${slider.trackColorSelected}`, + }, + handleWhenActive: { + width: slider.handleSizeActive, + height: slider.handleSizeActive, + }, + ripple: { + height: slider.handleSize, + width: slider.handleSize, + overflow: 'visible', + }, + rippleWhenPercentZero: { + top: -slider.trackSize, + left: -slider.trackSize, + }, + rippleInner: { + height: '300%', + width: '300%', + top: -slider.handleSize, + left: -slider.handleSize, + }, + rippleColor: { + fill: state.percent === 0 ? slider.handleColorZero : slider.rippleColor, + }, + }; + styles.filled = Object.assign({}, styles.filledAndRemaining, { + left: 0, + backgroundColor: (props.disabled) ? slider.trackColor : slider.selectionColor, + marginRight: fillGutter, + width: `calc(${(state.percent * 100)}%${calcDisabledSpacing})`, + }); + styles.remaining = Object.assign({}, styles.filledAndRemaining, { + right: 0, + backgroundColor: (state.hovered || state.focused) + && !props.disabled ? slider.trackColorSelected : slider.trackColor, + marginLeft: fillGutter, + width: `calc(${((1 - state.percent) * 100)}%${calcDisabledSpacing})`, + }); + + return styles; +}; const Slider = React.createClass({ @@ -186,119 +302,6 @@ const Slider = React.createClass({ } }, - getTheme() { - return this.state.muiTheme.slider; - }, - - getStyles() { - const fillGutter = this.getTheme().handleSize / 2; - const disabledGutter = this.getTheme().trackSize + this.getTheme().handleSizeDisabled / 2; - const calcDisabledSpacing = this.props.disabled ? ` - ${disabledGutter}px` : ''; - const styles = { - root: { - touchCallout: 'none', - userSelect: 'none', - cursor: 'default', - height: this.getTheme().handleSizeActive, - position: 'relative', - marginTop: 24, - marginBottom: 48, - }, - track: { - position: 'absolute', - top: (this.getTheme().handleSizeActive - this.getTheme().trackSize) / 2, - left: 0, - width: '100%', - height: this.getTheme().trackSize, - }, - filledAndRemaining: { - position: 'absolute', - top: 0, - height: '100%', - transition: Transitions.easeOut(null, 'margin'), - }, - handle: { - boxSizing: 'border-box', - position: 'absolute', - cursor: 'pointer', - pointerEvents: 'inherit', - top: 0, - left: '0%', - zIndex: 1, - margin: `${(this.getTheme().trackSize / 2)}px 0 0 0`, - width: this.getTheme().handleSize, - height: this.getTheme().handleSize, - backgroundColor: this.getTheme().selectionColor, - backgroundClip: 'padding-box', - border: '0px solid transparent', - borderRadius: '50%', - transform: 'translate(-50%, -50%)', - transition: - `${Transitions.easeOut('450ms', 'background')}, ${ - Transitions.easeOut('450ms', 'border-color')}, ${ - Transitions.easeOut('450ms', 'width')}, ${ - Transitions.easeOut('450ms', 'height')}`, - overflow: 'visible', - }, - handleWhenDisabled: { - boxSizing: 'content-box', - cursor: 'not-allowed', - backgroundColor: this.getTheme().trackColor, - width: this.getTheme().handleSizeDisabled, - height: this.getTheme().handleSizeDisabled, - border: 'none', - }, - handleWhenPercentZero: { - border: `${this.getTheme().trackSize}px solid ${this.getTheme().handleColorZero}`, - backgroundColor: this.getTheme().handleFillColor, - boxShadow: 'none', - }, - handleWhenPercentZeroAndDisabled: { - cursor: 'not-allowed', - width: this.getTheme().handleSizeDisabled, - height: this.getTheme().handleSizeDisabled, - }, - handleWhenPercentZeroAndFocused: { - border: `${this.getTheme().trackSize}px solid ${this.getTheme().trackColorSelected}`, - }, - handleWhenActive: { - width: this.getTheme().handleSizeActive, - height: this.getTheme().handleSizeActive, - }, - ripple: { - height: this.getTheme().handleSize, - width: this.getTheme().handleSize, - overflow: 'visible', - }, - rippleWhenPercentZero: { - top: -this.getTheme().trackSize, - left: -this.getTheme().trackSize, - }, - rippleInner: { - height: '300%', - width: '300%', - top: -this.getTheme().handleSize, - left: -this.getTheme().handleSize, - }, - }; - styles.filled = Object.assign({}, styles.filledAndRemaining, { - left: 0, - backgroundColor: (this.props.disabled) ? - this.getTheme().trackColor : - this.getTheme().selectionColor, - marginRight: fillGutter, - width: `calc(${(this.state.percent * 100)}%${calcDisabledSpacing})`, - }); - styles.remaining = Object.assign({}, styles.filledAndRemaining, { - right: 0, - backgroundColor: this.getTheme().trackColor, - marginLeft: fillGutter, - width: `calc(${((1 - this.state.percent) * 100)}%${calcDisabledSpacing})`, - }); - - return styles; - }, - // Needed to prevent text selection when dragging the slider handler. // In the future, we should consider use to avoid @@ -398,10 +401,6 @@ const Slider = React.createClass({ } }, - clearValue() { - this.setValue(this.props.min); - }, - _alignValue(val) { const {step, min} = this.props; const alignValue = Math.round((val - min) / step) * step + min; @@ -486,14 +485,13 @@ const Slider = React.createClass({ let percent = this.state.percent; if (percent > 1) percent = 1; else if (percent < 0) percent = 0; - const styles = this.getStyles(); + const styles = getStyles(this.props, this.state); const sliderStyles = Object.assign({}, styles.root, this.props.style); const handleStyles = percent === 0 ? Object.assign( {}, styles.handle, styles.handleWhenPercentZero, this.state.active && styles.handleWhenActive, - this.state.focused && {outline: 'none'}, (this.state.hovered || this.state.focused) && !this.props.disabled && styles.handleWhenPercentZeroAndFocused, this.props.disabled && styles.handleWhenPercentZeroAndDisabled @@ -501,7 +499,6 @@ const Slider = React.createClass({ {}, styles.handle, this.state.active && styles.handleWhenActive, - this.state.focused && {outline: 'none'}, this.props.disabled && styles.handleWhenDisabled, { left: `${(percent * 100)}%`, @@ -512,13 +509,8 @@ const Slider = React.createClass({ styles.ripple, percent === 0 && styles.rippleWhenPercentZero ); - const remainingStyles = styles.remaining; - if ((this.state.hovered || this.state.focused) && !this.props.disabled) { - remainingStyles.backgroundColor = this.getTheme().trackColorSelected; - } - const rippleShowCondition = (this.state.hovered || this.state.focused) && !this.state.active; - const rippleColor = this.state.percent === 0 ? this.getTheme().handleColorZero : this.getTheme().rippleColor; + let focusRipple; if (!this.props.disabled && !this.props.disableFocusRipple) { focusRipple = ( @@ -529,13 +521,12 @@ const Slider = React.createClass({ innerStyle={styles.rippleInner} show={rippleShowCondition} muiTheme={this.state.muiTheme} - color={rippleColor} + color={styles.rippleColor.fill} /> ); } let handleDragProps = {}; - if (!this.props.disabled) { handleDragProps = { onTouchStart: this._onHandleTouchStart, @@ -548,7 +539,7 @@ const Slider = React.createClass({ } = this.state.muiTheme; return ( -
+
{this.props.description} {this.props.error}
-
+
{focusRipple}
From f39258575b42a2b94f3154f1d1a2434648f78508 Mon Sep 17 00:00:00 2001 From: felipethome Date: Sun, 14 Feb 2016 21:07:53 -0200 Subject: [PATCH 3/4] [Slider] Put back the clearValue() declaration --- src/slider.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/slider.jsx b/src/slider.jsx index ff95958672b920..b9ea59c1ef0ff9 100644 --- a/src/slider.jsx +++ b/src/slider.jsx @@ -401,6 +401,10 @@ const Slider = React.createClass({ } }, + clearValue() { + this.setValue(this.props.min); + }, + _alignValue(val) { const {step, min} = this.props; const alignValue = Math.round((val - min) / step) * step + min; From 906b16a020cab95ae036807fa5a67b0eea21a471 Mon Sep 17 00:00:00 2001 From: felipethome Date: Mon, 15 Feb 2016 02:46:42 -0200 Subject: [PATCH 4/4] [Slider] Destructure properties in render() and move css to getStyles() --- src/slider.jsx | 58 +++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/src/slider.jsx b/src/slider.jsx index b9ea59c1ef0ff9..9f2d8a72d52278 100644 --- a/src/slider.jsx +++ b/src/slider.jsx @@ -76,7 +76,7 @@ const getStyles = (props, state) => { cursor: 'pointer', pointerEvents: 'inherit', top: 0, - left: '0%', + left: state.percent === 0 ? '0%' : `${(state.percent * 100)}%`, zIndex: 1, margin: `${(slider.trackSize / 2)}px 0 0 0`, width: slider.handleSize, @@ -485,28 +485,42 @@ const Slider = React.createClass({ }, render() { - const {...others} = this.props; + const { + description, + disabled, + disableFocusRipple, + error, + max, + min, + name, + required, + step, + style, + ...others, + } = this.props; + + const { + prepareStyles, + } = this.state.muiTheme; + let percent = this.state.percent; if (percent > 1) percent = 1; else if (percent < 0) percent = 0; const styles = getStyles(this.props, this.state); - const sliderStyles = Object.assign({}, styles.root, this.props.style); + const sliderStyles = Object.assign({}, styles.root, style); const handleStyles = percent === 0 ? Object.assign( {}, styles.handle, styles.handleWhenPercentZero, this.state.active && styles.handleWhenActive, - (this.state.hovered || this.state.focused) && !this.props.disabled + (this.state.hovered || this.state.focused) && !disabled && styles.handleWhenPercentZeroAndFocused, - this.props.disabled && styles.handleWhenPercentZeroAndDisabled + disabled && styles.handleWhenPercentZeroAndDisabled ) : Object.assign( {}, styles.handle, this.state.active && styles.handleWhenActive, - this.props.disabled && styles.handleWhenDisabled, - { - left: `${(percent * 100)}%`, - } + disabled && styles.handleWhenDisabled, ); const rippleStyle = Object.assign( {}, @@ -516,7 +530,7 @@ const Slider = React.createClass({ const rippleShowCondition = (this.state.hovered || this.state.focused) && !this.state.active; let focusRipple; - if (!this.props.disabled && !this.props.disableFocusRipple) { + if (!disabled && !disableFocusRipple) { focusRipple = ( - {this.props.description} - {this.props.error} +
+ {description} + {error}
);