@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
491 lines (490 loc) • 18 kB
JavaScript
import { _ as _define_property } from "@swc/helpers/_/_define_property";
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import classNames from "classnames";
import { useTouch } from "../../hooks/use-touch";
import { getRect } from "../../utils/get-rect";
import { ComponentDefaults } from "../../utils/typings";
import { usePropsValue } from "../../hooks/use-props-value";
import { useRtl } from "../configprovider";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
range: false,
min: 0,
max: 100,
step: 1,
vertical: false,
marks: {}
});
var classPrefix = 'nut-range';
var verticalClassPrefix = "".concat(classPrefix, "-vertical");
var isSameValue = function(newValue, oldValue) {
return JSON.stringify(newValue) === JSON.stringify(oldValue);
};
var handleOverlap = function(value) {
if (value[0] > value[1]) {
return value.slice(0).reverse();
}
return value;
};
export var Range = function(props) {
var rtl = useRtl();
var _$_object_spread = _object_spread({}, defaultProps, props), className = _$_object_spread.className, style = _$_object_spread.style, range = _$_object_spread.range, disabled = _$_object_spread.disabled, button = _$_object_spread.button, vertical = _$_object_spread.vertical, marks = _$_object_spread.marks, minDescription = _$_object_spread.minDescription, maxDescription = _$_object_spread.maxDescription, currentDescription = _$_object_spread.currentDescription, min = _$_object_spread.min, max = _$_object_spread.max, step = _$_object_spread.step, value = _$_object_spread.value, defaultValue = _$_object_spread.defaultValue, onChange = _$_object_spread.onChange, onStart = _$_object_spread.onStart, onEnd = _$_object_spread.onEnd;
var rtlClassPrefix = useMemo(function() {
return "rtl-".concat(vertical ? verticalClassPrefix : classPrefix);
}, [
vertical
]);
var _useState = _sliced_to_array(useState(0), 2), buttonIndex = _useState[0], setButtonIndex = _useState[1];
var _useState1 = _sliced_to_array(useState('start'), 2), dragStatus = _useState1[0], setDragStatus = _useState1[1];
var touch = useTouch();
var root = useRef(null);
var _useState2 = _sliced_to_array(useState([]), 2), marksList = _useState2[0], setMarksList = _useState2[1];
var _useState3 = _sliced_to_array(useState(0), 2), startValue = _useState3[0], setStartValue = _useState3[1];
var scope = useMemo(function() {
if (max < min || max === min) {
console.log('max 的值需要大于 min的值');
}
return max - min;
}, [
max,
min
]);
var handleChange = function(value) {
onChange && onChange(value);
};
var _usePropsValue = _sliced_to_array(usePropsValue({
value: value,
defaultValue: defaultValue,
finalValue: 0,
onChange: handleChange
}), 2), current = _usePropsValue[0], setCurrent = _usePropsValue[1];
var _useState4 = _sliced_to_array(useState(function() {
return value || defaultValue || 0;
}), 2), exactValue = _useState4[0], setExactValue = _useState4[1];
var marksRef = useRef({});
useEffect(function() {
if (marks) {
if (Array.isArray(marks)) {
var list = marks.sort(function(a, b) {
return a.value - b.value;
}).filter(function(point) {
return point.value >= min && point.value <= max;
});
setMarksList(list.map(function(mark) {
return mark.value;
}));
list.forEach(function(mark) {
marksRef.current[mark.value] = mark.label !== undefined ? mark.label : mark.value;
});
} else {
var marksKeys = Object.keys(marks);
var list1 = marksKeys.map(parseFloat).sort(function(a, b) {
return a - b;
}).filter(function(point) {
return point >= min && point <= max;
});
setMarksList(list1);
}
}
}, [
marks,
max,
min
]);
var _obj;
var classes = classNames(classPrefix, (_obj = {}, _define_property(_obj, "".concat(classPrefix, "-disabled"), disabled), _define_property(_obj, verticalClassPrefix, vertical), _obj));
var containerClasses = classNames("".concat(classPrefix, "-container"), _define_property({}, "".concat(verticalClassPrefix, "-container"), vertical), className);
var markClassName = useCallback(function(mark) {
var classPrefix = 'nut-range-mark';
var verticalClassPrefix = 'nut-range-vertical-mark';
var lowerBound = min;
var upperBound = max;
if (range && Array.isArray(current)) {
lowerBound = current[0];
upperBound = current[1];
} else {
upperBound = current;
}
var isActive = mark <= upperBound && mark >= lowerBound;
var _$classNames = [
"".concat(classPrefix, "-text-wrapper"),
"".concat(isActive ? "".concat(classPrefix, "-text-wrapper-active") : '')
];
if (vertical) {
_$classNames.push("".concat(verticalClassPrefix, "-text-wrapper"));
isActive && _$classNames.push("".concat(verticalClassPrefix, "-text-active-wrapper"));
}
if (rtl) {
_$classNames.push("".concat(rtlClassPrefix, "-mark-text-wrapper"));
}
return _$classNames.join(' ');
}, [
min,
max,
range,
current,
vertical,
rtl,
rtlClassPrefix
]);
var isRange = useCallback(function(val) {
return !!range && Array.isArray(val);
}, [
range
]);
var calcMainAxis = useCallback(function() {
var modelVal = current;
return isRange(modelVal) ? "".concat((modelVal[1] - modelVal[0]) * 100 / scope, "%") : "".concat((modelVal - min) * 100 / scope, "%");
}, [
current,
isRange,
min,
scope
]);
var calcOffset = useCallback(function() {
var modelVal = current;
return isRange(modelVal) ? "".concat((modelVal[0] - min) * 100 / scope, "%") : "0%";
}, [
current,
isRange,
min,
scope
]);
var barStyle = useCallback(function() {
if (vertical) {
return {
height: calcMainAxis(),
top: calcOffset(),
transition: dragStatus ? 'none' : undefined
};
}
var dir = rtl ? 'right' : 'left';
var _obj;
return _obj = {
width: calcMainAxis()
}, _define_property(_obj, dir, calcOffset()), _define_property(_obj, "transition", dragStatus ? 'none' : undefined), _obj;
}, [
calcMainAxis,
calcOffset,
dragStatus,
rtl,
vertical
]);
var marksStyle = useCallback(function(mark) {
var dir = rtl ? 'right' : 'left';
var style = _define_property({}, dir, "".concat((mark - min) / scope * 100, "%"));
if (vertical) {
style = {
top: "".concat((mark - min) / scope * 100, "%")
};
}
return style;
}, [
min,
rtl,
scope,
vertical
]);
var tickClass = useCallback(function(mark) {
if (range && Array.isArray(current)) {
return mark <= current[1] && mark >= current[0];
}
return mark <= current;
}, [
current,
range
]);
var format = useCallback(function(value) {
value = Math.max(+min, Math.min(value, +max));
return Math.round(value / +step) * +step;
}, [
max,
min,
step
]);
var updateValue = useCallback(function(value, end) {
if (isRange(value)) {
value = handleOverlap(value).map(format);
} else {
value = format(value);
}
if (!isSameValue(value, current)) {
setCurrent(value);
}
end && onEnd && onEnd(value);
}, [
current,
format,
isRange,
onEnd,
setCurrent
]);
var click = useCallback(function(event) {
if (disabled || !root.current) {
return;
}
setDragStatus('');
var rect = getRect(root.current);
var delta = event.clientX - rect.left;
var total = rect.width;
if (vertical) {
delta = event.clientY - rect.top;
total = rect.height;
}
var value = min + delta / total * scope;
setExactValue(current);
if (isRange(current)) {
var _current = _sliced_to_array(current, 2), left = _current[0], right = _current[1];
var middle = (left + right) / 2;
if (value <= middle) {
updateValue([
value,
right
], true);
} else {
updateValue([
left,
value
], true);
}
} else {
updateValue(value, true);
}
}, [
current,
disabled,
isRange,
min,
scope,
updateValue,
vertical
]);
var onTouchStart = useCallback(function(event) {
if (disabled) {
return;
}
touch.start(event);
setExactValue(current);
if (isRange(current)) {
setStartValue(current.map(format));
} else {
setStartValue(format(current));
}
setDragStatus('start');
}, [
current,
disabled,
format,
isRange,
touch
]);
var onTouchMove = useCallback(function(event) {
event.stopPropagation();
if (disabled || !root.current) {
return;
}
if (dragStatus === 'start') {
onStart && onStart();
}
touch.move(event);
setDragStatus('draging');
var rect = getRect(root.current);
var delta = touch.deltaX.current;
var total = rect.width;
var diff = delta / total * scope;
diff = rtl ? -diff : diff;
if (vertical) {
delta = touch.deltaY.current;
total = rect.height;
diff = delta / total * scope;
}
var newValue;
if (isRange(startValue)) {
newValue = exactValue.slice();
newValue[buttonIndex] = startValue[buttonIndex] + diff;
} else {
newValue = startValue + diff;
}
setExactValue(newValue);
updateValue(newValue);
}, [
buttonIndex,
disabled,
dragStatus,
exactValue,
isRange,
onStart,
rtl,
scope,
startValue,
touch,
updateValue,
vertical
]);
var onTouchEnd = useCallback(function() {
if (disabled) {
return;
}
if (dragStatus === 'draging') {
updateValue(current, true);
}
setDragStatus('');
}, [
current,
disabled,
dragStatus,
updateValue
]);
var curValue = useCallback(function(idx) {
var modelVal = current;
var value = typeof idx === 'number' ? modelVal[idx] : modelVal;
return value;
}, [
current
]);
var renderButton = useCallback(function(index) {
var buttonNumberTransform = vertical ? 'translate(100%, -50%)' : 'translate(-50%, -100%)';
var _obj, _obj1;
return /*#__PURE__*/ React.createElement(React.Fragment, null, button || /*#__PURE__*/ React.createElement("div", {
className: classNames("".concat(classPrefix, "-button"), (_obj = {}, _define_property(_obj, "".concat(verticalClassPrefix, "-button"), vertical), _define_property(_obj, "".concat(rtlClassPrefix, "-button"), rtl), _obj)),
style: {
transform: 'translate(-50%, -50%)'
}
}, currentDescription !== null && /*#__PURE__*/ React.createElement("div", {
className: classNames("".concat(classPrefix, "-button-number"), (_obj1 = {}, _define_property(_obj1, "".concat(verticalClassPrefix, "-button-number"), vertical), _define_property(_obj1, "".concat(rtlClassPrefix, "-button-number"), rtl), _obj1)),
style: {
transform: buttonNumberTransform
}
}, currentDescription ? currentDescription(curValue(index)) : curValue(index))));
}, [
button,
curValue,
currentDescription,
rtl,
rtlClassPrefix,
vertical
]);
var renderMarks = useCallback(function() {
if (marksList.length <= 0) return null;
var _obj;
var markcls = classNames("".concat(classPrefix, "-mark"), (_obj = {}, _define_property(_obj, "".concat(verticalClassPrefix, "-mark"), vertical), _define_property(_obj, "".concat(rtlClassPrefix, "-mark"), rtl), _obj));
var textcls = classNames("".concat(classPrefix, "-mark-text"), _define_property({}, "".concat(verticalClassPrefix, "-mark-text"), vertical));
return /*#__PURE__*/ React.createElement("div", {
className: markcls
}, marksList.map(function(mark) {
var _obj;
return /*#__PURE__*/ React.createElement("span", {
key: mark,
className: markClassName(mark),
style: marksStyle(mark)
}, /*#__PURE__*/ React.createElement("span", {
className: textcls
}, Array.isArray(marks) ? marksRef.current[mark] : marks[mark]), /*#__PURE__*/ React.createElement("span", {
className: classNames("".concat(vertical ? verticalClassPrefix : classPrefix, "-tick"), (_obj = {}, _define_property(_obj, "".concat(vertical ? verticalClassPrefix : classPrefix, "-tick-active"), tickClass(mark)), _define_property(_obj, "".concat(rtlClassPrefix, "-tick"), rtl), _obj))
}));
}));
}, [
markClassName,
marks,
marksList,
marksStyle,
rtl,
rtlClassPrefix,
tickClass,
vertical
]);
var getWrapperTransform = useCallback(function() {
var wrapperTransform = 'translate(-50%, -50%)';
return wrapperTransform;
}, []);
var renderRangeButton = useCallback(function() {
return [
0,
1
].map(function(item, index) {
var isLeft = index === 0;
var suffix = isLeft ? 'left' : 'right';
var transform = 'translate(-50%, -50%)';
var _obj;
var cls = classNames("".concat(classPrefix, "-button-wrapper-").concat(suffix), (_obj = {}, _define_property(_obj, "".concat(verticalClassPrefix, "-button-wrapper-").concat(suffix), vertical), _define_property(_obj, "".concat(rtlClassPrefix, "-button-wrapper-").concat(suffix), rtl), _obj));
return /*#__PURE__*/ React.createElement("div", {
key: index,
className: cls,
style: {
transform: transform
},
onTouchStart: function(e) {
setButtonIndex(index);
onTouchStart(e);
},
onTouchMove: onTouchMove,
onTouchEnd: onTouchEnd,
onTouchCancel: onTouchEnd,
onClick: function(e) {
return e.stopPropagation();
}
}, renderButton(index));
});
}, [
onTouchEnd,
onTouchMove,
onTouchStart,
renderButton,
vertical,
rtl,
rtlClassPrefix
]);
var renderSingleButton = useCallback(function() {
return /*#__PURE__*/ React.createElement("div", {
className: classNames("".concat(classPrefix, "-button-wrapper"), _define_property({}, "".concat(verticalClassPrefix, "-button-wrapper"), vertical)),
style: {
// @ts-ignore
transform: getWrapperTransform()
},
onTouchStart: onTouchStart,
onTouchMove: onTouchMove,
onTouchEnd: onTouchEnd,
onTouchCancel: onTouchEnd,
onClick: function(e) {
return e.stopPropagation();
}
}, renderButton());
}, [
getWrapperTransform,
onTouchEnd,
onTouchMove,
onTouchStart,
renderButton,
vertical
]);
var renderButtonWrapper = useCallback(function() {
if (range) {
return renderRangeButton();
}
return renderSingleButton();
}, [
renderRangeButton,
renderSingleButton,
range
]);
return /*#__PURE__*/ React.createElement("div", {
className: containerClasses,
style: style
}, minDescription !== null && /*#__PURE__*/ React.createElement("div", {
className: "".concat(classPrefix, "-min")
}, minDescription || min), /*#__PURE__*/ React.createElement("div", {
ref: root,
className: classes,
onClick: function(e) {
return click(e);
}
}, renderMarks(), /*#__PURE__*/ React.createElement("div", {
className: "".concat(classPrefix, "-bar"),
style: barStyle()
}, renderButtonWrapper())), maxDescription !== null && /*#__PURE__*/ React.createElement("div", {
className: "".concat(classPrefix, "-max")
}, maxDescription || max));
};
Range.displayName = 'NutRange';