var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name2 in all) __defProp(target, name2, { get: all[name2], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var stdin_exports = {}; __export(stdin_exports, { default: () => stdin_default, rateProps: () => rateProps }); module.exports = __toCommonJS(stdin_exports); var import_vue = require("vue"); var import_utils = require("../utils"); var import_use = require("@vant/use"); var import_use_refs = require("../composables/use-refs"); var import_use_touch = require("../composables/use-touch"); var import_icon = require("../icon"); const [name, bem] = (0, import_utils.createNamespace)("rate"); function getRateStatus(value, index, allowHalf, readonly) { if (value >= index) { return { status: "full", value: 1 }; } if (value + 0.5 >= index && allowHalf && !readonly) { return { status: "half", value: 0.5 }; } if (value + 1 >= index && allowHalf && readonly) { const cardinal = 10 ** 10; return { status: "half", value: Math.round((value - index + 1) * cardinal) / cardinal }; } return { status: "void", value: 0 }; } const rateProps = { size: import_utils.numericProp, icon: (0, import_utils.makeStringProp)("star"), color: String, count: (0, import_utils.makeNumericProp)(5), gutter: import_utils.numericProp, clearable: Boolean, readonly: Boolean, disabled: Boolean, voidIcon: (0, import_utils.makeStringProp)("star-o"), allowHalf: Boolean, voidColor: String, touchable: import_utils.truthProp, iconPrefix: String, modelValue: (0, import_utils.makeNumberProp)(0), disabledColor: String }; var stdin_default = (0, import_vue.defineComponent)({ name, props: rateProps, emits: ["change", "update:modelValue"], setup(props, { emit }) { const touch = (0, import_use_touch.useTouch)(); const [itemRefs, setItemRefs] = (0, import_use_refs.useRefs)(); const groupRef = (0, import_vue.ref)(); const unselectable = (0, import_vue.computed)(() => props.readonly || props.disabled); const untouchable = (0, import_vue.computed)(() => unselectable.value || !props.touchable); const list = (0, import_vue.computed)(() => Array(+props.count).fill("").map((_, i) => getRateStatus(props.modelValue, i + 1, props.allowHalf, props.readonly))); let ranges; let groupRefRect; let minRectTop = Number.MAX_SAFE_INTEGER; let maxRectTop = Number.MIN_SAFE_INTEGER; const updateRanges = () => { groupRefRect = (0, import_use.useRect)(groupRef); const rects = itemRefs.value.map(import_use.useRect); ranges = []; rects.forEach((rect, index) => { minRectTop = Math.min(rect.top, minRectTop); maxRectTop = Math.max(rect.top, maxRectTop); if (props.allowHalf) { ranges.push({ score: index + 0.5, left: rect.left, top: rect.top, height: rect.height }, { score: index + 1, left: rect.left + rect.width / 2, top: rect.top, height: rect.height }); } else { ranges.push({ score: index + 1, left: rect.left, top: rect.top, height: rect.height }); } }); }; const getScoreByPosition = (x, y) => { for (let i = ranges.length - 1; i > 0; i--) { if (y >= groupRefRect.top && y <= groupRefRect.bottom) { if (x > ranges[i].left && y >= ranges[i].top && y <= ranges[i].top + ranges[i].height) { return ranges[i].score; } } else { const curTop = y < groupRefRect.top ? minRectTop : maxRectTop; if (x > ranges[i].left && ranges[i].top === curTop) { return ranges[i].score; } } } return props.allowHalf ? 0.5 : 1; }; const select = (value) => { if (unselectable.value || value === props.modelValue) return; emit("update:modelValue", value); emit("change", value); }; const onTouchStart = (event) => { if (untouchable.value) { return; } touch.start(event); updateRanges(); }; const onTouchMove = (event) => { if (untouchable.value) { return; } touch.move(event); if (touch.isHorizontal() && !touch.isTap.value) { const { clientX, clientY } = event.touches[0]; (0, import_utils.preventDefault)(event); select(getScoreByPosition(clientX, clientY)); } }; const renderStar = (item, index) => { const { icon, size, color, count, gutter, voidIcon, disabled, voidColor, allowHalf, iconPrefix, disabledColor } = props; const score = index + 1; const isFull = item.status === "full"; const isVoid = item.status === "void"; const renderHalf = allowHalf && item.value > 0 && item.value < 1; let style; if (gutter && score !== +count) { style = { paddingRight: (0, import_utils.addUnit)(gutter) }; } const onClickItem = (event) => { updateRanges(); let value = allowHalf ? getScoreByPosition(event.clientX, event.clientY) : score; if (props.clearable && touch.isTap.value && value === props.modelValue) { value = 0; } select(value); }; return (0, import_vue.createVNode)("div", { "key": index, "ref": setItemRefs(index), "role": "radio", "style": style, "class": bem("item"), "tabindex": disabled ? void 0 : 0, "aria-setsize": count, "aria-posinset": score, "aria-checked": !isVoid, "onClick": onClickItem }, [(0, import_vue.createVNode)(import_icon.Icon, { "size": size, "name": isFull ? icon : voidIcon, "class": bem("icon", { disabled, full: isFull }), "color": disabled ? disabledColor : isFull ? color : voidColor, "classPrefix": iconPrefix }, null), renderHalf && (0, import_vue.createVNode)(import_icon.Icon, { "size": size, "style": { width: item.value + "em" }, "name": isVoid ? voidIcon : icon, "class": bem("icon", ["half", { disabled, full: !isVoid }]), "color": disabled ? disabledColor : isVoid ? voidColor : color, "classPrefix": iconPrefix }, null)]); }; (0, import_use.useCustomFieldValue)(() => props.modelValue); (0, import_use.useEventListener)("touchmove", onTouchMove, { target: groupRef }); return () => (0, import_vue.createVNode)("div", { "ref": groupRef, "role": "radiogroup", "class": bem({ readonly: props.readonly, disabled: props.disabled }), "tabindex": props.disabled ? void 0 : 0, "aria-disabled": props.disabled, "aria-readonly": props.readonly, "onTouchstartPassive": onTouchStart }, [list.value.map(renderStar)]); } });