UNPKG

@nutui/nutui-react

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

180 lines (179 loc) 7.39 kB
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';