import PropTypes from '../../_util/vue-types'; import classNames from 'classnames'; import KeyCode from '../../_util/KeyCode'; import { initDefaultProps, hasProp, getOptionProps, getComponentFromProp } from '../../_util/props-util'; import BaseMixin from '../../_util/BaseMixin'; import { getOffsetLeft } from './util'; import Star from './Star'; var rateProps = { disabled: PropTypes.bool, value: PropTypes.number, defaultValue: PropTypes.number, count: PropTypes.number, allowHalf: PropTypes.bool, allowClear: PropTypes.bool, prefixCls: PropTypes.string, character: PropTypes.any, tabIndex: PropTypes.number, autoFocus: PropTypes.bool }; function noop() {} export default { name: 'Rate', mixins: [BaseMixin], model: { prop: 'value', event: 'change' }, props: initDefaultProps(rateProps, { defaultValue: 0, count: 5, allowHalf: false, allowClear: true, prefixCls: 'rc-rate', tabIndex: 0, character: '★' }), data: function data() { var value = this.value; if (!hasProp(this, 'value')) { value = this.defaultValue; } return { sValue: value, focused: false, cleanedValue: null, hoverValue: undefined }; }, watch: { value: function value(val) { this.setState({ sValue: val }); } }, mounted: function mounted() { var _this = this; this.$nextTick(function () { if (_this.autoFocus && !_this.disabled) { _this.focus(); } }); }, methods: { onHover: function onHover(event, index) { var hoverValue = this.getStarValue(index, event.pageX); var cleanedValue = this.cleanedValue; if (hoverValue !== cleanedValue) { this.setState({ hoverValue: hoverValue, cleanedValue: null }); } this.$emit('hoverChange', hoverValue); }, onMouseLeave: function onMouseLeave() { this.setState({ hoverValue: undefined, cleanedValue: null }); this.$emit('hoverChange', undefined); }, onClick: function onClick(event, index) { var value = this.getStarValue(index, event.pageX); var isReset = false; if (this.allowClear) { isReset = value === this.sValue; } this.onMouseLeave(true); this.changeValue(isReset ? 0 : value); this.setState({ cleanedValue: isReset ? value : null }); }, onFocus: function onFocus() { this.setState({ focused: true }); this.$emit('focus'); }, onBlur: function onBlur() { this.setState({ focused: false }); this.$emit('blur'); }, onKeyDown: function onKeyDown(event) { var keyCode = event.keyCode; var count = this.count, allowHalf = this.allowHalf; var sValue = this.sValue; if (keyCode === KeyCode.RIGHT && sValue < count) { if (allowHalf) { sValue += 0.5; } else { sValue += 1; } this.changeValue(sValue); event.preventDefault(); } else if (keyCode === KeyCode.LEFT && sValue > 0) { if (allowHalf) { sValue -= 0.5; } else { sValue -= 1; } this.changeValue(sValue); event.preventDefault(); } this.$emit('keydown', event); }, getStarDOM: function getStarDOM(index) { return this.$refs['stars' + index].$el; }, getStarValue: function getStarValue(index, x) { var value = index + 1; if (this.allowHalf) { var starEle = this.getStarDOM(index); var leftDis = getOffsetLeft(starEle); var width = starEle.clientWidth; if (x - leftDis < width / 2) { value -= 0.5; } } return value; }, focus: function focus() { if (!this.disabled) { this.$refs.rateRef.focus(); } }, blur: function blur() { if (!this.disabled) { this.$refs.rateRef.blur(); } }, changeValue: function changeValue(value) { if (!hasProp(this, 'value')) { this.setState({ sValue: value }); } this.$emit('change', value); } }, render: function render() { var h = arguments[0]; var _getOptionProps = getOptionProps(this), count = _getOptionProps.count, allowHalf = _getOptionProps.allowHalf, prefixCls = _getOptionProps.prefixCls, disabled = _getOptionProps.disabled, tabIndex = _getOptionProps.tabIndex; var sValue = this.sValue, hoverValue = this.hoverValue, focused = this.focused; var stars = []; var disabledClass = disabled ? prefixCls + '-disabled' : ''; var character = getComponentFromProp(this, 'character'); for (var index = 0; index < count; index++) { var starProps = { props: { index: index, count: count, disabled: disabled, prefixCls: prefixCls + '-star', allowHalf: allowHalf, value: hoverValue === undefined ? sValue : hoverValue, character: character, focused: focused }, on: { click: this.onClick, hover: this.onHover }, key: index, ref: 'stars' + index }; stars.push(h(Star, starProps)); } return h( 'ul', { 'class': classNames(prefixCls, disabledClass), on: { 'mouseleave': disabled ? noop : this.onMouseLeave, 'focus': disabled ? noop : this.onFocus, 'blur': disabled ? noop : this.onBlur, 'keydown': disabled ? noop : this.onKeyDown }, attrs: { tabIndex: disabled ? -1 : tabIndex, role: 'radiogroup' }, ref: 'rateRef' }, [stars] ); } };