import _mergeJSXProps2 from "@vue/babel-helper-vue-jsx-merge-props"; import _mergeJSXProps from "@vue/babel-helper-vue-jsx-merge-props"; import { createNamespace, isDef, addUnit } from '../utils'; import { resetScroll } from '../utils/dom/reset-scroll'; import { preventDefault } from '../utils/dom/event'; import { addNumber, formatNumber as _formatNumber } from '../utils/format/number'; import { isNaN } from '../utils/validate/number'; import { FieldMixin } from '../mixins/field'; var _createNamespace = createNamespace('stepper'), createComponent = _createNamespace[0], bem = _createNamespace[1]; var LONG_PRESS_START_TIME = 600; var LONG_PRESS_INTERVAL = 200; function equal(value1, value2) { return String(value1) === String(value2); } export default createComponent({ mixins: [FieldMixin], props: { value: null, theme: String, integer: Boolean, disabled: Boolean, allowEmpty: Boolean, inputWidth: [Number, String], buttonSize: [Number, String], asyncChange: Boolean, placeholder: String, disablePlus: Boolean, disableMinus: Boolean, disableInput: Boolean, decimalLength: [Number, String], name: { type: [Number, String], default: '' }, min: { type: [Number, String], default: 1 }, max: { type: [Number, String], default: Infinity }, step: { type: [Number, String], default: 1 }, defaultValue: { type: [Number, String], default: 1 }, showPlus: { type: Boolean, default: true }, showMinus: { type: Boolean, default: true }, showInput: { type: Boolean, default: true }, longPress: { type: Boolean, default: true } }, data: function data() { var _this$value; var defaultValue = (_this$value = this.value) != null ? _this$value : this.defaultValue; var value = this.format(defaultValue); if (!equal(value, this.value)) { this.$emit('input', value); } return { currentValue: value }; }, computed: { minusDisabled: function minusDisabled() { return this.disabled || this.disableMinus || this.currentValue <= +this.min; }, plusDisabled: function plusDisabled() { return this.disabled || this.disablePlus || this.currentValue >= +this.max; }, inputStyle: function inputStyle() { var style = {}; if (this.inputWidth) { style.width = addUnit(this.inputWidth); } if (this.buttonSize) { style.height = addUnit(this.buttonSize); } return style; }, buttonStyle: function buttonStyle() { if (this.buttonSize) { var size = addUnit(this.buttonSize); return { width: size, height: size }; } } }, watch: { max: 'check', min: 'check', integer: 'check', decimalLength: 'check', value: function value(val) { if (!equal(val, this.currentValue)) { this.currentValue = this.format(val); } }, currentValue: function currentValue(val) { this.$emit('input', val); this.$emit('change', val, { name: this.name }); } }, methods: { check: function check() { var val = this.format(this.currentValue); if (!equal(val, this.currentValue)) { this.currentValue = val; } }, // formatNumber illegal characters formatNumber: function formatNumber(value) { return _formatNumber(String(value), !this.integer); }, format: function format(value) { if (this.allowEmpty && value === '') { return value; } value = this.formatNumber(value); // format range value = value === '' ? 0 : +value; value = isNaN(value) ? this.min : value; value = Math.max(Math.min(this.max, value), this.min); // format decimal if (isDef(this.decimalLength)) { value = value.toFixed(this.decimalLength); } return value; }, onInput: function onInput(event) { var value = event.target.value; var formatted = this.formatNumber(value); // limit max decimal length if (isDef(this.decimalLength) && formatted.indexOf('.') !== -1) { var pair = formatted.split('.'); formatted = pair[0] + "." + pair[1].slice(0, this.decimalLength); } if (!equal(value, formatted)) { event.target.value = formatted; } // prefer number type if (formatted === String(+formatted)) { formatted = +formatted; } this.emitChange(formatted); }, emitChange: function emitChange(value) { if (this.asyncChange) { this.$emit('input', value); this.$emit('change', value, { name: this.name }); } else { this.currentValue = value; } }, onChange: function onChange() { var type = this.type; if (this[type + "Disabled"]) { this.$emit('overlimit', type); return; } var diff = type === 'minus' ? -this.step : +this.step; var value = this.format(addNumber(+this.currentValue, diff)); this.emitChange(value); this.$emit(type); }, onFocus: function onFocus(event) { // readonly not work in legacy mobile safari if (this.disableInput && this.$refs.input) { this.$refs.input.blur(); } else { this.$emit('focus', event); } }, onBlur: function onBlur(event) { var value = this.format(event.target.value); event.target.value = value; this.emitChange(value); this.$emit('blur', event); resetScroll(); }, longPressStep: function longPressStep() { var _this = this; this.longPressTimer = setTimeout(function () { _this.onChange(); _this.longPressStep(_this.type); }, LONG_PRESS_INTERVAL); }, onTouchStart: function onTouchStart() { var _this2 = this; if (!this.longPress) { return; } clearTimeout(this.longPressTimer); this.isLongPress = false; this.longPressTimer = setTimeout(function () { _this2.isLongPress = true; _this2.onChange(); _this2.longPressStep(); }, LONG_PRESS_START_TIME); }, onTouchEnd: function onTouchEnd(event) { if (!this.longPress) { return; } clearTimeout(this.longPressTimer); if (this.isLongPress) { preventDefault(event); } }, onMousedown: function onMousedown(event) { // fix mobile safari page scroll down issue // see: https://github.com/vant-ui/vant/issues/7690 if (this.disableInput) { event.preventDefault(); } } }, render: function render() { var _this3 = this; var h = arguments[0]; var createListeners = function createListeners(type) { return { on: { click: function click(e) { // disable double tap scrolling on mobile safari e.preventDefault(); _this3.type = type; _this3.onChange(); }, touchstart: function touchstart() { _this3.type = type; _this3.onTouchStart(); }, touchend: _this3.onTouchEnd, touchcancel: _this3.onTouchEnd } }; }; return h("div", { "class": bem([this.theme]) }, [h("button", _mergeJSXProps([{ "directives": [{ name: "show", value: this.showMinus }], "attrs": { "type": "button" }, "style": this.buttonStyle, "class": bem('minus', { disabled: this.minusDisabled }) }, createListeners('minus')])), h("input", { "directives": [{ name: "show", value: this.showInput }], "ref": "input", "attrs": { "type": this.integer ? 'tel' : 'text', "role": "spinbutton", "disabled": this.disabled, "readonly": this.disableInput, "inputmode": this.integer ? 'numeric' : 'decimal', "placeholder": this.placeholder, "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": this.currentValue }, "class": bem('input'), "domProps": { "value": this.currentValue }, "style": this.inputStyle, "on": { "input": this.onInput, "focus": this.onFocus, "blur": this.onBlur, "mousedown": this.onMousedown } }), h("button", _mergeJSXProps2([{ "directives": [{ name: "show", value: this.showPlus }], "attrs": { "type": "button" }, "style": this.buttonStyle, "class": bem('plus', { disabled: this.plusDisabled }) }, createListeners('plus')]))]); } });