@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
219 lines (218 loc) • 9.54 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, useLayoutEffect, useRef, useState } from "react";
import classNames from "classnames";
import { StarFill } from "@nutui/icons-react-taro";
import { Text, View } from "@tarojs/components";
import { ComponentDefaults } from "../../utils/typings";
import { usePropsValue } from "../../hooks/use-props-value";
import { getRectInMultiPlatform } from "../../utils/taro/get-rect";
import { useRefs } from "../../hooks/use-refs";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
size: 'normal',
direction: 'horizontal',
showScore: false,
count: 5,
min: 0,
checkedIcon: null,
uncheckedIcon: null,
disabled: false,
readOnly: false,
allowHalf: false,
touchable: false
});
export var Rate = function Rate(props) {
var _$_object_spread = _object_spread({}, defaultProps, props), className = _$_object_spread.className, style = _$_object_spread.style, size = _$_object_spread.size, direction = _$_object_spread.direction, label = _$_object_spread.label, 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 shouldAnimate = direction === 'vertical' || size === 'large';
var _useState = _sliced_to_array(useState(-1), 2), animatingIndex = _useState[0], setAnimatingIndex = _useState[1];
useEffect(function() {
if (animatingIndex >= 0) {
var timer = setTimeout(function() {
return setAnimatingIndex(-1);
}, 300);
return function() {
return clearTimeout(timer);
};
}
}, [
animatingIndex
]);
var _useState1 = _sliced_to_array(useState([
1,
2,
3,
4,
5
]), 2), countArray = _useState1[0], setCountArray = _useState1[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 renderIcon(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 onClick(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);
if (shouldAnimate && value > score) {
setAnimatingIndex(index - 1);
}
setScore(value);
};
var onHalfClick = function onHalfClick(event, n) {
event.preventDefault();
event.stopPropagation();
var value = Math.max(min, n - 0.5);
if (shouldAnimate && value > score) {
setAnimatingIndex(n - 1);
}
setScore(value);
};
var getScoreByPosition = function getScoreByPosition(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 = useCallback(function() {
var _loop = function(index) {
var item = refs[index];
if (item) {
getRectInMultiPlatform(item).then(function(res) {
rateRects.current[index] = res;
});
}
};
for(var index = 0; index < refs.length; index++)_loop(index);
}, [
refs
]);
useLayoutEffect(function() {
updateRects();
}, [
updateRects
]);
var handleTouchStart = function handleTouchStart(e) {
if (!touchable || readOnly || disabled) {
return;
}
if (e.cancelable) {
e.preventDefault();
}
e.stopPropagation();
updateRects();
};
var handleTouchMove = function handleTouchMove(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 handleTouchEnd(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 isArrayLabel = Array.isArray(label);
var renderSingleLabel = function renderSingleLabel() {
if (label == null || isArrayLabel) return null;
return /*#__PURE__*/ React.createElement(Text, {
className: classNames("".concat(classPrefix, "-label"), "".concat(classPrefix, "-label-").concat(size))
}, label);
};
var renderArrayLabels = function renderArrayLabels() {
if (!isArrayLabel) return null;
return /*#__PURE__*/ React.createElement(View, {
className: classNames("".concat(classPrefix, "-labels"), "".concat(classPrefix, "-labels-").concat(size))
}, label.map(function(item, index) {
return /*#__PURE__*/ React.createElement(Text, {
className: "".concat(classPrefix, "-labels-item"),
key: index
}, item);
}));
};
var renderScore = function renderScore() {
if (!showScore) return null;
return /*#__PURE__*/ React.createElement(Text, {
className: classNames("".concat(classPrefix, "-score"), "".concat(classPrefix, "-score-").concat(size), _define_property({}, "".concat(classPrefix, "-score-disabled"), disabled))
}, score.toFixed(1));
};
return /*#__PURE__*/ React.createElement(View, {
className: classNames(classPrefix, "".concat(classPrefix, "-").concat(direction), {
disabled: disabled,
readonly: readOnly
}, className),
catchMove: true,
style: style,
onTouchStart: handleTouchStart,
onTouchMove: handleTouchMove,
onTouchEnd: handleTouchEnd,
onTouchCancel: handleTouchEnd
}, direction === 'horizontal' && renderSingleLabel(), /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-list")
}, countArray.map(function(n, index) {
var _obj;
return /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-item ").concat(classPrefix, "-item-").concat(size),
key: n,
ref: setRefs(index),
onClick: function onClick1(event) {
return onClick(event, n);
}
}, /*#__PURE__*/ React.createElement(View, {
className: classNames("".concat(classPrefix, "-item-icon"), (_obj = {}, _define_property(_obj, "".concat(classPrefix, "-item-icon-disabled"), disabled || n > score), _define_property(_obj, "".concat(classPrefix, "-item-icon-animate"), animatingIndex === index), _obj))
}, renderIcon(n)), allowHalf && score > n - 1 && /*#__PURE__*/ React.createElement(View, {
className: classNames("".concat(classPrefix, "-item-half"), "".concat(classPrefix, "-item-icon"), "".concat(classPrefix, "-item-icon-half")),
onClick: function onClick(event) {
return onHalfClick(event, n);
}
}, renderIcon(n)));
})), direction === 'horizontal' && renderScore(), direction === 'vertical' && /*#__PURE__*/ React.createElement(React.Fragment, null, renderScore(), isArrayLabel ? renderArrayLabels() : renderSingleLabel()));
};
Rate.displayName = 'NutRate';