import React from 'react'; import Tooltip from 'rc-tooltip'; import rcUtil, {Dom as DomUtils} from 'rc-util'; function noop() { } function pauseEvent(e) { e.cancelBubble = true; e.returnValue = false; if (e.stopPropagation) { e.stopPropagation(); } if (e.preventDefault) { e.preventDefault(); } } function prefixClsFn(prefixCls, ...args) { return args.map((s)=> { return prefixCls + '-' + s; }).join(' '); } function getValueFromIndex(props) { let value; const marksLen = props.marks.length; let index; if ('index' in props) { index = props.index; } else { index = props.defaultIndex; } if (marksLen > 0) { value = ((props.max - props.min) / (marksLen - 1)) * (index); value = value.toFixed(5) / 1; } return value; } const Slider = React.createClass({ propTypes: { min: React.PropTypes.number, max: React.PropTypes.number, step: React.PropTypes.number, defaultValue: React.PropTypes.number, defaultIndex: React.PropTypes.number, value: React.PropTypes.number, index: React.PropTypes.number, marks: React.PropTypes.array, isIncluded: React.PropTypes.bool, className: React.PropTypes.string, prefixCls: React.PropTypes.string, disabled: React.PropTypes.bool, children: React.PropTypes.any, onBeforeChange: React.PropTypes.func, onChange: React.PropTypes.func, onAfterChange: React.PropTypes.func, tipTransitionName: React.PropTypes.string, }, getDefaultProps() { return { min: 0, max: 100, step: 1, defaultValue: 0, marks: [], isIncluded: true, className: '', prefixCls: 'rc-slider', disabled: false, defaultIndex: 0, tipTransitionName: '', }; }, getInitialState() { const props = this.props; let value = props.defaultValue; if ('value' in props) { value = props.value; } value = this._trimAlignValue(value); const marksLen = props.marks.length; if (marksLen > 0) { value = getValueFromIndex(props); } return { dragging: false, showTooltip: false, value: value, }; }, componentWillReceiveProps(nextProps) { if ('value' in nextProps) { this.setState({ value: nextProps.value, }); } else if ('index' in nextProps) { this.setState({ value: getValueFromIndex(nextProps), }); } }, 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); }, onTouchUp() { this._end('touch'); }, onMouseMove(e) { const position = e.pageX || (e.clientX + document.documentElement.scrollLeft); // to compat ie8 this.onMove(e, position); }, onTouchMove(e) { if (e.touches.length > 1 || (e.type === 'touchend' && e.touches.length > 0)) { this._end('touch'); return; } const position = this._getTouchPosition(e); this.onMove(e, position); }, onMove(e, position) { pauseEvent(e); const props = this.props; const state = this.state; let value = state.value; const oldValue = value; const diffPosition = position - this.startPosition; const diffValue = diffPosition / this.getSliderLength() * (props.max - props.min); value = this._trimAlignValue(this.startValue + diffValue); if (value !== oldValue && !('value' in props) && !('index' in props)) { this.setState({value: value}); } if (value !== oldValue) { this._triggerEvents('onChange', value); } }, onTouchStart(e) { if (e.touches.length > 1 || (e.type.toLowerCase() === 'touchend' && e.touches.length > 0)) { return; } const position = this._getTouchPosition(e); const value = this._calValueByPos(position); this._triggerEvents('onChange', value); this._start(position); this._addDocumentEvents('touch'); pauseEvent(e); }, onSliderMouseDown(e) { const position = e.pageX || (e.clientX + document.documentElement.scrollLeft); // to compat ie8 const value = this._calValueByPos(position); this._triggerEvents('onChange', value); this._start(position); this._addDocumentEvents('mouse'); pauseEvent(e); }, getIndex(v) { const props = this.props; const value = v === undefined ? this.state.value : v; if (props.marks.length === 0) { return Math.floor((value - props.min) / props.step); } const unit = ((props.max - props.min) / (props.marks.length - 1)).toFixed(5); return Math.round(value / unit); }, getSliderLength() { const slider = this.refs.slider; if (!slider) { return 0; } return slider.getDOMNode().clientWidth; }, getSliderStart() { const slider = this.refs.slider.getDOMNode(); const rect = slider.getBoundingClientRect(); return rect.left; }, renderSteps() { const props = this.props; const marksLen = props.marks.length; const stepNum = marksLen > 0 ? 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 (