// Utils import { createNamespace, addUnit } from '../utils'; import { preventDefault } from '../utils/dom/event'; // Mixins import { TouchMixin } from '../mixins/touch'; import { FieldMixin } from '../mixins/field'; // Components import Icon from '../icon'; var _createNamespace = createNamespace('rate'), createComponent = _createNamespace[0], bem = _createNamespace[1]; function getRateStatus(value, index, allowHalf) { if (value >= index) { return 'full'; } if (value + 0.5 >= index && allowHalf) { return 'half'; } return 'void'; } export default createComponent({ mixins: [TouchMixin, FieldMixin], props: { size: [Number, String], color: String, gutter: [Number, String], readonly: Boolean, disabled: Boolean, allowHalf: Boolean, voidColor: String, iconPrefix: String, disabledColor: String, value: { type: Number, default: 0 }, icon: { type: String, default: 'star' }, voidIcon: { type: String, default: 'star-o' }, count: { type: [Number, String], default: 5 }, touchable: { type: Boolean, default: true } }, computed: { list: function list() { var list = []; for (var i = 1; i <= this.count; i++) { list.push(getRateStatus(this.value, i, this.allowHalf)); } return list; }, sizeWithUnit: function sizeWithUnit() { return addUnit(this.size); }, gutterWithUnit: function gutterWithUnit() { return addUnit(this.gutter); } }, mounted: function mounted() { this.bindTouchEvent(this.$el); }, methods: { select: function select(index) { if (!this.disabled && !this.readonly && index !== this.value) { this.$emit('input', index); this.$emit('change', index); } }, onTouchStart: function onTouchStart(event) { var _this = this; if (this.readonly || this.disabled || !this.touchable) { return; } this.touchStart(event); var rects = this.$refs.items.map(function (item) { return item.getBoundingClientRect(); }); var ranges = []; rects.forEach(function (rect, index) { if (_this.allowHalf) { ranges.push({ score: index + 0.5, left: rect.left }, { score: index + 1, left: rect.left + rect.width / 2 }); } else { ranges.push({ score: index + 1, left: rect.left }); } }); this.ranges = ranges; }, onTouchMove: function onTouchMove(event) { if (this.readonly || this.disabled || !this.touchable) { return; } this.touchMove(event); if (this.direction === 'horizontal') { preventDefault(event); var clientX = event.touches[0].clientX; this.select(this.getScoreByPosition(clientX)); } }, getScoreByPosition: function getScoreByPosition(x) { for (var i = this.ranges.length - 1; i > 0; i--) { if (x > this.ranges[i].left) { return this.ranges[i].score; } } return this.allowHalf ? 0.5 : 1; }, genStar: function genStar(status, index) { var _this2 = this; var h = this.$createElement; var icon = this.icon, color = this.color, count = this.count, voidIcon = this.voidIcon, disabled = this.disabled, voidColor = this.voidColor, disabledColor = this.disabledColor; var score = index + 1; var isFull = status === 'full'; var isVoid = status === 'void'; var style; if (this.gutterWithUnit && score !== +count) { style = { paddingRight: this.gutterWithUnit }; } return h("div", { "ref": "items", "refInFor": true, "key": index, "attrs": { "role": "radio", "tabindex": "0", "aria-setsize": count, "aria-posinset": score, "aria-checked": String(!isVoid) }, "style": style, "class": bem('item') }, [h(Icon, { "attrs": { "size": this.sizeWithUnit, "name": isFull ? icon : voidIcon, "color": disabled ? disabledColor : isFull ? color : voidColor, "classPrefix": this.iconPrefix, "data-score": score }, "class": bem('icon', { disabled: disabled, full: isFull }), "on": { "click": function click() { _this2.select(score); } } }), this.allowHalf && h(Icon, { "attrs": { "size": this.sizeWithUnit, "name": isVoid ? voidIcon : icon, "color": disabled ? disabledColor : isVoid ? voidColor : color, "classPrefix": this.iconPrefix, "data-score": score - 0.5 }, "class": bem('icon', ['half', { disabled: disabled, full: !isVoid }]), "on": { "click": function click() { _this2.select(score - 0.5); } } })]); } }, render: function render() { var _this3 = this; var h = arguments[0]; return h("div", { "class": bem({ readonly: this.readonly, disabled: this.disabled }), "attrs": { "tabindex": "0", "role": "radiogroup" } }, [this.list.map(function (status, index) { return _this3.genStar(status, index); })]); } });