UNPKG

antd-group-slider

Version:
424 lines (357 loc) 13.5 kB
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('react'); var React__default = _interopDefault(React); var antd = require('antd'); function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var DEFAULT_SEPARATOR = '-'; function renderRangeInText(range, text, separator) { if (text === void 0) { text = ''; } if (separator === void 0) { separator = DEFAULT_SEPARATOR; } if (!range || range.length !== 2) { return text; } var left = range[0]; var right = range[1]; return text.replace(/{{range}}/, "" + left + separator + right); } var DEFAULT_PLACEHOLDER = 'Description for range {{range}}'; var SideTextDescription = function SideTextDescription(_ref) { var leftText = _ref.leftText, rightText = _ref.rightText, children = _ref.children; return /*#__PURE__*/React__default.createElement("div", { className: "antd-group-slider-item__description" }, /*#__PURE__*/React__default.createElement("div", { className: "antd-group-slider-item__description-left-text" }, leftText), children, /*#__PURE__*/React__default.createElement("div", { className: "antd-group-slider-item__description-right-text" }, rightText)); }; var GroupSliderLine = /*#__PURE__*/function (_React$Component) { _inheritsLoose(GroupSliderLine, _React$Component); function GroupSliderLine() { var _this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this; _this.state = { right: _this.props.value[1], left: _this.props.value[0] }; _this.onChange = function (val) { var left = val[0], right = val[1]; var nextRight = left === _this.state.left ? right : left; _this.setState({ right: Math.max(_this.state.left, nextRight) }); }; _this.calculateMarks = function (min, max) { var _ref2; if (min === void 0) { min = 0; } var mid = Math.floor((max + min) / 2); return _ref2 = {}, _ref2[min] = min.toString(), _ref2[mid] = mid.toString(), _ref2[max] = max.toString(), _ref2; }; _this.renderDescription = function () { var descriptionConfig = _this.props.descriptionConfig || {}; var placeholder = descriptionConfig.placeholder, type = descriptionConfig.type, separator = descriptionConfig.separator, leftText = descriptionConfig.leftText, leftAddonText = descriptionConfig.leftAddonText, rightText = descriptionConfig.rightText, rightAddonText = descriptionConfig.rightAddonText; if (type === 'none') { return /*#__PURE__*/React__default.createElement(React__default.Fragment, null); } var range = [_this.state.left, _this.state.right]; var inputProps = { className: 'antd-group-slider-item__description', placeholder: placeholder ? renderRangeInText(range, placeholder, separator) : renderRangeInText(range, DEFAULT_PLACEHOLDER, separator), defaultValue: _this.props.initialDescription, onChange: function onChange(e) { return _this.props.updateDescription(e.target.value); } }; if (type === 'input') { var inputPropsWithAddon = Object.assign({}, inputProps, { addonBefore: renderRangeInText(range, leftAddonText, separator), addonAfter: renderRangeInText(range, rightAddonText, separator) }); return /*#__PURE__*/React__default.createElement(SideTextDescription, { range: range, leftText: renderRangeInText(range, leftText, separator), rightText: renderRangeInText(range, rightText, separator) }, /*#__PURE__*/React__default.createElement(antd.Input, inputPropsWithAddon)); } return /*#__PURE__*/React__default.createElement(SideTextDescription, { range: range, leftText: renderRangeInText(range, leftText, separator), rightText: renderRangeInText(range, rightText, separator) }, /*#__PURE__*/React__default.createElement(antd.Input.TextArea, inputProps)); }; return _this; } var _proto = GroupSliderLine.prototype; _proto.render = function render() { var _this2 = this; var _this$state = this.state, left = _this$state.left, right = _this$state.right; var marks = this.props.marks || this.calculateMarks(this.props.min, this.props.max); return /*#__PURE__*/React__default.createElement("div", { className: "antd-group-slider-item" }, /*#__PURE__*/React__default.createElement(antd.Slider, { className: "antd-group-slider-item__slider", range: true, min: this.props.min, max: this.props.max, marks: marks, value: [left, right], onChange: this.onChange, onAfterChange: function onAfterChange(val) { _this2.props.onAfterRangeChange(val); _this2.setState({ right: _this2.props.value[1], left: _this2.props.value[0] }); } }), this.renderDescription(), this.props.extra ? this.props.extra : /*#__PURE__*/React__default.createElement(React__default.Fragment, null)); }; return GroupSliderLine; }(React__default.Component); function syncRanges(inputRanges, range, index) { var ranges = [].concat(inputRanges); var currentRight = range[1]; var rightNeighbor = ranges[index + 1]; if (rightNeighbor) { var nextRight = rightNeighbor[1]; if (currentRight >= nextRight - 1) { currentRight = nextRight - 1; rightNeighbor[0] = rightNeighbor[1]; } else { rightNeighbor[0] = currentRight + 1; } } ranges[index][1] = currentRight; return ranges; } function fillGaps(data, config) { if (config === void 0) { config = { fillGaps: true }; } if (!config.fillGaps) return data; if (data.ranges && data.ranges.length < 2) return data; var descriptions = data.descriptions; var ranges = standardizeRanges(data.ranges); var output = fillMissingGaps(ranges, descriptions); return output; } function standardizeRanges(ranges) { return ranges.map(function (range) { var left = Math.min.apply(Math, range); var right = Math.max.apply(Math, range); return [left, right]; }); } function enoughForNewRange(ranges, leftIndex, rightIndex) { return ranges[rightIndex][0] - ranges[leftIndex][1] > 1; } function fillMissingGaps(inputRanges, inputDescriptions) { var ranges = [].concat(inputRanges); var descriptions = [].concat(inputDescriptions); for (var rightIndex = ranges.length - 1; rightIndex > 0; rightIndex--) { var leftIndex = rightIndex - 1; if (enoughForNewRange(ranges, leftIndex, rightIndex)) { var missingRange = calculateMissingRange(ranges, leftIndex, rightIndex); ranges.splice(rightIndex, 0, missingRange); descriptions.splice(rightIndex, 0, ''); } } return { ranges: ranges, descriptions: descriptions }; } function calculateMissingRange(ranges, leftIndex, rightIndex) { var left = ranges[leftIndex][1] + 1; var right = ranges[rightIndex][0] - 1; return [left, right]; } var _excluded = ["min", "max"]; var DEFAULT_LEFT = 0; var DEFAULT_RIGHT = 100; var TooltipAddButton = function TooltipAddButton(_ref) { var children = _ref.children; return /*#__PURE__*/React__default.createElement(antd.Tooltip, { trigger: "hover", placement: "top", title: "Only can add range if the point range is not fully covered" }, children); }; var GroupSlider = function GroupSlider(_ref2) { var _ref2$min = _ref2.min, min = _ref2$min === void 0 ? DEFAULT_LEFT : _ref2$min, _ref2$max = _ref2.max, max = _ref2$max === void 0 ? DEFAULT_RIGHT : _ref2$max, props = _objectWithoutPropertiesLoose(_ref2, _excluded); var _useState = React.useState([[min, max]]), ranges = _useState[0], setRanges = _useState[1]; var _useState2 = React.useState([]), descriptions = _useState2[0], setDescriptions = _useState2[1]; var _useState3 = React.useState([]), lineExtras = _useState3[0], setLineExtras = _useState3[1]; React.useEffect(function () { if (props.initialValues) { setLineExtras(lineExtras.lineExtras); var processedInitialValues = fillGaps(props.initialValues, props.initialValuesConfig); var _ranges = processedInitialValues.ranges, _descriptions = processedInitialValues.descriptions; var leftMost = _ranges[0][0]; _ranges[0][0] = Math.max(min, leftMost); var lastIndex = _ranges.length - 1; var rightMost = _ranges[lastIndex][1]; _ranges[lastIndex][1] = Math.min(max, rightMost); setRanges(_ranges); setDescriptions(_descriptions); } }, []); React.useEffect(function () { ranges[0][0] = min; }, [min]); var isFullRange = function isFullRange() { var values = new Set(); ranges.forEach(function (r) { var left = r[0], right = r[1]; for (var i = left; i <= right; i++) { if (i >= 0 && i <= 100) values.add(i); } }); return values.size === parseInt(max) + 1; }; React.useEffect(function () { if (props.onChange) { props.onChange({ ranges: ranges, descriptions: descriptions, isFullRange: isFullRange() }); } }, [ranges, descriptions]); var addRange = function addRange() { var newRanges = [].concat(ranges); var lastIndex = ranges.length - 1; var left = ranges[lastIndex][1]; newRanges.push([left + 1, max]); setRanges(newRanges); }; var syncNewRange = function syncNewRange(updatedRange, index) { var nextRanges = syncRanges(ranges, updatedRange, index); setRanges(nextRanges); }; var _updateDescription = function updateDescription(description, index) { var nextDescriptions = [].concat(descriptions); nextDescriptions[index] = description; setDescriptions(nextDescriptions); }; var renderPointRangeGroupLine = function renderPointRangeGroupLine() { return ranges.map(function (range, i) { var _props$lineExtras; return /*#__PURE__*/React__default.createElement(React__default.Fragment, { key: range }, /*#__PURE__*/React__default.createElement(GroupSliderLine, { marks: props.marks, descriptionConfig: props.descriptionConfig, onAfterRangeChange: function onAfterRangeChange(data) { return syncNewRange(data, i); }, updateDescription: function updateDescription(data) { return _updateDescription(data, i); }, initialDescription: descriptions[i], extra: (_props$lineExtras = props.lineExtras) === null || _props$lineExtras === void 0 ? void 0 : _props$lineExtras[i], value: range, max: max, min: min }), props.showDivider ? /*#__PURE__*/React__default.createElement(antd.Divider, null) : /*#__PURE__*/React__default.createElement(React__default.Fragment, null)); }); }; var isAbleToAddRange = function isAbleToAddRange() { var lastIndex = ranges.length - 1; var rightMost = ranges[lastIndex][1]; return rightMost > max - 1; }; var cannotRemoveRange = function cannotRemoveRange() { return ranges.length <= 1; }; var removeLastRange = function removeLastRange() { ranges.pop(); var lastIndex = ranges.length - 1; ranges[lastIndex][1] = max; setRanges([].concat(ranges)); descriptions.pop(); setDescriptions([].concat(descriptions)); }; var removeText = props.removeButtonText || 'Remove last range'; var addText = props.addButtonText || 'Add more range'; var addButton = /*#__PURE__*/React__default.createElement(antd.Button, { className: "antd-group-slider__btn-add-range", disabled: isAbleToAddRange(), ghost: true, type: "primary", onClick: addRange }, addText); return /*#__PURE__*/React__default.createElement("div", { className: "antd-group-slider" }, renderPointRangeGroupLine(), /*#__PURE__*/React__default.createElement(antd.Row, { className: "antd-group-slider__footer", gutter: 4 }, /*#__PURE__*/React__default.createElement(antd.Col, { span: 12 }, isFullRange() ? /*#__PURE__*/React__default.createElement(TooltipAddButton, null, addButton) : addButton), /*#__PURE__*/React__default.createElement(antd.Col, { span: 12 }, /*#__PURE__*/React__default.createElement(antd.Button, { className: "antd-group-slider__btn-remove-range", danger: true, disabled: cannotRemoveRange(), onClick: removeLastRange }, removeText)))); }; module.exports = GroupSlider; //# sourceMappingURL=index.js.map