From 555f5a06600238aaa9541190bc27f23a9e4b80ad Mon Sep 17 00:00:00 2001 From: Benjy Cui Date: Sat, 5 Dec 2015 12:30:14 +0800 Subject: [PATCH] fix: value should be aligned if `min` `max` changed --- examples/range.js | 24 ++++++++++++++++++++++-- examples/slider.js | 26 ++++++++++++++++++++++++-- package.json | 1 + src/Slider.jsx | 41 +++++++++++++++++++++++++++++++---------- tests/index.spec.js | 2 +- 5 files changed, 79 insertions(+), 15 deletions(-) diff --git a/examples/range.js b/examples/range.js index ef4edb9..e97263d 100644 --- a/examples/range.js +++ b/examples/range.js @@ -16,14 +16,34 @@ const CustomizedRange = React.createClass({ value: [20, 40], }; }, - onChange: function(value) { + onSliderChange: function(value) { log(value); this.setState({ value: value, }); }, + onMinChange: function(e) { + this.setState({ + min: +e.target.value || 0, + }); + }, + onMaxChange: function(e) { + this.setState({ + max: +e.target.value || 100, + }); + }, render: function() { - return ; + return ( +
+ + +
+ + +

+ +
+ ); }, }); diff --git a/examples/slider.js b/examples/slider.js index c06528f..45a4dad 100644 --- a/examples/slider.js +++ b/examples/slider.js @@ -19,16 +19,38 @@ const CustomizedSlider = React.createClass({ getInitialState: function() { return { value: 50, + min: 0, + max: 100, }; }, - onChange: function(value) { + onSliderChange: function(value) { log(value); this.setState({ value: value, }); }, + onMinChange: function(e) { + this.setState({ + min: +e.target.value || 0, + }); + }, + onMaxChange: function(e) { + this.setState({ + max: +e.target.value || 100, + }); + }, render: function() { - return ; + return ( +
+ + +
+ + +

+ +
+ ); }, }); diff --git a/package.json b/package.json index 85232df..ca8ff4d 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ ], "dependencies": { "classnames": "^2.2.1", + "object-assign": "^4.0.1", "rc-tooltip": "3.x", "rc-util": "3.x" } diff --git a/src/Slider.jsx b/src/Slider.jsx index 5b6ed60..76cd574 100644 --- a/src/Slider.jsx +++ b/src/Slider.jsx @@ -1,6 +1,7 @@ import React from 'react'; import {Dom as DomUtils} from 'rc-util'; import classNames from 'classnames'; +import objectAssign from 'object-assign'; import Track from './Track'; import Handle from './Handle'; import Dots from './Dots'; @@ -66,18 +67,34 @@ class Slider extends React.Component { } componentWillReceiveProps(nextProps) { + if (!('value' in nextProps || 'min' in nextProps || 'max' in nextProps)) return; + + const {lowerBound, upperBound} = this.state; if (nextProps.range) { const value = nextProps.value; - if (value) { - this.setState({ - upperBound: value[1], - lowerBound: value[0], - }); - } - } else if ('value' in nextProps) { + const nextUpperBound = this.trimAlignValue(value[1], nextProps); + const nextLowerBound = this.trimAlignValue(value[0], nextProps); + if (nextLowerBound === lowerBound && nextUpperBound === upperBound) return; + this.setState({ - upperBound: nextProps.value, + upperBound: nextUpperBound, + lowerBound: nextLowerBound, }); + if (this.isValueOutOfBounds(upperBound, nextProps) || + this.isValueOutOfBounds(lowerBound, nextProps)) { + this.props.onChange([nextLowerBound, nextUpperBound]); + } + } else { + const nextValue = this.trimAlignValue(nextProps.value, nextProps); + if (nextValue === upperBound && lowerBound === nextProps.min) return; + + this.setState({ + upperBound: nextValue, + lowerBound: nextProps.min, + }); + if (this.isValueOutOfBounds(upperBound, nextProps)) { + this.props.onChange(nextValue); + } } } @@ -214,10 +231,14 @@ class Slider extends React.Component { return precision; } - trimAlignValue(v) { + isValueOutOfBounds(value, props) { + return value < props.min || value > props.max; + } + + trimAlignValue(v, nextProps) { const state = this.state || {}; const {handle, lowerBound, upperBound} = state; - const {marks, step, min, max} = this.props; + const {marks, step, min, max} = objectAssign({}, this.props, nextProps || {}); let val = v; if (val <= min) { diff --git a/tests/index.spec.js b/tests/index.spec.js index f37a55a..2f958f1 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -106,7 +106,7 @@ describe('rc-slider', function() { expect(ReactTestUtils.scryRenderedDOMComponentsWithClass(slider, 'rc-slider-mark-text')[1].innerHTML).to.be('30'); expect(ReactTestUtils.scryRenderedDOMComponentsWithClass(slider, 'rc-slider-mark-text')[2].innerHTML).to.be('100'); - const range = ReactDOM.render(, div); + const range = ReactDOM.render(, div); expect(ReactTestUtils.scryRenderedDOMComponentsWithClass(range, 'rc-slider-mark-text').length).to.be(3); });