zent
Version:
一套前端设计语言和基于React的实现
314 lines (313 loc) • 13.9 kB
JavaScript
import { __assign, __extends } from "tslib";
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import cx from 'classnames';
import { Component, createRef } from 'react';
import getWidth from '../utils/getWidth';
import Point from './Point';
import Marks from './Marks';
import Dots from './Dots';
import { DisabledContext } from '../disabled';
import { getValue, toFixed, isLeftValue } from './common';
import NumberInput from '../number-input';
import { getPotentialValues, normalizeToPotentialValue } from './normalize';
import { WindowEventHandler } from '../utils/component/WindowEventHandler';
import withinRange from '../utils/withinRange';
export var getDecimal = function (step) {
var fixed = String(step).split('.')[1];
return fixed ? fixed.length : 0;
};
var getPosition = function (value, min, max) {
var pos = ((value - min) * 100) / (max - min);
return pos + "%";
};
function checkProps(props) {
var range = props.range, value = props.value, max = props.max, min = props.min, dots = props.dots, marks = props.marks;
if (range) {
if (!Array.isArray(value)) {
throw new Error('`value` must an array when `range` is true');
}
if (!(value.length === 2)) {
throw new Error("value's length must as 2 when `range` is true");
}
if (!value.every(function (v) { return typeof v === 'number' && v >= min && v <= max; })) {
throw new Error("value's each item must be a number and between min and max when `range` is true");
}
if (!(value[0] <= value[1])) {
throw new Error('value[0] must be less than value[1] when `range` is true');
}
}
else {
if (typeof value !== 'number') {
throw new Error('value must be an number when `range` is false');
}
if (value < min || value > max) {
throw new Error('value must between min and max when `range` is false');
}
}
if (dots) {
if (!marks) {
throw new Error('marks must be used with dots');
}
}
if (marks && Object.keys(marks).length < 2) {
throw new Error('at lease 2 marks needed');
}
}
var Slider = (function (_super) {
__extends(Slider, _super);
function Slider() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = {
decimal: getDecimal(_this.props.step),
potentialValues: getPotentialValues(_this.props.marks),
active: null,
prevProps: _this.props,
};
_this.containerRef = createRef();
_this.mouseDown = false;
_this.limit = null;
_this.isLeft = null;
_this.onSingleChange = function (value) {
if (_this.props.range !== false) {
return;
}
var _a = _this.props, onChange = _a.onChange, dots = _a.dots, disabled = _a.disabled;
var potentialValues = _this.state.potentialValues;
var newValue = Number(value);
if (dots) {
newValue = normalizeToPotentialValue(potentialValues, newValue);
}
!disabled && onChange && onChange(newValue);
};
_this.onLeftChange = function (value) {
if (_this.props.range !== true) {
return;
}
var _a = _this.props, _b = _a.value, prevValue = _b === void 0 ? [0, 0] : _b, onChange = _a.onChange, dots = _a.dots, disabled = _a.disabled;
var potentialValues = _this.state.potentialValues;
if (disabled || !onChange) {
return;
}
var newValue = Number(value);
if (dots) {
newValue = normalizeToPotentialValue(potentialValues, newValue);
}
var nextValue = newValue > prevValue[1]
? [prevValue[1], newValue]
: [newValue, prevValue[1]];
onChange(nextValue);
};
_this.onRightChange = function (value) {
if (_this.props.range !== true) {
return;
}
var _a = _this.props, _b = _a.value, prevValue = _b === void 0 ? [0, 0] : _b, onChange = _a.onChange, dots = _a.dots, disabled = _a.disabled;
var potentialValues = _this.state.potentialValues;
if (disabled || !onChange) {
return;
}
var newValue = Number(value);
if (dots) {
newValue = normalizeToPotentialValue(potentialValues, newValue);
}
var nextValue = newValue > prevValue[0]
? [prevValue[0], newValue]
: [newValue, prevValue[0]];
onChange(nextValue);
};
_this.onMouseDown = function (e) {
_this.mouseDown = true;
var value = _this.getValueFromEvent(e);
var _a = _this.props, min = _a.min, max = _a.max;
var nextValue = withinRange(value, min, max);
if (!_this.state.active) {
_this.setState({
active: 'point-single',
});
}
_this.onChange(nextValue);
};
_this.onWindowMouseUp = function () {
_this.mouseDown = false;
_this.limit = null;
_this.isLeft = null;
_this.setState({
active: null,
});
};
_this.onWindowMouseMove = function (e) {
if (!_this.mouseDown) {
return;
}
var nextValue = _this.getValueFromEvent(e);
if (_this.props.range) {
var _a = _this.props, value = _a.value, min = _a.min, max = _a.max;
var left = void 0;
if (value[0] === value[1]) {
left = e.movementX <= 0;
}
else {
left = isLeftValue(nextValue, value);
}
if (!_this.state.active) {
_this.setState({
active: left ? 'point-left' : 'point-right',
});
}
if (!_this.limit) {
_this.isLeft = left;
if (left) {
_this.limit = [min, value[1]];
}
else {
_this.limit = [value[0], max];
}
}
nextValue = withinRange(nextValue, _this.limit[0], _this.limit[1]);
}
else {
var _b = _this.props, min = _b.min, max = _b.max;
if (!_this.state.active) {
_this.setState({
active: 'point-single',
});
}
nextValue = withinRange(nextValue, min, max);
}
_this.onChange(nextValue);
};
return _this;
}
Slider.prototype.getComputedProps = function () {
var _a = this.props, _b = _a.disabled, disabled = _b === void 0 ? this.context.value : _b, min = _a.min, max = _a.max;
var decimal = this.state.decimal;
if (this.props.range !== false) {
var value = this.props.value;
var leftPosition = getPosition(value[0], min, max);
var leftProps = {
min: min,
max: value[1],
disabled: disabled,
decimal: decimal,
onChange: this.onLeftChange,
value: value[0],
position: leftPosition,
};
var rightProps = {
min: value[0],
max: max,
disabled: disabled,
decimal: decimal,
onChange: this.onRightChange,
value: value[1],
position: getPosition(value[1], min, max),
};
var width = (value[1] - value[0]) / (max - min);
return {
range: true,
leftProps: leftProps,
rightProps: rightProps,
trackStyle: {
left: leftPosition,
width: width * 100 + "%",
},
};
}
var position = getPosition(this.props.value, min, max);
return {
range: false,
props: {
min: min,
max: max,
disabled: disabled,
decimal: decimal,
onChange: this.onSingleChange,
value: this.props.value,
position: position,
},
trackStyle: {
left: 0,
width: position,
},
};
};
Slider.prototype.onChange = function (rawValue) {
var _a = this.props, dots = _a.dots, disabled = _a.disabled;
var _b = this.state, potentialValues = _b.potentialValues, decimal = _b.decimal;
if (disabled) {
return;
}
var nextValue = toFixed(rawValue, decimal);
if (dots) {
nextValue = normalizeToPotentialValue(potentialValues, nextValue);
}
if (this.props.range === true) {
var _c = this.props, onChange = _c.onChange, value = _c.value;
if (!onChange) {
return;
}
var isLeft = this.isLeft !== null ? this.isLeft : isLeftValue(rawValue, value);
if (isLeft) {
onChange([nextValue, value[1]]);
}
else {
onChange([value[0], nextValue]);
}
}
else {
var onChange = this.props.onChange;
onChange && onChange(nextValue);
}
};
Slider.prototype.getValueFromEvent = function (e) {
var _a = this.props, min = _a.min, max = _a.max;
var el = this.containerRef.current;
var ratio = (e.clientX - el.getBoundingClientRect().left) / el.clientWidth;
var nextValue = getValue(ratio, min, max);
return nextValue;
};
Slider.getDerivedStateFromProps = function (nextProps, _a) {
var prevProps = _a.prevProps;
if (nextProps === prevProps) {
return null;
}
var state = {
prevProps: nextProps,
};
if (prevProps.step !== nextProps.step) {
state.decimal = getDecimal(nextProps.step);
}
if (prevProps.marks !== nextProps.marks) {
state.potentialValues = getPotentialValues(nextProps.marks);
}
return state;
};
Slider.prototype.render = function () {
if (process.env.NODE_ENV !== 'production') {
checkProps(this.props);
}
var _a = this.props, withInput = _a.withInput, className = _a.className, width = _a.width, _b = _a.disabled, disabled = _b === void 0 ? this.context.value : _b, min = _a.min, max = _a.max, marks = _a.marks, dots = _a.dots;
var _c = this.state, potentialValues = _c.potentialValues, active = _c.active;
var computed = this.getComputedProps();
return (_jsxs("div", __assign({ className: cx('zent-slider', className, {
'zent-slider-disabled': disabled,
}), style: getWidth(width), "data-zv": '10.0.17' }, { children: [_jsxs("div", __assign({ ref: this.containerRef, className: "zent-slider-main", onMouseDown: this.onMouseDown, "data-zv": '10.0.17' }, { children: [_jsx("div", { style: computed.trackStyle, className: cx('zent-slider-track', {
'zent-slider-track-disabled': disabled,
}), "data-zv": '10.0.17' }, void 0), computed.range === true ? (_jsxs(_Fragment, { children: [_jsx(Point, { active: active === 'point-left', disabled: disabled, position: computed.leftProps.position, value: computed.leftProps.value }, "point-left"), _jsx(Point, { active: active === 'point-right', disabled: disabled, position: computed.rightProps.position, value: computed.rightProps.value }, "point-right")] }, void 0)) : (_jsx(Point, { active: active === 'point-single', disabled: disabled, position: computed.props.position, value: computed.props.value }, "point-single")), marks ? (_jsxs(_Fragment, { children: [_jsx(Marks, { marks: marks, min: min, max: max, potentialValues: potentialValues }, void 0), dots ? (_jsx(Dots, { marks: marks, min: min, max: max, activeLeft: this.props.range === true ? this.props.value[0] : 0, activeRight: this.props.range === true
? this.props.value[1]
: this.props.value, potentialValues: potentialValues, disabled: disabled }, void 0)) : null] }, void 0)) : null] }), void 0), withInput &&
!dots &&
(computed.range === true ? (_jsxs("div", __assign({ className: "zent-slider-input", "data-zv": '10.0.17' }, { children: [_jsx(NumberInput, __assign({}, computed.leftProps), "number-input-left"), _jsx("div", __assign({ className: "slider-input-line", "data-zv": '10.0.17' }, { children: "-" }), void 0), _jsx(NumberInput, __assign({}, computed.rightProps), "number-input-right")] }), void 0)) : (_jsx(NumberInput, __assign({ className: "zent-slider-input" }, computed.props), "number-input-single"))), _jsx(WindowEventHandler, { eventName: "mousemove", listener: this.onWindowMouseMove }, void 0), _jsx(WindowEventHandler, { eventName: "mouseup", listener: this.onWindowMouseUp }, void 0)] }), void 0));
};
Slider.defaultProps = {
min: 0,
max: 100,
step: 1,
withInput: true,
range: false,
value: 0,
};
Slider.contextType = DisabledContext;
return Slider;
}(Component));
export { Slider };