You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
5.5 KiB

// 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);
})]);
}
});