diff --git a/README.md b/README.md
index 5669d94..e462d68 100644
--- a/README.md
+++ b/README.md
@@ -50,9 +50,10 @@ slider ui component for react
## Usage
```js
-var Rcslider = require('rc-slider');
var React = require('react');
-React.render(, container);
+var ReactDOM = require('react-dom');
+var Rcslider = require('rc-slider');
+ReactDOM.render(, container);
```
## API
diff --git a/examples/simple.js b/examples/simple.js
index c0d47fc..6ebfa54 100644
--- a/examples/simple.js
+++ b/examples/simple.js
@@ -2,8 +2,8 @@
require('rc-slider/assets/index.less');
-var Slider = require('rc-slider');
var React = require('react');
+var Slider = require('rc-slider');
function onChange(v) {
console.log(v);
diff --git a/package.json b/package.json
index da4079a..ab705d4 100644
--- a/package.json
+++ b/package.json
@@ -39,11 +39,13 @@
},
"devDependencies": {
"expect.js": "0.3.x",
+ "jquery": "^1.11.2",
"precommit-hook": "^1.0.7",
"rc-server": "3.x",
"rc-tools": "4.x",
- "react": "^0.13.x",
- "jquery": "^1.11.2"
+ "react": "~0.14.0",
+ "react-addons-test-utils": "^0.14.0",
+ "react-dom": "~0.14.0"
},
"precommit": [
"lint"
diff --git a/src/Handle.jsx b/src/Handle.jsx
new file mode 100644
index 0000000..98b968b
--- /dev/null
+++ b/src/Handle.jsx
@@ -0,0 +1,60 @@
+import React from 'react';
+import Tooltip from 'rc-tooltip';
+
+export default class Handle extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ isTooltipVisible: false,
+ };
+ }
+
+ render() {
+ const props = this.props;
+ const {className, prefixCls, offset, tipTransitionName, value} = props;
+ const {dragging, noTip} = props;
+
+ const style = { left: offset + '%' };
+ const handle = (
);
+
+ if (noTip) {
+ return handle;
+ }
+
+ const isTooltipVisible = dragging || this.state.isTooltipVisible;
+ return (
{value}}
+ delay={0}
+ transitionName={tipTransitionName}>
+ {handle}
+ );
+ }
+
+ showTooltip() {
+ this.setState({
+ isTooltipVisible: true,
+ });
+ }
+ hideTooltip() {
+ this.setState({
+ isTooltipVisible: false,
+ });
+ }
+}
+
+Handle.propTypes = {
+ className: React.PropTypes.string,
+ prefixCls: React.PropTypes.string,
+ offset: React.PropTypes.number,
+ tipTransitionName: React.PropTypes.string,
+ value: React.PropTypes.number,
+ dragging: React.PropTypes.bool,
+ noTip: React.PropTypes.bool,
+};
diff --git a/src/Marks.jsx b/src/Marks.jsx
new file mode 100644
index 0000000..d4afefa
--- /dev/null
+++ b/src/Marks.jsx
@@ -0,0 +1,35 @@
+import React from 'react';
+import rcUtil from 'rc-util';
+
+const Marks = ({className, marks, index, isIncluded}) => {
+ const marksLen = marks.length;
+ const unit = 100 / (marksLen - 1);
+ const markWidth = unit / 2 + '%';
+
+ const elements = [];
+ for (let i = 0; i < marksLen; i++) {
+ const isActived = (isIncluded && i <= index) || (!isIncluded && i === index);
+ const markClassName = rcUtil.classSet({
+ [className + '-text']: true,
+ [className + '-text-active']: isActived,
+ });
+
+ const style = { width: markWidth };
+ const offset = unit * i;
+ if (i === marksLen - 1) {
+ style.right = -unit / 4 + '%';
+ } else {
+ style.left = (i > 0 ? offset - unit / 4 : -unit / 4) + '%';
+ }
+
+ elements.push(
+ {marks[i]}
+ );
+ }
+
+ return (
+ {elements}
+
);
+};
+
+export default Marks;
diff --git a/src/Slider.jsx b/src/Slider.jsx
index cb1d452..f093049 100644
--- a/src/Slider.jsx
+++ b/src/Slider.jsx
@@ -1,6 +1,9 @@
import React from 'react';
-import Tooltip from 'rc-tooltip';
import rcUtil, {Dom as DomUtils} from 'rc-util';
+import Track from './Track';
+import Handle from './Handle';
+import Steps from './Steps';
+import Marks from './Marks';
function noop() {
}
@@ -16,12 +19,6 @@ function pauseEvent(e) {
}
}
-function prefixClsFn(prefixCls, ...args) {
- return args.map((s)=> {
- return prefixCls + '-' + s;
- }).join(' ');
-}
-
function getValueFromIndex(props) {
let value;
const marksLen = props.marks.length;
@@ -90,7 +87,6 @@ const Slider = React.createClass({
}
return {
dragging: false,
- showTooltip: false,
value: value,
};
},
@@ -107,14 +103,8 @@ const Slider = React.createClass({
}
},
- onMouseUp(e) {
- const m = e.target;
- const handleDom = React.findDOMNode(this.refs.handle);
- let showToolTip = false;
- if (m === handleDom) {
- showToolTip = true;
- }
- this._end('mouse', showToolTip);
+ onMouseUp() {
+ this._end('mouse');
},
onTouchUp() {
@@ -197,201 +187,70 @@ const Slider = React.createClass({
return 0;
}
- return slider.getDOMNode().clientWidth;
+ return slider.clientWidth;
},
getSliderStart() {
- const slider = this.refs.slider.getDOMNode();
+ const slider = this.refs.slider;
const rect = slider.getBoundingClientRect();
return rect.left;
},
- renderSteps() {
- const props = this.props;
- const marksLen = props.marks.length;
- const withDots = props.withDots;
-
- if (marksLen || withDots) {
- const stepNum = marksLen ? marksLen : Math.floor((props.max - props.min) / props.step) + 1;
- const unit = 100 / (stepNum - 1);
-
- const prefixCls = props.prefixCls;
- const stepClassName = prefixClsFn(prefixCls, 'step');
-
- const elements = [];
- for (let i = 0; i < stepNum; i++) {
- const offset = unit * i + '%';
- const style = {
- left: offset,
- };
- let className = prefixClsFn(prefixCls, 'dot');
- if (props.isIncluded) {
- if (i <= this.getIndex()) {
- className = prefixClsFn(prefixCls, 'dot', 'dot-active');
- }
- } else {
- className = (i === this.getIndex()) ? prefixClsFn(prefixCls, 'dot', 'dot-active') : className;
- }
-
- elements[i] = (
-
- );
- }
-
- return (
-
- {elements}
-
- );
- }
-
- return null;
- },
-
- renderMark(i) {
- const marks = this.props.marks;
- const marksLen = marks.length;
- const unit = 100 / (marksLen - 1);
- const offset = unit * i;
-
- const style = {
- width: unit / 2 + '%',
- };
-
- if (i === marksLen - 1) {
- style.right = -unit / 4 + '%';
- } else {
- style.left = i > 0 ? offset - unit / 4 + '%' : -unit / 4 + '%';
- }
-
- const prefixCls = this.props.prefixCls;
- let className = prefixClsFn(prefixCls, 'mark-text');
-
- if (this.props.isIncluded) {
- if (i <= this.getIndex()) {
- className = prefixClsFn(prefixCls, 'mark-text', 'mark-text-active');
- }
- } else {
- className = (i === this.getIndex()) ? prefixClsFn(prefixCls, 'mark-text', 'mark-text-active') : className;
- }
-
- return (
-
{this.props.marks[i]}
- );
- },
-
- renderMarks() {
- const marks = this.props.marks;
- const marksLen = marks.length;
- const elements = [];
- for (let i = 0; i < marksLen; i++) {
- elements[i] = this.renderMark(i);
- }
-
- const prefixCls = this.props.prefixCls;
- const className = prefixClsFn(prefixCls, 'mark');
-
- return (
-
- {elements}
-
- );
- },
-
- renderHandler(offset) {
- const onStyle = {
- left: offset,
- };
-
- const prefixCls = this.props.prefixCls;
- const className = prefixClsFn(prefixCls, 'handle');
-
- let events = {};
-
- let tooltipVisible;
-
- if (this.state.dragging) {
- tooltipVisible = true;
- } else {
- events = {
- onClick: this.showTooltip.bind(this, true),
- onMouseEnter: this.showTooltip.bind(this, true),
- onMouseLeave: this.showTooltip.bind(this, false),
- };
- tooltipVisible = this.state.showTooltip;
- }
-
- const handle = (
);
-
- if (this.props.marks.length > 0) {
- return handle;
- }
- return (
-
{this.state.value}}
- delay={0}
- transitionName={this.props.tipTransitionName}
- prefixCls={prefixClsFn(prefixCls, 'tooltip')}>
- {handle}
-
- );
- },
-
- renderTrack(offset) {
- const style = {
- width: offset,
- };
-
- const prefixCls = this.props.prefixCls;
- const trackClassName = prefixClsFn(prefixCls, 'track');
-
- return (
-
- );
- },
-
render() {
const state = this.state;
+ const {value, dragging} = state;
const props = this.props;
- const value = state.value;
+ const {className, prefixCls, disabled, isIncluded, withDots} = props;
+ const {marks, step, max, min, tipTransitionName, children} = props;
+ const marksLen = marks.length;
+
+ const sliderClassName = rcUtil.classSet({
+ [prefixCls]: true,
+ [prefixCls + '-disabled']: disabled,
+ [className]: !!className,
+ });
+
const offset = this._calcOffset(value);
- const track = this.props.isIncluded ? this.renderTrack(offset) : null;
- const ons = this.renderHandler(offset);
- const steps = (props.step > 1 || props.marks.length > 0) ? this.renderSteps() : null;
- const sliderMarks = (props.marks.length > 0) ? this.renderMarks() : null;
- const prefixCls = props.prefixCls;
- const disabled = props.disabled;
- const sliderClassName = {
- [prefixCls]: 1,
- [props.className]: !!props.className,
- [`${prefixCls}-disabled`]: disabled,
- };
+
+ let track = null;
+ if (isIncluded) {
+ const trackClassName = prefixCls + '-track';
+ track =
;
+ }
+
+ const handleClassName = prefixCls + '-handle';
+
+ let steps = null;
+ if (marksLen > 0 || (step > 1 && withDots)) {
+ const stepsClassName = prefixCls + '-step';
+ const stepNum = marksLen > 0 ? marksLen : Math.floor((max - min) / step) + 1;
+ steps = (
);
+ }
+
+ let mark = null;
+ if (marksLen > 0) {
+ const markClassName = prefixCls + '-mark';
+ mark = (
);
+ }
return (
-
{track}
- {ons}
+ 0} />
{steps}
- {sliderMarks}
- {this.props.children}
+ {mark}
+ {children}
);
},
- showTooltip(show) {
- this.setState({
- showTooltip: show,
- });
- },
-
_trimAlignValue(v, propsArg) {
let val = v;
const props = propsArg || this.props;
@@ -416,7 +275,7 @@ const Slider = React.createClass({
_calcOffset(value) {
const ratio = (value - this.props.min) / (this.props.max - this.props.min);
- return ratio * 100 + '%';
+ return ratio * 100;
},
_calcValue(offset) {
@@ -485,12 +344,11 @@ const Slider = React.createClass({
});
},
- _end(type, showToolTip) {
+ _end(type) {
this._removeEventons(type);
this._triggerEvents('onAfterChange');
this.setState({
dragging: false,
- showTooltip: !!showToolTip,
});
},
});
diff --git a/src/Steps.jsx b/src/Steps.jsx
new file mode 100644
index 0000000..dc49d2d
--- /dev/null
+++ b/src/Steps.jsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import rcUtil from 'rc-util';
+
+const Steps = ({className, stepNum, isIncluded, index}) => {
+ const dotClassName = className.replace('step', 'dot');
+ const unit = 100 / (stepNum - 1);
+
+ const elements = [];
+ for (let i = 0; i < stepNum; i++) {
+ const offset = unit * i + '%';
+ const style = { left: offset };
+
+ const isActived = (isIncluded && i <= index) || (!isIncluded && i === index);
+ const stepClassName = rcUtil.classSet({
+ [dotClassName]: true,
+ [dotClassName + '-active']: isActived,
+ });
+
+ elements.push(
);
+ }
+
+ return (
+ {elements}
+
);
+};
+
+export default Steps;
diff --git a/src/Track.jsx b/src/Track.jsx
new file mode 100644
index 0000000..fb1cdf2
--- /dev/null
+++ b/src/Track.jsx
@@ -0,0 +1,11 @@
+import React from 'react';
+
+const Track = ({className, offset, length}) => {
+ const style = {
+ left: offset + '%',
+ width: length + '%',
+ };
+ return
;
+};
+
+export default Track;
diff --git a/tests/index.spec.js b/tests/index.spec.js
index 1ea2b4a..8c18335 100644
--- a/tests/index.spec.js
+++ b/tests/index.spec.js
@@ -1,8 +1,9 @@
var expect = require('expect.js');
var Slider = require('../index.js');
-var React = require('react/addons');
-var TestUtils = React.addons.TestUtils;
+var React = require('react');
+var ReactDOM = require('react-dom');
+var TestUtils = require('react-addons-test-utils');
var Simulate = TestUtils.Simulate;
var $ = require('jquery');
require('../assets/index.less');
@@ -17,7 +18,7 @@ describe('rc-slider', function () {
});
it('should render a simple slider with value correctly!', function () {
- var slider = React.render(
+ var slider = ReactDOM.render(
,
div
);
@@ -31,7 +32,7 @@ describe('rc-slider', function () {
});
it('should render a slider with correct numbers of step!', function () {
- var slider = React.render(
+ var slider = ReactDOM.render(
,
div
);
@@ -50,7 +51,7 @@ describe('rc-slider', function () {
});
it('should render a slider with marks correctly!', function () {
- var slider = React.render(
+ var slider = ReactDOM.render(
,
div
);
@@ -65,7 +66,7 @@ describe('rc-slider', function () {
});
// it('should mouseDown works!', function (done) {
- // var slider = React.render(
+ // var slider = ReactDOM.render(
// ,
// div
// );