Skip to content

Commit

Permalink
Merge pull request #304 from Robin-front/bugfix/keep-pushable
Browse files Browse the repository at this point in the history
Bugfix/keep pushable
  • Loading branch information
yesmeck authored Feb 27, 2018
2 parents c7f6f22 + c4522e7 commit 7c82832
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 20 deletions.
7 changes: 4 additions & 3 deletions examples/range.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'rc-slider/assets/index.less';
import React from 'react';
import ReactDOM from 'react-dom';
import Slider from 'rc-slider';

const Range = Slider.Range;

const style = { width: 400, margin: 50 };
Expand Down Expand Up @@ -106,7 +107,7 @@ class ControlledRange extends React.Component {
}
render() {
return (
<Range value={this.state.value} onChange={this.handleChange}/>
<Range value={this.state.value} onChange={this.handleChange} />
);
}
}
Expand Down Expand Up @@ -183,8 +184,8 @@ ReactDOM.render(
<ControlledRangeDisableAcross />
</div>
<div style={style}>
<p>Controlled Range, not allow across, pushable</p>
<ControlledRangeDisableAcross pushable/>
<p>Controlled Range, not allow across, pushable=5</p>
<ControlledRangeDisableAcross pushable={5} />
</div>
<div style={style}>
<p>Multi Range</p>
Expand Down
25 changes: 14 additions & 11 deletions src/Range.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Range extends React.Component {
props.defaultValue : initialValue;
const value = props.value !== undefined ?
props.value : defaultValue;
const bounds = value.map(v => this.trimAlignValue(v));
const bounds = value.map((v, i) => this.trimAlignValue(v, i));
const recent = bounds[0] === max ? 0 : bounds.length - 1;

this.state = {
Expand All @@ -57,9 +57,10 @@ class Range extends React.Component {
shallowEqual(this.props.value, nextProps.value)) {
return;
}

const { bounds } = this.state;
const value = nextProps.value || bounds;
const nextBounds = value.map(v => this.trimAlignValue(v, nextProps));
const nextBounds = value.map((v, i) => this.trimAlignValue(v, i, nextProps));
if (nextBounds.length === bounds.length && nextBounds.every((v, i) => v === bounds[i])) return;

this.setState({ bounds: nextBounds });
Expand Down Expand Up @@ -263,23 +264,25 @@ class Range extends React.Component {
return true;
}

trimAlignValue(v, nextProps = {}) {
trimAlignValue(v, handle, nextProps = {}) {
const mergedProps = { ...this.props, ...nextProps };
const valInRange = utils.ensureValueInRange(v, mergedProps);
const valNotConflict = this.ensureValueNotConflict(valInRange, mergedProps);
const valNotConflict = this.ensureValueNotConflict(handle, valInRange, mergedProps);
return utils.ensureValuePrecision(valNotConflict, mergedProps);
}

ensureValueNotConflict(val, { allowCross }) {
ensureValueNotConflict(handle, val, { allowCross, pushable: thershold }) {
const state = this.state || {};
const { handle, bounds } = state;
const { bounds } = state;
handle = handle === undefined ? state.handle : handle;
thershold = Number(thershold);
/* eslint-disable eqeqeq */
if (!allowCross && handle != null) {
if (handle > 0 && val <= bounds[handle - 1]) {
return bounds[handle - 1];
if (!allowCross && handle != null && bounds !== undefined) {
if (handle > 0 && val <= (bounds[handle - 1] + thershold)) {
return bounds[handle - 1] + thershold;
}
if (handle < bounds.length - 1 && val >= bounds[handle + 1]) {
return bounds[handle + 1];
if (handle < bounds.length - 1 && val >= (bounds[handle + 1] - thershold)) {
return bounds[handle + 1] - thershold;
}
}
/* eslint-enable eqeqeq */
Expand Down
6 changes: 0 additions & 6 deletions src/common/createSlider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,6 @@ export default function createSlider(Component) {
/* eslint-enable no-unused-expressions */
}

onMouseUp = () => {
this.onEnd();
this.removeDocumentEvents();
}

onMouseMove = (e) => {
if (!this.sliderRef) {
this.onEnd();
Expand Down Expand Up @@ -290,7 +285,6 @@ export default function createSlider(Component) {
className={sliderClassName}
onTouchStart={disabled ? noop : this.onTouchStart}
onMouseDown={disabled ? noop : this.onMouseDown}
onMouseUp={disabled ? noop : this.onMouseUp}
onKeyDown={disabled ? noop : this.onKeyDown}
onFocus={disabled ? noop : this.onFocus}
onBlur={disabled ? noop : this.onBlur}
Expand Down
85 changes: 85 additions & 0 deletions tests/Range.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,91 @@ describe('Range', () => {
expect(wrapper.state().visibles[1]).toBe(false);
});

it('should keep pushable when not allowCross and setState', () => {
class CustomizedRange extends React.Component { // eslint-disable-line
constructor(props) {
super(props);
this.state = {
value: [20, 40],
};
}
getSlider() {
return this.refs.slider;
}
render() {
return <Range ref="slider" allowCross={false} value={this.state.value} pushable={10} />;
}
}
const wrapper = mount(<CustomizedRange />);
expect(wrapper.instance().getSlider().state.bounds[0]).toBe(20);
expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
wrapper.setState({ value: [30, 40] });
expect(wrapper.instance().getSlider().state.bounds[0]).toBe(30);
expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
wrapper.setState({ value: [35, 40] });
expect(wrapper.instance().getSlider().state.bounds[0]).toBe(30);
expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
wrapper.setState({ value: [30, 30] });
expect(wrapper.instance().getSlider().state.bounds[0]).toBe(30);
expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
});

it('should keep pushable with pushable s defalutValue when not allowCross and setState', () => {
class CustomizedRange extends React.Component { // eslint-disable-line
constructor(props) {
super(props);
this.state = {
value: [20, 40],
};
this.onChange = this.onChange.bind(this);
}
onChange(value) {
this.setState({
value,
});
}
getSlider() {
return this.refs.slider;
}
render() {
return <Range ref="slider" allowCross={false} value={this.state.value} pushable onChange={this.onChange} />;
}
}
const map = {};
document.addEventListener = jest.genMockFn().mockImplementation((event, cb) => {
map[event] = cb;
});

const mockRect = (wrapper) => {
wrapper.instance().getSlider().sliderRef.getBoundingClientRect = () => ({
left: 0,
width: 100,
});
};

const container = document.createElement('div');
document.body.appendChild(container);

const wrapper = mount(<CustomizedRange />, { attachTo: container });
mockRect(wrapper);

expect(wrapper.instance().getSlider().state.bounds[0]).toBe(20);
expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);

wrapper.find('.rc-slider').simulate('mouseDown', { button: 0, pageX: 0, pageY: 0 });
map.mousemove({ type: 'mousemove', pageX: 30, pageY: 0 });
map.mouseup({ type: 'mouseup', pageX: 30, pageY: 0 });

expect(wrapper.instance().getSlider().state.bounds[0]).toBe(30);
expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);

wrapper.find('.rc-slider').simulate('mouseDown', { button: 0, pageX: 0, pageY: 0 });
map.mousemove({ type: 'mousemove', pageX: 50, pageY: 0 });
map.mouseup({ type: 'mouseup', pageX: 50, pageY: 0 });
expect(wrapper.instance().getSlider().state.bounds[0]).toBe(39);
expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
});

describe('focus & blur', () => {
let container;

Expand Down

0 comments on commit 7c82832

Please sign in to comment.