@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
180 lines (179 loc) • 7.39 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, { useEffect, useRef, useState } from "react";
import classNames from "classnames";
import { StarFill } from "@nutui/icons-react";
import { ComponentDefaults } from "../../utils/typings";
import { usePropsValue } from "../../hooks/use-props-value";
import { getRect } from "../../utils/get-rect";
import { useRefs } from "../../hooks/use-refs";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
size: 'normal',
showScore: false,
count: 5,
min: 0,
checkedIcon: null,
uncheckedIcon: null,
disabled: false,
readOnly: false,
allowHalf: false,
touchable: false
});
export var Rate = function(props) {
var _$_object_spread = _object_spread({}, defaultProps, props), className = _$_object_spread.className, style = _$_object_spread.style, size = _$_object_spread.size, showScore = _$_object_spread.showScore, count = _$_object_spread.count, value = _$_object_spread.value, defaultValue = _$_object_spread.defaultValue, min = _$_object_spread.min, checkedIcon = _$_object_spread.checkedIcon, uncheckedIcon = _$_object_spread.uncheckedIcon, disabled = _$_object_spread.disabled, readOnly = _$_object_spread.readOnly, allowHalf = _$_object_spread.allowHalf, touchable = _$_object_spread.touchable, onChange = _$_object_spread.onChange, onTouchEnd = _$_object_spread.onTouchEnd;
var classPrefix = 'nut-rate';
var _useState = _sliced_to_array(useState([
1,
2,
3,
4,
5
]), 2), countArray = _useState[0], setCountArray = _useState[1];
var _useRefs = _sliced_to_array(useRefs(), 2), refs = _useRefs[0], setRefs = _useRefs[1];
var rateRects = useRef([]);
var _usePropsValue = _sliced_to_array(usePropsValue({
value: value,
defaultValue: Math.max(defaultValue || 0, min),
finalValue: 0,
onChange: onChange
}), 2), score = _usePropsValue[0], setScore = _usePropsValue[1];
useEffect(function() {
var tmp = [];
for(var i = 1; i <= Number(count); i++){
tmp.push(i);
}
setCountArray(tmp);
}, [
count
]);
var renderIcon = function(n) {
return n <= score ? checkedIcon || /*#__PURE__*/ React.createElement(StarFill, null) : uncheckedIcon || (checkedIcon ? /*#__PURE__*/ React.cloneElement(checkedIcon, {
color: undefined
}) : /*#__PURE__*/ React.createElement(StarFill, null));
};
var onClick = function(e, index) {
e.preventDefault();
e.stopPropagation();
if (disabled || readOnly) return;
var value = 0;
if (!(index === 1 && score === index)) {
value = index;
}
value = Math.max(value, min);
setScore(value);
};
var onHalfClick = function(event, n) {
event.preventDefault();
event.stopPropagation();
var value = Math.max(min, n - 0.5);
setScore(value);
};
var getScoreByPosition = function(x) {
var _rateRects_current;
if ((_rateRects_current = rateRects.current) === null || _rateRects_current === void 0 ? void 0 : _rateRects_current.length) {
for(var index = rateRects.current.length - 1; index >= 0; index--){
var item = rateRects.current[index];
if (item && x > item.left) {
return allowHalf ? index + (x > item.left + item.width / 2 ? 1 : 0.5) : index + 1;
}
}
return 0;
}
};
var updateRects = function() {
for(var index = 0; index < refs.length; index++){
var item = refs[index];
if (item) {
rateRects.current[index] = getRect(item);
}
}
};
var handleTouchStart = function(e) {
if (!touchable || readOnly || disabled) {
return;
}
if (e.cancelable) {
e.preventDefault();
}
e.stopPropagation();
updateRects();
};
var handleTouchMove = function(e) {
if (!touchable || readOnly || disabled) {
return;
}
if (e.cancelable) {
e.preventDefault();
}
e.stopPropagation();
var val = getScoreByPosition(e.touches[0].clientX);
if (val !== undefined) {
setScore(Math.max(min, val));
}
};
var handleTouchEnd = function(e) {
if (!touchable || readOnly || disabled) {
return;
}
if (e.cancelable) {
e.preventDefault();
}
e.stopPropagation();
var val = getScoreByPosition(e.changedTouches[0].clientX);
if (val !== undefined) {
setScore(Math.max(min, val));
onTouchEnd && onTouchEnd(e, Math.max(min, val));
}
};
var rateRef = useRef(null);
useEffect(function() {
var element = rateRef.current;
if (element) {
element.addEventListener('touchstart', handleTouchStart, {
passive: false
});
element.addEventListener('touchmove', handleTouchMove, {
passive: false
});
element.addEventListener('touchend', handleTouchEnd, {
passive: false
});
}
return function() {
if (element) {
element.removeEventListener('touchstart', handleTouchStart);
element.removeEventListener('touchmove', handleTouchMove);
element.removeEventListener('touchend', handleTouchEnd);
}
};
}, []);
return /*#__PURE__*/ React.createElement("div", {
className: classNames(classPrefix, {
disabled: disabled,
readonly: readOnly
}, className),
ref: rateRef,
style: style
}, countArray.map(function(n, index) {
return /*#__PURE__*/ React.createElement("div", {
className: "".concat(classPrefix, "-item ").concat(classPrefix, "-item-").concat(size),
key: n,
ref: setRefs(index),
onClick: function(event) {
return onClick(event, n);
}
}, /*#__PURE__*/ React.createElement("div", {
className: classNames("".concat(classPrefix, "-item-icon"), _define_property({}, "".concat(classPrefix, "-item-icon-disabled"), disabled || n > score))
}, renderIcon(n)), allowHalf && score > n - 1 && /*#__PURE__*/ React.createElement("div", {
className: classNames("".concat(classPrefix, "-item-half"), "".concat(classPrefix, "-item-icon"), "".concat(classPrefix, "-item-icon-half")),
onClick: function(event) {
return onHalfClick(event, n);
}
}, renderIcon(n)));
}), showScore ? /*#__PURE__*/ React.createElement("span", {
className: classNames("".concat(classPrefix, "-score"), "".concat(classPrefix, "-score-").concat(size), _define_property({}, "".concat(classPrefix, "-score-disabled"), disabled))
}, score.toFixed(1)) : null);
};
Rate.displayName = 'NutRate';