acud
Version:
acg react 组件库
268 lines • 11.5 kB
JavaScript
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable max-len */
/**
* @file rate
* @description 评分 星星现在是svg写文件里 打开了每行最大长度的限制
* @author jc
*/
import React, { useState, useMemo, useCallback, useContext, useEffect, Fragment } from 'react';
import classNames from 'classnames';
import { ConfigContext } from '../config-provider';
var Rate = function Rate(_ref) {
var customizePrefixCls = _ref.prefixCls,
_ref$allowClear = _ref.allowClear,
allowClear = _ref$allowClear === void 0 ? true : _ref$allowClear,
_ref$allowHalf = _ref.allowHalf,
allowHalf = _ref$allowHalf === void 0 ? false : _ref$allowHalf,
className = _ref.className,
style = _ref.style,
_ref$count = _ref.count,
count = _ref$count === void 0 ? 5 : _ref$count,
_ref$defaultValue = _ref.defaultValue,
defaultValue = _ref$defaultValue === void 0 ? 0 : _ref$defaultValue,
_ref$value = _ref.value,
value = _ref$value === void 0 ? 0 : _ref$value,
_ref$tooltips = _ref.tooltips,
tooltips = _ref$tooltips === void 0 ? [] : _ref$tooltips,
_ref$disabled = _ref.disabled,
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
_ref$tags = _ref.tags,
tags = _ref$tags === void 0 ? [] : _ref$tags,
onFocus = _ref.onFocus,
onBlur = _ref.onBlur,
onHoverChange = _ref.onHoverChange,
onChange = _ref.onChange,
renderCharacter = _ref.renderCharacter,
onLabelChange = _ref.onLabelChange,
renderTag = _ref.renderTag;
var _useContext = useContext(ConfigContext),
getPrefixCls = _useContext.getPrefixCls;
var prefixCls = getPrefixCls('rate', customizePrefixCls);
var STAR_FIX = "".concat(prefixCls, "-star"); // ⭐容器
var STAR_INNER_FIX = "".concat(STAR_FIX, "-inner"); // ⭐
var STAR_FULL_FIX = "".concat(STAR_FIX, "-full"); // 高分⭐
var STAR_LOW_FIX = "".concat(STAR_FIX, "-low"); // 低分⭐
var STAR_NORMAL_FIX = "".concat(STAR_FIX, "-normal"); // 普通⭐
var STAR_DISABLED = "".concat(STAR_FIX, "-disabled"); // 禁用的⭐
var STAR_HALF_FIX = "".concat(STAR_FIX, "-half"); // 半⭐
var LABEL_FIX = "".concat(prefixCls, "-label"); // 辅助文案
var TAGS_FIX = "".concat(prefixCls, "-tags"); // 标签
var TAGS_SELECT_FIX = "".concat(TAGS_FIX, "-select"); // 选中的标签
var TAGS_DISABLED = "".concat(TAGS_FIX, "-disabled"); // 禁用的标签
var _useState = useState(-1),
_useState2 = _slicedToArray(_useState, 2),
hoverValue = _useState2[0],
updateHoverValue = _useState2[1];
var _useState3 = useState(allowHalf ? defaultValue : defaultValue - 1),
_useState4 = _slicedToArray(_useState3, 2),
currValue = _useState4[0],
updateCurrValue = _useState4[1];
var _useState5 = useState(false),
_useState6 = _slicedToArray(_useState5, 2),
isHover = _useState6[0],
updateIsHover = _useState6[1];
var _useState7 = useState([]),
_useState8 = _slicedToArray(_useState7, 2),
selectTags = _useState8[0],
updateSelectTags = _useState8[1];
var list = useMemo(function () {
return new Array(count).fill('').map(function (_item, index) {
return index;
});
}, [count]);
useEffect(function () {
value && updateCurrValue(allowHalf && value % 1 ? value : value - 1);
}, [value]);
// 获取焦点
var handleFocus = useCallback(function () {
onFocus && onFocus();
}, []);
// 鼠标移出
var handleBlur = useCallback(function () {
updateHoverValue(-1);
updateIsHover(false);
onBlur && onBlur();
}, []);
// 鼠标经过
var handleHoverChange = useCallback(function (value, isHalf) {
if (disabled) {
return;
}
var _value = isHalf ? value + 0.5 : value;
updateHoverValue(_value);
updateIsHover(true);
onHoverChange && onHoverChange(isHalf ? _value : _value + 1);
}, [disabled]);
// 点击值变更
var handleChange = useCallback(function (value, isHalf) {
if (disabled) {
return;
}
// 点击时的值和当前值进行判断
// 判断的目的是 如果设置了allowClear 就设置value为-1进行清空
var clickValue = isHalf ? value + 0.5 : value;
var _value = allowClear && clickValue === currValue ? -1 : clickValue;
// 内部的计算从0开始
// eg: 半颗星星返回0.5 1颗星星返回0 ...
// 暂时先在CB函数里 + 1 如果要改currvalue会有不小改动
// 同样在handleHoverChange做了相同的处理
updateCurrValue(_value);
onChange && onChange(isHalf ? _value : _value + 1);
}, [currValue, disabled]);
// star class
var getCurrClassName = useCallback(function (value) {
var halfValue = count / 2;
var getActiveClass = function getActiveClass(_value) {
var classname = '';
_value <= halfValue ? classname = " ".concat(value <= _value ? STAR_LOW_FIX : STAR_NORMAL_FIX) : classname = " ".concat(value <= _value ? STAR_FULL_FIX : STAR_NORMAL_FIX);
return classname;
};
// hover样式
if (isHover && hoverValue !== -1) {
return "".concat(STAR_FIX).concat(getActiveClass(hoverValue));
}
// 点击样式
if (currValue !== -1) {
return "".concat(STAR_FIX).concat(getActiveClass(currValue));
}
// 默认样式
return STAR_FIX;
}, [currValue, hoverValue, isHover, count]);
// 点击选择标签
var handleSelectTag = useCallback(function (item, index) {
if (disabled) {
return;
}
var newLabels = _toConsumableArray(selectTags);
var currLabel = selectTags.find(function (_ref2) {
var key = _ref2.key;
return key === index;
});
// 如果已经存在,取消选中
if (currLabel) {
newLabels = newLabels.filter(function (_ref3) {
var key = _ref3.key;
return key !== index;
});
updateSelectTags(newLabels);
}
// 如果不存在,插入
else {
newLabels.push({
key: index,
text: item
});
updateSelectTags(newLabels);
}
onLabelChange && onLabelChange(item, newLabels.map(function (item) {
return item === null || item === void 0 ? void 0 : item.text;
}));
}, [selectTags]);
// label class
var getLabelClass = useCallback(function (index) {
var baseClass = "".concat(TAGS_FIX, "-item");
var isSelect = selectTags.find(function (_ref4) {
var key = _ref4.key;
return key === index;
});
return classNames(baseClass, isSelect ? TAGS_SELECT_FIX : '');
}, [tags, selectTags]);
// 渲染⭐
var renderStar = useCallback(function (value, index) {
var isCurrentHalf = allowHalf && !isHover && currValue - value > 0 && currValue - value < 1; // 是否半⭐
var isHoverHalf = allowHalf && hoverValue - value > 0 && hoverValue - value < 1; // 是否半⭐
var isHalf = isCurrentHalf || isHoverHalf;
var IconLeft = /*#__PURE__*/React.createElement("svg", {
className: "".concat(STAR_INNER_FIX, "-left-svg"),
viewBox: "0 0 16 16",
focusable: "false",
"data-icon": "star",
fill: "currentColor",
"aria-hidden": "true"
}, /*#__PURE__*/React.createElement("path", {
d: "M7.69013023,2.45403461 C7.790097,2.4047144 7.89613451,2.3814534 8.00053121,2.38163544 L7.99961383,11.7516344 L7.999,11.751 L5.23767823,13.2028077 C5.10138222,13.2744675 4.94526032,13.2991856 4.793494,13.2731336 C4.4124677,13.2077272 4.15660721,12.845822 4.22201361,12.4647957 L4.22201361,12.4647957 L4.75,9.389 L2.516094,7.21145716 C2.40579775,7.10394377 2.33404155,6.96305337 2.31194523,6.81061931 C2.25648476,6.42801877 2.52168419,6.07290015 2.90428473,6.01743969 L2.90428473,6.01743969 L5.991,5.57 L7.37214898,2.77195304 C7.4402962,2.6338947 7.55205843,2.52215456 7.69013023,2.45403461 Z"
}));
var IconRight = /*#__PURE__*/React.createElement("svg", {
className: "".concat(STAR_INNER_FIX, "-right-svg"),
viewBox: "0 0 16 16",
focusable: "false",
"data-icon": "star",
fill: "currentColor",
"aria-hidden": "true"
}, /*#__PURE__*/React.createElement("path", {
d: "M7.99986281,2.38163459 C8.25776985,2.38183708 8.50576461,2.52513046 8.62759969,2.77207707 L8.62759969,2.77207707 L10.008,5.57 L13.0948664,6.01814893 C13.2472813,6.04027642 13.3881443,6.11205203 13.4956302,6.2223549 C13.7654388,6.49923458 13.7597066,6.94241299 13.4828269,7.21222159 L13.4828269,7.21222159 L11.249,9.389 L11.7770174,12.4649763 C11.8030652,12.6167184 11.7783592,12.7728154 11.7067249,12.909097 C11.5268502,13.2513019 11.1036211,13.3828964 10.7614163,13.2030217 L10.7614163,13.2030217 L7.999,11.751 Z"
}));
var CustomIcon = renderCharacter && renderCharacter(index);
if (CustomIcon) {
IconLeft = /*#__PURE__*/React.createElement("div", {
className: "".concat(STAR_INNER_FIX, "-left-svg")
}, CustomIcon);
IconRight = /*#__PURE__*/React.createElement("div", {
className: "".concat(STAR_INNER_FIX, "-right-svg")
}, CustomIcon);
}
return /*#__PURE__*/React.createElement("div", {
key: value,
className: "".concat(getCurrClassName(value), " ").concat(disabled ? STAR_DISABLED : '')
}, /*#__PURE__*/React.createElement("div", {
className: "".concat(STAR_INNER_FIX, " ").concat(isHalf ? STAR_HALF_FIX : '')
}, /*#__PURE__*/React.createElement("div", {
className: "".concat(STAR_INNER_FIX, "-left"),
onMouseOver: function onMouseOver() {
return handleHoverChange(value, allowHalf);
},
onClick: function onClick() {
return handleChange(value, allowHalf);
}
}, IconLeft), /*#__PURE__*/React.createElement("div", {
onMouseOver: function onMouseOver() {
return handleHoverChange(value, false);
},
onClick: function onClick() {
return handleChange(value, false);
},
className: "".concat(STAR_INNER_FIX, "-right")
}, IconRight)));
}, [currValue, hoverValue, isHover, disabled, allowHalf]);
// 渲染辅助文案
var renderLabel = useCallback(function () {
var hoverLabel = tooltips[hoverValue | 0];
var currLabel = tooltips[currValue | 0];
var label = isHover ? hoverLabel : currLabel;
return /*#__PURE__*/React.createElement("span", {
className: LABEL_FIX
}, label);
}, [hoverValue, currValue, isHover]);
// 渲染标签
var renderTags = useCallback(function () {
if (!tags || tags.length === 0) {
return;
}
return /*#__PURE__*/React.createElement("div", {
className: TAGS_FIX
}, tags.map(function (item, index) {
return /*#__PURE__*/React.createElement("div", {
key: index,
className: classNames(getLabelClass(index), disabled ? TAGS_DISABLED : ''),
onClick: function onClick() {
return handleSelectTag(item, index);
}
}, renderTag ? renderTag(item, index) : item);
}));
}, [tags, selectTags, disabled]);
return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", {
className: classNames(className, prefixCls),
style: style,
onMouseEnter: function onMouseEnter() {
return handleFocus();
},
onMouseLeave: function onMouseLeave() {
return handleBlur();
}
}, list.map(function (value, index) {
return renderStar(value, index);
}), renderLabel()), renderTags());
};
export default Rate;