rsuite
Version:
A suite of react components
378 lines (310 loc) • 11.3 kB
JavaScript
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import _extends from "@babel/runtime/helpers/esm/extends";
import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
import * as React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import _ from 'lodash';
import { DOMMouseMoveTracker, addStyle, getWidth as _getWidth, getHeight as _getHeight, getOffset } from 'dom-lib';
import { getUnhandledProps, defaultProps, prefix } from '../utils';
import Tooltip from '../Tooltip';
var Slider =
/*#__PURE__*/
function (_React$Component) {
_inheritsLoose(Slider, _React$Component);
function Slider(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.handleRef = void 0;
_this.barRef = void 0;
_this.mouseMoveTracker = null;
_this.handleClick = function (event) {
if (_this.props.disabled) {
return;
}
var _this$props = _this.props,
vertical = _this$props.vertical,
min = _this$props.min;
var barOffset = getOffset(_this.barRef.current);
var offset = vertical ? event.pageY - barOffset.top : event.pageX - barOffset.left;
_this.setValue(_this.calculateValue(offset) + min);
};
_this.handleMouseDown = function (event) {
if (_this.props.disabled) {
return;
}
_this.mouseMoveTracker = _this.getMouseMoveTracker();
_this.mouseMoveTracker.captureMouseMoves(event);
_this.setState({
handleDown: true
});
};
_this.handleMouseEnter = function () {
_this.setTooltipPosition();
};
_this.handleDragEnd = function () {
_this.releaseMouseMoves();
_this.setState({
handleDown: false
});
};
_this.handleDragMove = function (_deltaX, _deltaY, event) {
if (!_this.mouseMoveTracker || !_this.mouseMoveTracker.isDragging()) {
return;
}
var _this$props2 = _this.props,
vertical = _this$props2.vertical,
min = _this$props2.min;
var barOffset = getOffset(_this.barRef.current);
var offset = vertical ? event.pageY - barOffset.top : event.pageX - barOffset.left;
_this.setValue(_this.calculateValue(offset) + min);
_this.setTooltipPosition();
};
_this.releaseMouseMoves = function () {
if (_this.mouseMoveTracker) {
_this.mouseMoveTracker.releaseMouseMoves();
_this.mouseMoveTracker = null;
}
};
_this.addPrefix = function (name) {
return prefix(_this.props.classPrefix)(name);
};
_this.state = {
value: _this.checkValue(props.defaultValue, props)
};
_this.handleRef = React.createRef();
_this.barRef = React.createRef();
return _this;
}
var _proto = Slider.prototype;
_proto.componentWillUnmount = function componentWillUnmount() {
this.releaseMouseMoves();
};
_proto.getMouseMoveTracker = function getMouseMoveTracker() {
return this.mouseMoveTracker || new DOMMouseMoveTracker(this.handleDragMove, this.handleDragEnd, document.body);
};
_proto.getSplitCount = function getSplitCount() {
var _this$props3 = this.props,
min = _this$props3.min,
step = _this$props3.step;
var max = this.getMax();
return (max - min) / step;
};
_proto.getMax = function getMax(props) {
var _ref = props || this.props,
max = _ref.max,
min = _ref.min,
step = _ref.step;
return Math.floor((max - min) / step) * step + min;
};
_proto.getValue = function getValue() {
var value = this.props.value;
return typeof value === 'undefined' ? this.state.value : this.checkValue(value);
};
_proto.setValue = function setValue(value) {
var _this$props4 = this.props,
onChange = _this$props4.onChange,
min = _this$props4.min;
var max = this.getMax();
if (value < min) {
value = min;
}
if (value > max) {
value = max;
}
this.setState({
value: value
});
onChange && onChange(value);
};
_proto.setTooltipPosition = function setTooltipPosition() {
var tooltip = this.props.tooltip;
if (tooltip) {
var handle = this.handleRef.current;
var tip = handle.querySelector("." + this.addPrefix('tooltip'));
var width = _getWidth(tip);
addStyle(tip, 'left', "-" + width / 2 + "px");
}
};
_proto.checkValue = function checkValue(value, props) {
var _ref2 = props || this.props,
min = _ref2.min;
var max = this.getMax(props);
if (value < min) {
return min;
}
if (value > max) {
return max;
}
return value;
};
_proto.getHeight = function getHeight() {
if (this.barRef.current) {
return _getHeight(this.barRef.current);
}
return 0;
};
_proto.getWidth = function getWidth() {
if (this.barRef.current) {
return _getWidth(this.barRef.current);
}
return 0;
}
/**
* 通过偏移量计算值
* @param {number} offset 偏移量
*/
;
_proto.calculateValue = function calculateValue(offset) {
var _this$props5 = this.props,
step = _this$props5.step,
vertical = _this$props5.vertical;
var count = this.getSplitCount();
var value = 0;
if (isNaN(offset)) {
return value;
}
if (vertical) {
var barHeight = this.getHeight();
value = Math.round(offset / (barHeight / count)) * step;
} else {
var barWidth = this.getWidth();
value = Math.round(offset / (barWidth / count)) * step;
}
return value;
};
_proto.renderMark = function renderMark(mark, last) {
var _classNames;
var renderMark = this.props.renderMark;
var classes = classNames(this.addPrefix('mark'), (_classNames = {}, _classNames[this.addPrefix('last-mark')] = last, _classNames));
if (renderMark) {
return React.createElement("span", {
className: classes
}, React.createElement("span", {
className: this.addPrefix('mark-content')
}, renderMark(mark)));
}
return null;
};
_proto.renderGraduated = function renderGraduated() {
var _this$props6 = this.props,
step = _this$props6.step,
min = _this$props6.min;
var max = this.getMax();
var count = this.getSplitCount();
var value = this.getValue();
var graduatedItems = [];
var pass = value / step - min / step;
var active = Math.ceil((value - min) / (max - min) * count);
for (var i = 0; i < count; i += 1) {
var _classNames2;
var classes = classNames((_classNames2 = {}, _classNames2[this.addPrefix('pass')] = i <= pass, _classNames2[this.addPrefix('active')] = i === active, _classNames2));
var mark = i * step + min;
var last = i === count - 1;
graduatedItems.push(React.createElement("li", {
className: classes,
key: i
}, this.renderMark(mark), last && this.renderMark(max, true)));
}
return React.createElement("div", {
className: this.addPrefix('graduator')
}, React.createElement("ul", null, graduatedItems));
};
_proto.renderHanlde = function renderHanlde() {
var _extends2, _classNames3;
var _this$props7 = this.props,
handleClassName = _this$props7.handleClassName,
handleTitle = _this$props7.handleTitle,
min = _this$props7.min,
vertical = _this$props7.vertical,
tooltip = _this$props7.tooltip,
handleStyle = _this$props7.handleStyle,
renderTooltip = _this$props7.renderTooltip;
var max = this.getMax();
var handleDown = this.state.handleDown;
var value = this.getValue();
var direction = vertical ? 'top' : 'left';
var style = _extends({}, handleStyle, (_extends2 = {}, _extends2[direction] = (value - min) / (max - min) * 100 + "%", _extends2));
var handleClasses = classNames(this.addPrefix('handle'), handleClassName, (_classNames3 = {}, _classNames3[this.addPrefix('showtip')] = handleDown, _classNames3));
return React.createElement("div", {
className: handleClasses,
role: "presentation",
onMouseDown: this.handleMouseDown,
onMouseEnter: this.handleMouseEnter,
style: style,
ref: this.handleRef
}, tooltip && React.createElement(Tooltip, {
className: classNames(this.addPrefix('tooltip'), 'placement-top')
}, renderTooltip ? renderTooltip(value) : value), handleTitle);
};
_proto.renderProgress = function renderProgress() {
var _style;
var _this$props8 = this.props,
vertical = _this$props8.vertical,
min = _this$props8.min;
var max = this.getMax();
var value = this.getValue();
var key = vertical ? 'height' : 'width';
var style = (_style = {}, _style[key] = (value - min) / (max - min) * 100 + "%", _style);
return React.createElement("div", {
style: style,
className: this.addPrefix('progress-bar')
});
};
_proto.render = function render() {
var _classNames4;
var _this$props9 = this.props,
graduated = _this$props9.graduated,
className = _this$props9.className,
barClassName = _this$props9.barClassName,
progress = _this$props9.progress,
vertical = _this$props9.vertical,
disabled = _this$props9.disabled,
classPrefix = _this$props9.classPrefix,
renderMark = _this$props9.renderMark,
rest = _objectWithoutPropertiesLoose(_this$props9, ["graduated", "className", "barClassName", "progress", "vertical", "disabled", "classPrefix", "renderMark"]);
var handleDown = this.state.handleDown;
var classes = classNames(classPrefix, className, (_classNames4 = {}, _classNames4[this.addPrefix('vertical')] = vertical, _classNames4[this.addPrefix('disabled')] = disabled, _classNames4[this.addPrefix('graduated')] = graduated, _classNames4[this.addPrefix('dragging')] = handleDown, _classNames4[this.addPrefix('with-mark')] = _.isFunction(renderMark), _classNames4));
var unhandled = getUnhandledProps(Slider, rest);
return React.createElement("div", _extends({}, unhandled, {
className: classes,
onClick: this.handleClick,
role: "presentation"
}), React.createElement("div", {
className: classNames(this.addPrefix('bar'), barClassName),
ref: this.barRef
}, progress && this.renderProgress(), graduated && this.renderGraduated()), this.renderHanlde());
};
return Slider;
}(React.Component);
Slider.propTypes = {
min: PropTypes.number,
max: PropTypes.number,
step: PropTypes.number,
value: PropTypes.number,
defaultValue: PropTypes.number,
className: PropTypes.string,
classPrefix: PropTypes.string,
handleClassName: PropTypes.string,
handleTitle: PropTypes.node,
barClassName: PropTypes.string,
handleStyle: PropTypes.object,
disabled: PropTypes.bool,
graduated: PropTypes.bool,
tooltip: PropTypes.bool,
progress: PropTypes.bool,
vertical: PropTypes.bool,
onChange: PropTypes.func,
renderMark: PropTypes.func,
renderTooltip: PropTypes.func
};
Slider.defaultProps = {
min: 0,
max: 100,
step: 1,
defaultValue: 0,
tooltip: true
};
export default defaultProps({
classPrefix: 'slider'
})(Slider);