"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper")); var _react = _interopRequireDefault(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _Track = _interopRequireDefault(require("./common/Track")); var _createSlider = _interopRequireDefault(require("./common/createSlider")); var utils = _interopRequireWildcard(require("./utils")); var _trimAlignValue = function trimAlignValue(_ref) { var value = _ref.value, handle = _ref.handle, bounds = _ref.bounds, props = _ref.props; var allowCross = props.allowCross, pushable = props.pushable; var thershold = Number(pushable); var valInRange = utils.ensureValueInRange(value, props); var valNotConflict = valInRange; if (!allowCross && handle != null && bounds !== undefined) { if (handle > 0 && valInRange <= bounds[handle - 1] + thershold) { valNotConflict = bounds[handle - 1] + thershold; } if (handle < bounds.length - 1 && valInRange >= bounds[handle + 1] - thershold) { valNotConflict = bounds[handle + 1] - thershold; } } return utils.ensureValuePrecision(valNotConflict, props); }; var Range = /*#__PURE__*/function (_React$Component) { (0, _inherits2.default)(Range, _React$Component); var _super = (0, _createSuper2.default)(Range); function Range(props) { var _this; (0, _classCallCheck2.default)(this, Range); _this = _super.call(this, props); _this.positionGetValue = function (position) { var bounds = _this.getValue(); var value = _this.calcValueByPos(position); var closestBound = _this.getClosestBound(value); var index = _this.getBoundNeedMoving(value, closestBound); var prevValue = bounds[index]; if (value === prevValue) return null; var nextBounds = (0, _toConsumableArray2.default)(bounds); nextBounds[index] = value; return nextBounds; }; _this.onEnd = function (force) { var handle = _this.state.handle; _this.removeDocumentEvents(); if (!handle) { _this.dragTrack = false; } if (handle !== null || force) { _this.props.onAfterChange(_this.getValue()); } _this.setState({ handle: null }); }; var count = props.count, min = props.min, max = props.max; var initialValue = Array.apply(void 0, (0, _toConsumableArray2.default)(Array(count + 1))).map(function () { return min; }); var defaultValue = 'defaultValue' in props ? props.defaultValue : initialValue; var value = props.value !== undefined ? props.value : defaultValue; var bounds = value.map(function (v, i) { return _trimAlignValue({ value: v, handle: i, props: props }); }); var recent = bounds[0] === max ? 0 : bounds.length - 1; _this.state = { handle: null, recent: recent, bounds: bounds }; return _this; } /** * [Legacy] Used for inherit other component. * It's a bad code style which should be refactor. */ /* eslint-disable @typescript-eslint/no-unused-vars, class-methods-use-this */ (0, _createClass2.default)(Range, [{ key: "calcValueByPos", value: function calcValueByPos(value) { return 0; } }, { key: "getSliderLength", value: function getSliderLength() { return 0; } }, { key: "calcOffset", value: function calcOffset(value) { return 0; } }, { key: "saveHandle", value: function saveHandle(index, h) {} }, { key: "removeDocumentEvents", value: function removeDocumentEvents() {} }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { var _this2 = this; var _this$props = this.props, onChange = _this$props.onChange, value = _this$props.value, min = _this$props.min, max = _this$props.max; if (!('min' in this.props || 'max' in this.props)) { return; } if (min === prevProps.min && max === prevProps.max) { return; } var currentValue = value || prevState.bounds; if (currentValue.some(function (v) { return utils.isValueOutOfRange(v, _this2.props); })) { var newValues = currentValue.map(function (v) { return utils.ensureValueInRange(v, _this2.props); }); onChange(newValues); } } }, { key: "onChange", value: function onChange(state) { var props = this.props; var isNotControlled = !('value' in props); if (isNotControlled) { this.setState(state); } else { var controlledState = {}; ['handle', 'recent'].forEach(function (item) { if (state[item] !== undefined) { controlledState[item] = state[item]; } }); if (Object.keys(controlledState).length) { this.setState(controlledState); } } var data = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, this.state), state); var changedValue = data.bounds; props.onChange(changedValue); } }, { key: "onStart", value: function onStart(position) { var props = this.props, state = this.state; var bounds = this.getValue(); props.onBeforeChange(bounds); var value = this.calcValueByPos(position); this.startValue = value; this.startPosition = position; var closestBound = this.getClosestBound(value); this.prevMovedHandleIndex = this.getBoundNeedMoving(value, closestBound); this.setState({ handle: this.prevMovedHandleIndex, recent: this.prevMovedHandleIndex }); var prevValue = bounds[this.prevMovedHandleIndex]; if (value === prevValue) return; var nextBounds = (0, _toConsumableArray2.default)(state.bounds); nextBounds[this.prevMovedHandleIndex] = value; this.onChange({ bounds: nextBounds }); } }, { key: "onMove", value: function onMove(e, position, dragTrack, startBounds) { utils.pauseEvent(e); var state = this.state, props = this.props; var maxValue = props.max || 100; var minValue = props.min || 0; if (dragTrack) { var pos = props.vertical ? -position : position; pos = props.reverse ? -pos : pos; var max = maxValue - Math.max.apply(Math, (0, _toConsumableArray2.default)(startBounds)); var min = minValue - Math.min.apply(Math, (0, _toConsumableArray2.default)(startBounds)); var ratio = Math.min(Math.max(pos / (this.getSliderLength() / (maxValue - minValue)), min), max); var nextBounds = startBounds.map(function (v) { return Math.floor(Math.max(Math.min(v + ratio, maxValue), minValue)); }); if (state.bounds.map(function (c, i) { return c === nextBounds[i]; }).some(function (c) { return !c; })) { this.onChange({ bounds: nextBounds }); } return; } var value = this.calcValueByPos(position); var oldValue = state.bounds[state.handle]; if (value === oldValue) return; this.moveTo(value); } }, { key: "onKeyboard", value: function onKeyboard(e) { var _this$props2 = this.props, reverse = _this$props2.reverse, vertical = _this$props2.vertical; var valueMutator = utils.getKeyboardValueMutator(e, vertical, reverse); if (valueMutator) { utils.pauseEvent(e); var state = this.state, props = this.props; var bounds = state.bounds, handle = state.handle; var oldValue = bounds[handle === null ? state.recent : handle]; var mutatedValue = valueMutator(oldValue, props); var value = _trimAlignValue({ value: mutatedValue, handle: handle, bounds: state.bounds, props: props }); if (value === oldValue) return; var isFromKeyboardEvent = true; this.moveTo(value, isFromKeyboardEvent); } } }, { key: "getValue", value: function getValue() { return this.state.bounds; } }, { key: "getClosestBound", value: function getClosestBound(value) { var bounds = this.state.bounds; var closestBound = 0; for (var i = 1; i < bounds.length - 1; i += 1) { if (value >= bounds[i]) { closestBound = i; } } if (Math.abs(bounds[closestBound + 1] - value) < Math.abs(bounds[closestBound] - value)) { closestBound += 1; } return closestBound; } }, { key: "getBoundNeedMoving", value: function getBoundNeedMoving(value, closestBound) { var _this$state = this.state, bounds = _this$state.bounds, recent = _this$state.recent; var boundNeedMoving = closestBound; var isAtTheSamePoint = bounds[closestBound + 1] === bounds[closestBound]; if (isAtTheSamePoint && bounds[recent] === bounds[closestBound]) { boundNeedMoving = recent; } if (isAtTheSamePoint && value !== bounds[closestBound + 1]) { boundNeedMoving = value < bounds[closestBound + 1] ? closestBound : closestBound + 1; } return boundNeedMoving; } }, { key: "getLowerBound", value: function getLowerBound() { return this.state.bounds[0]; } }, { key: "getUpperBound", value: function getUpperBound() { var bounds = this.state.bounds; return bounds[bounds.length - 1]; } /** * Returns an array of possible slider points, taking into account both * `marks` and `step`. The result is cached. */ }, { key: "getPoints", value: function getPoints() { var _this$props3 = this.props, marks = _this$props3.marks, step = _this$props3.step, min = _this$props3.min, max = _this$props3.max; var cache = this.internalPointsCache; if (!cache || cache.marks !== marks || cache.step !== step) { var pointsObject = (0, _objectSpread2.default)({}, marks); if (step !== null) { for (var point = min; point <= max; point += step) { pointsObject[point] = point; } } var points = Object.keys(pointsObject).map(parseFloat); points.sort(function (a, b) { return a - b; }); this.internalPointsCache = { marks: marks, step: step, points: points }; } return this.internalPointsCache.points; } }, { key: "moveTo", value: function moveTo(value, isFromKeyboardEvent) { var _this3 = this; var state = this.state, props = this.props; var nextBounds = (0, _toConsumableArray2.default)(state.bounds); var handle = state.handle === null ? state.recent : state.handle; nextBounds[handle] = value; var nextHandle = handle; if (props.pushable !== false) { this.pushSurroundingHandles(nextBounds, nextHandle); } else if (props.allowCross) { nextBounds.sort(function (a, b) { return a - b; }); nextHandle = nextBounds.indexOf(value); } this.onChange({ recent: nextHandle, handle: nextHandle, bounds: nextBounds }); if (isFromKeyboardEvent) { // known problem: because setState is async, // so trigger focus will invoke handler's onEnd and another handler's onStart too early, // cause onBeforeChange and onAfterChange receive wrong value. // here use setState callback to hack,but not elegant this.props.onAfterChange(nextBounds); this.setState({}, function () { _this3.handlesRefs[nextHandle].focus(); }); this.onEnd(); } } }, { key: "pushSurroundingHandles", value: function pushSurroundingHandles(bounds, handle) { var value = bounds[handle]; var pushable = this.props.pushable; var threshold = Number(pushable); var direction = 0; if (bounds[handle + 1] - value < threshold) { direction = +1; // push to right } if (value - bounds[handle - 1] < threshold) { direction = -1; // push to left } if (direction === 0) { return; } var nextHandle = handle + direction; var diffToNext = direction * (bounds[nextHandle] - value); if (!this.pushHandle(bounds, nextHandle, direction, threshold - diffToNext)) { // revert to original value if pushing is impossible // eslint-disable-next-line no-param-reassign bounds[handle] = bounds[nextHandle] - direction * threshold; } } }, { key: "pushHandle", value: function pushHandle(bounds, handle, direction, amount) { var originalValue = bounds[handle]; var currentValue = bounds[handle]; while (direction * (currentValue - originalValue) < amount) { if (!this.pushHandleOnePoint(bounds, handle, direction)) { // can't push handle enough to create the needed `amount` gap, so we // revert its position to the original value // eslint-disable-next-line no-param-reassign bounds[handle] = originalValue; return false; } currentValue = bounds[handle]; } // the handle was pushed enough to create the needed `amount` gap return true; } }, { key: "pushHandleOnePoint", value: function pushHandleOnePoint(bounds, handle, direction) { var points = this.getPoints(); var pointIndex = points.indexOf(bounds[handle]); var nextPointIndex = pointIndex + direction; if (nextPointIndex >= points.length || nextPointIndex < 0) { // reached the minimum or maximum available point, can't push anymore return false; } var nextHandle = handle + direction; var nextValue = points[nextPointIndex]; var pushable = this.props.pushable; var threshold = Number(pushable); var diffToNext = direction * (bounds[nextHandle] - nextValue); if (!this.pushHandle(bounds, nextHandle, direction, threshold - diffToNext)) { // couldn't push next handle, so we won't push this one either return false; } // push the handle // eslint-disable-next-line no-param-reassign bounds[handle] = nextValue; return true; } }, { key: "trimAlignValue", value: function trimAlignValue(value) { var _this$state2 = this.state, handle = _this$state2.handle, bounds = _this$state2.bounds; return _trimAlignValue({ value: value, handle: handle, bounds: bounds, props: this.props }); } }, { key: "render", value: function render() { var _this4 = this; var _this$state3 = this.state, handle = _this$state3.handle, bounds = _this$state3.bounds; var _this$props4 = this.props, prefixCls = _this$props4.prefixCls, vertical = _this$props4.vertical, included = _this$props4.included, disabled = _this$props4.disabled, min = _this$props4.min, max = _this$props4.max, reverse = _this$props4.reverse, handleGenerator = _this$props4.handle, trackStyle = _this$props4.trackStyle, handleStyle = _this$props4.handleStyle, tabIndex = _this$props4.tabIndex, ariaLabelGroupForHandles = _this$props4.ariaLabelGroupForHandles, ariaLabelledByGroupForHandles = _this$props4.ariaLabelledByGroupForHandles, ariaValueTextFormatterGroupForHandles = _this$props4.ariaValueTextFormatterGroupForHandles; var offsets = bounds.map(function (v) { return _this4.calcOffset(v); }); var handleClassName = "".concat(prefixCls, "-handle"); var handles = bounds.map(function (v, i) { var _classNames; var mergedTabIndex = tabIndex[i] || 0; if (disabled || tabIndex[i] === null) { mergedTabIndex = null; } var dragging = handle === i; return handleGenerator({ className: (0, _classnames.default)((_classNames = {}, (0, _defineProperty2.default)(_classNames, handleClassName, true), (0, _defineProperty2.default)(_classNames, "".concat(handleClassName, "-").concat(i + 1), true), (0, _defineProperty2.default)(_classNames, "".concat(handleClassName, "-dragging"), dragging), _classNames)), prefixCls: prefixCls, vertical: vertical, dragging: dragging, offset: offsets[i], value: v, index: i, tabIndex: mergedTabIndex, min: min, max: max, reverse: reverse, disabled: disabled, style: handleStyle[i], ref: function ref(h) { return _this4.saveHandle(i, h); }, ariaLabel: ariaLabelGroupForHandles[i], ariaLabelledBy: ariaLabelledByGroupForHandles[i], ariaValueTextFormatter: ariaValueTextFormatterGroupForHandles[i] }); }); var tracks = bounds.slice(0, -1).map(function (_, index) { var _classNames2; var i = index + 1; var trackClassName = (0, _classnames.default)((_classNames2 = {}, (0, _defineProperty2.default)(_classNames2, "".concat(prefixCls, "-track"), true), (0, _defineProperty2.default)(_classNames2, "".concat(prefixCls, "-track-").concat(i), true), _classNames2)); return /*#__PURE__*/_react.default.createElement(_Track.default, { className: trackClassName, vertical: vertical, reverse: reverse, included: included, offset: offsets[i - 1], length: offsets[i] - offsets[i - 1], style: trackStyle[index], key: i }); }); return { tracks: tracks, handles: handles }; } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(props, state) { if (!('value' in props || 'min' in props || 'max' in props)) { return null; } var value = props.value || state.bounds; var nextBounds = value.map(function (v, i) { return _trimAlignValue({ value: v, handle: i, bounds: state.bounds, props: props }); }); if (state.bounds.length === nextBounds.length) { if (nextBounds.every(function (v, i) { return v === state.bounds[i]; })) { return null; } } else { nextBounds = value.map(function (v, i) { return _trimAlignValue({ value: v, handle: i, props: props }); }); } return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, state), {}, { bounds: nextBounds }); } }]); return Range; }(_react.default.Component); /* eslint-enable */ Range.displayName = 'Range'; Range.defaultProps = { count: 1, allowCross: true, pushable: false, draggableTrack: false, tabIndex: [], ariaLabelGroupForHandles: [], ariaLabelledByGroupForHandles: [], ariaValueTextFormatterGroupForHandles: [] }; var _default = (0, _createSlider.default)(Range); exports.default = _default;