Compare commits

...
23 Commits
Author SHA1 Message Date
Benjy Cui ddcf32b094 bump 3.6.2 2016-04-28 09:35:21 +08:00
Boris Serdiuk 025a9e7ea6 Merge pull request #99 from react-component/fix-bugs
Fix #96 and #97
2016-04-27 15:08:48 +04:00
Benjy Cui e4396ae4bd refactor: simplify code 2016-04-27 17:48:17 +08:00
Benjy Cui 37b7f508da fix: use the latest step, close: #96 2016-04-27 14:29:45 +08:00
Benjy Cui ecbb253986 fix: set recent default value correctly, close: #97 2016-04-27 14:17:32 +08:00
Benjy Cui f4a82e3fd1 bump 3.6.1 2016-04-27 12:09:04 +08:00
Benjy Cui 0b1a421a71 chore: add warning for invalid usage, close: #91 2016-04-27 12:07:20 +08:00
Benjy Cui 0e6fed5c9b Merge pull request #85 from react-component/feat-vertical
feat: vertical slider
2016-04-10 08:53:55 +08:00
叶言 1ce8c3b117 fix: eslint error 2016-04-09 13:32:44 +08:00
叶言 ffdd062074 fix: some diffs
- update to 3.6.0 (refs:https://github.com/react-component/slider/pull/85#discussion-diff-58325891)
- change `.rc-slider-vertical` to `.{prefixClass}-vertical` (refs:https://github.com/react-component/slider/pull/85#discussion-diff-58325944)
- put all the slider & Range in one row (refs:https://github.com/react-component/slider/pull/85#discussion-diff-58326190)
2016-04-09 13:04:52 +08:00
叶言 3b03957a54 feat: vertical slider
- add `vertical` props
- add vertical slider demo: v-marks.html v-range.html v-slider.html

refs:https://github.com/react-component/slider/issues/18
2016-04-01 16:40:36 +08:00
Benjy Cui e1be65a107 docs: update demo 2016-03-23 11:48:36 +08:00
Benjy Cui 68d3efc7da deps: remove object-assign 2016-03-23 10:54:54 +08:00
Benjy Cui 806cb06d76 bump 3.5.1 2016-03-22 17:22:43 +08:00
Benjy Cui 73b9953084 refactor: update Marks style algorithm 2016-03-22 17:21:50 +08:00
Benjy Cui 6347b6d0c6 bump 3.5.0 2016-03-22 16:55:02 +08:00
Benjy Cui 6a5573b6ca feat: support React.Component in marks 2016-03-22 16:53:38 +08:00
Benjy Cui e030ba9f9d refactor: rename Dots to Steps 2016-03-22 16:27:50 +08:00
Benjy Cui daaea139b9 bump 3.4.0 2016-03-17 15:48:33 +08:00
Boris Serdiuk 2641880783 Merge pull request #82 from react-component/feat-mark-style
feat: support set style of specific mark point
2016-03-17 10:30:45 +03:00
Benjy Cui d6e81a692c feat: support set style of specific mark point 2016-03-17 09:45:55 +08:00
Benjy Cui 0512ee6ee0 Merge pull request #71 from kalinichenko/master
put marks in correct order so one can style it
2016-02-02 20:53:13 +08:00
Andrey Kalinichenko 613a2ae213 put marks in correct order so one can style it 2016-02-02 11:35:10 +01:00
18 changed files with 449 additions and 62 deletions
+5
View File
@@ -1,6 +1,11 @@
# History
----
## 3.6.0 / 2016-04-01
[#18](https://github.com/react-component/slider/issues/18) add `vertical` props ([@wnlee](https://github.com/WNLee))
...
## 1.2.5 / 2015-07-13
+8 -2
View File
@@ -90,9 +90,9 @@ ReactDOM.render(<Rcslider />, container);
</tr>
<tr>
<td>marks</td>
<td>object {number: string}</td>
<td>object{number: string} or object{number: object{ style, label }}</td>
<td>{}</td>
<td>Mark on the slider. The key determines the position, and the value determines what will show.</td>
<td>Mark on the slider. The key determines the position, and the value determines what will show. If you want to set the style of a specific mark point, the value should be an object which contains `style` and `label` properties.</td>
</tr>
<tr>
<td>step</td>
@@ -112,6 +112,12 @@ ReactDOM.render(<Rcslider />, container);
<td>true</td>
<td>When `range` is `true`, `allowCross` could be set as `true` to allow those two handles cross.</td>
</tr>
<tr>
<td>vertical</td>
<td>boolean</td>
<td>false</td>
<td>If vertical is `true`, the slider will be vertical.</td>
</tr>
<tr>
<td>defaultValue</td>
<td>number or [number, number]</td>
+40 -1
View File
@@ -94,7 +94,7 @@
&-dot {
position: absolute;
top: -2px;
bottom: -2px;
margin-left: -4px;
width: 8px;
height: 8px;
@@ -133,6 +133,45 @@
}
}
.@{prefixClass}-vertical {
width: 4px;
height: 100%;
.@{prefixClass} {
&-track {
bottom: 0;
width: 4px;
}
&-handle {
position: absolute;
margin-left: -5px;
margin-bottom: -7px;
}
&-mark {
top: 0;
left: 10px;
height: 100%;
}
&-step {
height: 100%;
width: 4px;
}
&-dot {
left: 2px;
margin-bottom: -4px;
&:first-child {
margin-bottom: -4px;
}
&:last-child {
margin-bottom: -4px;
}
}
}
}
.motion-common() {
animation-duration: .3s;
animation-fill-mode: both;
+7 -2
View File
@@ -7,11 +7,16 @@ const Slider = require('rc-slider');
const style = {width: 400, margin: 50};
const marks = {
'-10': '-10°C',
0: '0°C',
0: <strong>0°C</strong>,
26: '26°C',
37: '37°C',
50: '50°C',
100: '100°C',
100: {
style: {
color: 'red',
},
label: <strong>100°C</strong>,
},
};
function log(value) {
+26 -2
View File
@@ -14,17 +14,41 @@ function log(value) {
const CustomizedRange = React.createClass({
getInitialState: function() {
return {
lowerBound: 20,
upperBound: 40,
value: [20, 40],
};
},
onLowerBoundChange: function(e) {
this.setState({ lowerBound: +e.target.value });
},
onUpperBoundChange: function(e) {
this.setState({ upperBound: +e.target.value });
},
onSliderChange: function(value) {
log(value);
this.setState({
value: value,
});
},
handleApply: function() {
const { lowerBound, upperBound } = this.state;
this.setState({ value: [lowerBound, upperBound]});
},
render: function() {
return <Slider range value={this.state.value} onChange={this.onSliderChange} />;
return (
<div>
<label>LowerBound: </label>
<input type="number" value={this.state.lowerBound} onChange={this.onLowerBoundChange} />
<br />
<label>UpperBound: </label>
<input type="number" value={this.state.upperBound} onChange={this.onUpperBoundChange} />
<br />
<button onClick={this.handleApply}>Apply</button>
<br /><br />
<Slider range allowCross={false} value={this.state.value} onChange={this.onSliderChange} />
</div>
);
},
});
@@ -71,7 +95,7 @@ ReactDOM.render(
</div>
<div style={style}>
<p>Basic Range`step=20` </p>
<Slider range step={20} defaultValue={[20, 40]} onBeforeChange={log} />
<Slider range step={20} defaultValue={[20, 20]} onBeforeChange={log} />
</div>
<div style={style}>
<p>Basic Range`step=20, dots` </p>
+1
View File
@@ -0,0 +1 @@
placeholder
+55
View File
@@ -0,0 +1,55 @@
require('rc-slider/assets/index.less');
const React = require('react');
const ReactDOM = require('react-dom');
const Slider = require('rc-slider');
const style = {float: 'left', width: 160, height: 400, marginBottom: 160, marginLeft: 50};
const parentStyle = {overflow: 'hidden'};
const marks = {
'-10': '-10°C',
0: <strong>0°C</strong>,
26: '26°C',
37: '37°C',
50: '50°C',
100: {
style: {
color: 'red',
},
label: <strong>100°C</strong>,
},
};
function log(value) {
console.log(value);
}
ReactDOM.render(
<div style={parentStyle}>
<div style={style}>
<p>Slider with marks, `step=null`</p>
<Slider vertical min={-10} marks={marks} step={null} onChange={log} defaultValue={20} />
</div>
<div style={style}>
<p>Slider with marks and steps</p>
<Slider vertical dots min={-10} marks={marks} step={10} onChange={log} defaultValue={20} />
</div>
<div style={style}>
<p>Slider with marks, `included=false`</p>
<Slider vertical min={-10} marks={marks} included={false} defaultValue={20} />
</div>
<div style={style}>
<p>Slider with marks and steps, `included=false`</p>
<Slider vertical min={-10} marks={marks} step={10} included={false} defaultValue={20} />
</div>
<div style={style}>
<p>Range with marks</p>
<Slider vertical min={-10} range marks={marks} onChange={log} defaultValue={[20, 40]} />
</div>
<div style={style}>
<p>Range with marks and steps</p>
<Slider vertical min={-10} range marks={marks} step={10} onChange={log} defaultValue={[20, 40]} />
</div>
</div>
, document.getElementById('__react-content'));
View File
+116
View File
@@ -0,0 +1,116 @@
/* eslint react/no-multi-comp: 0 */
require('rc-slider/assets/index.less');
const React = require('react');
const ReactDOM = require('react-dom');
const Slider = require('rc-slider');
const style = {float: 'left', width: 180, height: 400, marginBottom: 160, marginLeft: 50};
const parentStyle = {overflow: 'hidden'};
function log(value) {
console.log(value);
}
const CustomizedRange = React.createClass({
getInitialState: function() {
return {
lowerBound: 20,
upperBound: 40,
value: [20, 40],
};
},
onLowerBoundChange: function(e) {
this.setState({ lowerBound: +e.target.value });
},
onUpperBoundChange: function(e) {
this.setState({ upperBound: +e.target.value });
},
onSliderChange: function(value) {
log(value);
this.setState({
value: value,
});
},
handleApply: function() {
const { lowerBound, upperBound } = this.state;
this.setState({ value: [lowerBound, upperBound]});
},
render: function() {
return (
<div style={style}>
<Slider range vertical allowCross={false} value={this.state.value} onChange={this.onSliderChange} />
<label>LowerBound: </label>
<input type="number" value={this.state.lowerBound} onChange={this.onLowerBoundChange} />
<br />
<label>UpperBound: </label>
<input type="number" value={this.state.upperBound} onChange={this.onUpperBoundChange} />
<br />
<button onClick={this.handleApply}>Apply</button>
</div>
);
},
});
const DynamicBounds = React.createClass({
getInitialState() {
return {
min: 0,
max: 100,
};
},
onSliderChange: function(value) {
log(value);
},
onMinChange: function(e) {
this.setState({
min: +e.target.value || 0,
});
},
onMaxChange: function(e) {
this.setState({
max: +e.target.value || 100,
});
},
render: function() {
return (
<div style={style}>
<Slider range vertical defaultValue={[20, 50]} min={this.state.min} max={this.state.max} onChange={this.onSliderChange} />
<label>Min: </label>
<input type="number" value={this.state.min} onChange={this.onMinChange} />
<br />
<label>Max: </label>
<input type="number" value={this.state.max} onChange={this.onMaxChange} />
</div>
);
},
});
ReactDOM.render(
<div style={parentStyle}>
<div style={style}>
<p>Basic Range`allowCross=false`</p>
<Slider range vertical allowCross={false} defaultValue={[0, 20]} onChange={log} />
</div>
<div style={style}>
<p>Basic Range`step=20` </p>
<Slider range vertical step={20} defaultValue={[20, 40]} onBeforeChange={log} />
</div>
<div style={style}>
<p>Basic Range`step=20, dots` </p>
<Slider range vertical dots step={20} defaultValue={[20, 40]} onAfterChange={log} />
</div>
<div style={style}>
<p>Controlled Range</p>
<Slider range vertical value={[20, 40]} />
</div>
<div style={style}>
<p>Customized Range</p>
<CustomizedRange />
</div>
<div style={style}>
<p>Range with dynamic `max` `min`</p>
<DynamicBounds />
</div>
</div>
, document.getElementById('__react-content'));
+1
View File
@@ -0,0 +1 @@
placeholder
+106
View File
@@ -0,0 +1,106 @@
/* eslint react/no-multi-comp: 0 */
require('rc-slider/assets/index.less');
const React = require('react');
const ReactDOM = require('react-dom');
const Slider = require('rc-slider');
const style = {float: 'left', width: 200, height: 400, marginBottom: 160, marginLeft: 50};
const parentStyle = {overflow: 'hidden'};
function log(value) {
console.log(value);
}
function percentFormatter(v) {
return v + ' %';
}
const CustomizedSlider = React.createClass({
getInitialState: function() {
return {
value: 50,
};
},
onSliderChange: function(value) {
log(value);
this.setState({
value: value,
});
},
render: function() {
return <Slider vertical value={this.state.value} onChange={this.onSliderChange} />;
},
});
const DynamicBounds = React.createClass({
getInitialState: function() {
return {
min: 0,
max: 100,
};
},
onSliderChange: function(value) {
log(value);
},
onMinChange: function(e) {
this.setState({
min: +e.target.value || 0,
});
},
onMaxChange: function(e) {
this.setState({
max: +e.target.value || 100,
});
},
render: function() {
return (
<div style={style}>
<p>Slider with dynamic `min` `max`</p>
<Slider vertical defaultValue={50} min={this.state.min} max={this.state.max} onChange={this.onSliderChange} />
<label>Min: </label>
<input type="number" value={this.state.min} onChange={this.onMinChange} />
<br />
<label>Max: </label>
<input type="number" value={this.state.max} onChange={this.onMaxChange} />
</div>
);
},
});
ReactDOM.render(
<div style={parentStyle}>
<div style={style}>
<p>Basic Slider</p>
<Slider vertical tipTransitionName="rc-slider-tooltip-zoom-down" onChange={log} />
</div>
<div style={style}>
<p>Basic Slider`step=20`</p>
<Slider vertical step={20} defaultValue={50} onBeforeChange={log} />
</div>
<div style={style}>
<p>Basic Slider`step=20, dots`</p>
<Slider vertical dots step={20} defaultValue={100} onAfterChange={log} />
</div>
<div style={style}>
<p>Basic Slider with `tipFormatter`</p>
<Slider vertical tipFormatter={percentFormatter} tipTransitionName="rc-slider-tooltip-zoom-down" onChange={log} />
</div>
<div style={style}>
<p>Basic Slider without tooltip</p>
<Slider vertical tipFormatter={null} onChange={log} />
</div>
<div style={style}>
<p>Controlled Slider</p>
<Slider vertical value={50} />
</div>
<div style={style}>
<p>Customized Slider</p>
<CustomizedSlider />
</div>
<div>
<DynamicBounds />
</div>
</div>
, document.getElementById('__react-content'));
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "rc-slider",
"version": "3.3.2",
"version": "3.6.2",
"description": "slider ui component for react",
"keywords": [
"react",
@@ -51,8 +51,8 @@
],
"dependencies": {
"classnames": "^2.2.1",
"object-assign": "^4.0.1",
"rc-tooltip": "3.x",
"rc-util": "3.x"
"rc-util": "3.x",
"warning": "^2.1.0"
}
}
+3 -2
View File
@@ -24,10 +24,10 @@ export default class Handle extends React.Component {
render() {
const props = this.props;
const {className, tipTransitionName, tipFormatter, offset, value} = props;
const {className, tipTransitionName, tipFormatter, vertical, offset, value} = props;
const {dragging, noTip} = props;
const style = { left: offset + '%' };
const style = vertical ? { bottom: offset + '%' } : { left: offset + '%' };
const handle = (<div className={className} style={style}
onMouseUp={this.showTooltip.bind(this)}
onMouseEnter={this.showTooltip.bind(this)}
@@ -52,6 +52,7 @@ export default class Handle extends React.Component {
Handle.propTypes = {
className: React.PropTypes.string,
vertical: React.PropTypes.bool,
offset: React.PropTypes.number,
tipTransitionName: React.PropTypes.string,
tipFormatter: React.PropTypes.func,
+23 -6
View File
@@ -1,14 +1,14 @@
import React from 'react';
import classNames from 'classnames';
const Marks = ({className, marks, included, upperBound, lowerBound, max, min}) => {
const Marks = ({className, vertical, marks, included, upperBound, lowerBound, max, min}) => {
const marksKeys = Object.keys(marks);
const marksCount = marksKeys.length;
const unit = 100 / (marksCount - 1);
const markWidth = unit * 0.9;
const range = max - min;
const elements = marksKeys.map(parseFloat).map((point) => {
const elements = marksKeys.map(parseFloat).sort((a, b) => a - b).map((point) => {
const isActived = (!included && point === upperBound) ||
(included && point <= upperBound && point >= lowerBound);
const markClassName = classNames({
@@ -16,11 +16,28 @@ const Marks = ({className, marks, included, upperBound, lowerBound, max, min}) =
[className + '-text-active']: isActived,
});
const style = { width: markWidth + '%' };
style.left = (point - min) / range * 100 - markWidth / 2 + '%';
const bottomStyle = {
// height: markWidth + '%',
marginBottom: '-200' + '%',
bottom: (point - min) / range * 100 + '%',
};
return (<span className={markClassName} style={style} key={point}>
{marks[point]}
const leftStyle = {
width: markWidth + '%',
marginLeft: -markWidth / 2 + '%',
left: (point - min) / range * 100 + '%',
};
const style = vertical ? bottomStyle : leftStyle;
const markPoint = marks[point];
const markPointIsObject = typeof markPoint === 'object' &&
!React.isValidElement(markPoint);
const markLabel = markPointIsObject ? markPoint.label : markPoint;
const markStyle = markPointIsObject ?
{ ...style, ...markPoint.style } : style;
return (<span className={markClassName} style={markStyle} key={point}>
{markLabel}
</span>);
});
+32 -34
View File
@@ -1,10 +1,9 @@
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';
import Steps from './Steps';
import Marks from './Marks';
function noop() {
@@ -14,12 +13,12 @@ function isNotTouchEvent(e) {
return e.touches.length > 1 || (e.type.toLowerCase() === 'touchend' && e.touches.length > 0);
}
function getTouchPosition(e) {
return e.touches[0].pageX;
function getTouchPosition(vertical, e) {
return vertical ? e.touches[0].clientY : e.touches[0].pageX;
}
function getMousePosition(e) {
return e.pageX;
function getMousePosition(vertical, e) {
return vertical ? e.clientY : e.pageX;
}
function pauseEvent(e) {
@@ -47,12 +46,7 @@ class Slider extends React.Component {
let recent;
if (props.range && upperBound === lowerBound) {
if (lowerBound === max) {
recent = 'lowerBound';
}
if (upperBound === min) {
recent = 'upperBound';
}
recent = lowerBound === max ? 'lowerBound' : 'upperBound';
} else {
recent = 'upperBound';
}
@@ -108,13 +102,13 @@ class Slider extends React.Component {
this.setState({handle: state.handle});
}
const data = objectAssign({}, this.state, state);
const data = {...this.state, ...state};
const changedValue = props.range ? [data.lowerBound, data.upperBound] : data.upperBound;
props.onChange(changedValue);
}
onMouseMove(e) {
const position = getMousePosition(e);
const position = getMousePosition(this.props.vertical, e);
this.onMove(e, position);
}
@@ -124,7 +118,7 @@ class Slider extends React.Component {
return;
}
const position = getTouchPosition(e);
const position = getTouchPosition(this.props.vertical, e);
this.onMove(e, position);
}
@@ -133,7 +127,8 @@ class Slider extends React.Component {
const props = this.props;
const state = this.state;
const diffPosition = position - this.startPosition;
let diffPosition = position - this.startPosition;
diffPosition = this.props.vertical ? -diffPosition : diffPosition;
const diffValue = diffPosition / this.getSliderLength() * (props.max - props.min);
const value = this.trimAlignValue(this.startValue + diffValue);
@@ -165,14 +160,14 @@ class Slider extends React.Component {
onTouchStart(e) {
if (isNotTouchEvent(e)) return;
const position = getTouchPosition(e);
const position = getTouchPosition(this.props.vertical, e);
this.onStart(position);
this.addDocumentEvents('touch');
pauseEvent(e);
}
onMouseDown(e) {
const position = getMousePosition(e);
const position = getMousePosition(this.props.vertical, e);
this.onStart(position);
this.addDocumentEvents('mouse');
pauseEvent(e);
@@ -230,19 +225,18 @@ class Slider extends React.Component {
return 0;
}
return slider.clientWidth;
return this.props.vertical ? slider.clientHeight : slider.clientWidth;
}
getSliderStart() {
const slider = this.refs.slider;
const rect = slider.getBoundingClientRect();
return rect.left;
return this.props.vertical ? rect.top : rect.left;
}
getPrecision() {
const props = this.props;
const stepString = props.step.toString();
getPrecision(step) {
const stepString = step.toString();
let precision = 0;
if (stepString.indexOf('.') >= 0) {
precision = stepString.length - stepString.indexOf('.') - 1;
@@ -257,7 +251,7 @@ class Slider extends React.Component {
trimAlignValue(v, nextProps) {
const state = this.state || {};
const {handle, lowerBound, upperBound} = state;
const {marks, step, min, max, allowCross} = objectAssign({}, this.props, nextProps || {});
const {marks, step, min, max, allowCross} = {...this.props, ...(nextProps || {})};
let val = v;
if (val <= min) {
@@ -282,7 +276,7 @@ class Slider extends React.Component {
const diffs = points.map((point) => Math.abs(val - point));
const closestPoint = points[diffs.indexOf(Math.min.apply(Math, diffs))];
return step !== null ? parseFloat(closestPoint.toFixed(this.getPrecision())) : closestPoint;
return step !== null ? parseFloat(closestPoint.toFixed(this.getPrecision(step))) : closestPoint;
}
calcOffset(value) {
@@ -292,9 +286,10 @@ class Slider extends React.Component {
}
calcValue(offset) {
const {min, max} = this.props;
const ratio = offset / this.getSliderLength();
return ratio * (max - min) + min;
const {vertical, min, max} = this.props;
const ratio = Math.abs(offset / this.getSliderLength());
const value = vertical ? (1 - ratio) * (max - min) + min : ratio * (max - min) + min;
return value;
}
calcValueByPos(position) {
@@ -332,7 +327,7 @@ class Slider extends React.Component {
render() {
const {handle, upperBound, lowerBound} = this.state;
const {className, prefixCls, disabled, dots, included, range, step,
const {className, prefixCls, disabled, vertical, dots, included, range, step,
marks, max, min, tipTransitionName, tipFormatter, children} = this.props;
const upperOffset = this.calcOffset(upperBound);
@@ -343,19 +338,20 @@ class Slider extends React.Component {
const upper = (<Handle className={handleClassName}
noTip={isNoTip} tipTransitionName={tipTransitionName} tipFormatter={tipFormatter}
offset={upperOffset} value={upperBound} dragging={handle === 'upperBound'}/>);
vertical = {vertical} offset={upperOffset} value={upperBound} dragging={handle === 'upperBound'}/>);
let lower = null;
if (range) {
lower = (<Handle className={handleClassName}
noTip={isNoTip} tipTransitionName={tipTransitionName} tipFormatter={tipFormatter}
offset={lowerOffset} value={lowerBound} dragging={handle === 'lowerBound'}/>);
vertical = {vertical} offset={lowerOffset} value={lowerBound} dragging={handle === 'lowerBound'}/>);
}
const sliderClassName = classNames({
[prefixCls]: true,
[prefixCls + '-disabled']: disabled,
[className]: !!className,
[prefixCls + '-vertical']: this.props.vertical,
});
const isIncluded = included || range;
return (
@@ -364,12 +360,12 @@ class Slider extends React.Component {
onMouseDown={disabled ? noop : this.onMouseDown.bind(this)}>
{upper}
{lower}
<Track className={prefixCls + '-track'} included={isIncluded}
<Track className={prefixCls + '-track'} vertical = {vertical} included={isIncluded}
offset={lowerOffset} length={upperOffset - lowerOffset}/>
<Dots prefixCls={prefixCls} marks={marks} dots={dots} step={step}
<Steps prefixCls={prefixCls} vertical = {vertical} marks={marks} dots={dots} step={step}
included={isIncluded} lowerBound={lowerBound}
upperBound={upperBound} max={max} min={min}/>
<Marks className={prefixCls + '-mark'} marks={marks}
<Marks className={prefixCls + '-mark'} vertical = {vertical} marks={marks}
included={isIncluded} lowerBound={lowerBound}
upperBound={upperBound} max={max} min={min}/>
{children}
@@ -403,6 +399,7 @@ Slider.propTypes = {
tipFormatter: React.PropTypes.func,
dots: React.PropTypes.bool,
range: React.PropTypes.bool,
vertical: React.PropTypes.bool,
allowCross: React.PropTypes.bool,
};
@@ -422,6 +419,7 @@ Slider.defaultProps = {
disabled: false,
dots: false,
range: false,
vertical: false,
allowCross: true,
};
+9 -6
View File
@@ -1,7 +1,9 @@
import React from 'react';
import classNames from 'classnames';
import warning from 'warning';
function calcPoints(marks, dots, step, min, max) {
function calcPoints(vertical, marks, dots, step, min, max) {
warning(dots ? step > 0 : true, '`Slider[step]` should be a positive number in order to make Slider[dots] work.');
const points = Object.keys(marks).map(parseFloat);
if (dots) {
for (let i = min; i <= max; i = i + step) {
@@ -12,11 +14,12 @@ function calcPoints(marks, dots, step, min, max) {
return points;
}
const Dots = ({prefixCls, marks, dots, step, included, lowerBound, upperBound, max, min}) => {
const Steps = ({prefixCls, vertical, marks, dots, step, included,
lowerBound, upperBound, max, min}) => {
const range = max - min;
const elements = calcPoints(marks, dots, step, min, max).map((point) => {
const offset = (point - min) / range * 100 + '%';
const style = { left: offset };
const elements = calcPoints(vertical, marks, dots, step, min, max).map((point) => {
const offset = Math.abs(point - min) / range * 100 + '%';
const style = vertical ? { bottom: offset } : { left: offset };
const isActived = (!included && point === upperBound) ||
(included && point <= upperBound && point >= lowerBound);
@@ -31,4 +34,4 @@ const Dots = ({prefixCls, marks, dots, step, included, lowerBound, upperBound, m
return <div className={prefixCls + '-step'}>{elements}</div>;
};
export default Dots;
export default Steps;
+8 -3
View File
@@ -1,11 +1,16 @@
import React from 'react';
const Track = ({className, included, offset, length}) => {
const Track = ({className, included, vertical, offset, length}) => {
const style = {
left: offset + '%',
width: length + '%',
visibility: included ? 'visible' : 'hidden',
};
if (vertical) {
style.bottom = offset + '%';
style.height = length + '%';
} else {
style.left = offset + '%';
style.width = length + '%';
}
return <div className={className} style={style} />;
};
+6 -1
View File
@@ -6,7 +6,7 @@ const Slider = require('..');
require('../assets/index.less');
describe('rc-slider', function() {
describe('rc-slider', function test() {
this.timeout(5000);
const div = document.createElement('div');
document.body.appendChild(div);
@@ -140,4 +140,9 @@ describe('rc-slider', function() {
expect(range.state.upperBound).to.be(90);
ReactDOM.unmountComponentAtNode(div);
});
it('should render a vertical slider, when `vertical` is true', () => {
const slider = ReactDOM.render(<Slider vertical />, div);
expect(ReactTestUtils.scryRenderedDOMComponentsWithClass(slider, 'rc-slider-vertical').length).to.be(1);
});
});