import { ref, watch, computed, nextTick, defineComponent, vShow as _vShow, mergeProps as _mergeProps, createVNode as _createVNode, withDirectives as _withDirectives } from "vue"; import { isDef, addUnit, addNumber, truthProp, resetScroll, numericProp, formatNumber, getSizeStyle, preventDefault, createNamespace, callInterceptor, makeNumericProp, HAPTICS_FEEDBACK, LONG_PRESS_START_TIME } from "../utils/index.mjs"; import { useCustomFieldValue } from "@vant/use"; const [name, bem] = createNamespace("stepper"); const LONG_PRESS_INTERVAL = 200; const isEqual = (value1, value2) => String(value1) === String(value2); const stepperProps = { min: makeNumericProp(1), max: makeNumericProp(Infinity), name: makeNumericProp(""), step: makeNumericProp(1), theme: String, integer: Boolean, disabled: Boolean, showPlus: truthProp, showMinus: truthProp, showInput: truthProp, longPress: truthProp, autoFixed: truthProp, allowEmpty: Boolean, modelValue: numericProp, inputWidth: numericProp, buttonSize: numericProp, placeholder: String, disablePlus: Boolean, disableMinus: Boolean, disableInput: Boolean, beforeChange: Function, defaultValue: makeNumericProp(1), decimalLength: numericProp }; var stdin_default = defineComponent({ name, props: stepperProps, emits: ["plus", "blur", "minus", "focus", "change", "overlimit", "update:modelValue"], setup(props, { emit }) { const format = (value, autoFixed = true) => { const { min, max, allowEmpty, decimalLength } = props; if (allowEmpty && value === "") { return value; } value = formatNumber(String(value), !props.integer); value = value === "" ? 0 : +value; value = Number.isNaN(value) ? +min : value; value = autoFixed ? Math.max(Math.min(+max, value), +min) : value; if (isDef(decimalLength)) { value = value.toFixed(+decimalLength); } return value; }; const getInitialValue = () => { var _a; const defaultValue = (_a = props.modelValue) != null ? _a : props.defaultValue; const value = format(defaultValue); if (!isEqual(value, props.modelValue)) { emit("update:modelValue", value); } return value; }; let actionType; const inputRef = ref(); const current = ref(getInitialValue()); const minusDisabled = computed(() => props.disabled || props.disableMinus || +current.value <= +props.min); const plusDisabled = computed(() => props.disabled || props.disablePlus || +current.value >= +props.max); const inputStyle = computed(() => ({ width: addUnit(props.inputWidth), height: addUnit(props.buttonSize) })); const buttonStyle = computed(() => getSizeStyle(props.buttonSize)); const check = () => { const value = format(current.value); if (!isEqual(value, current.value)) { current.value = value; } }; const setValue = (value) => { if (props.beforeChange) { callInterceptor(props.beforeChange, { args: [value], done() { current.value = value; } }); } else { current.value = value; } }; const onChange = () => { if (actionType === "plus" && plusDisabled.value || actionType === "minus" && minusDisabled.value) { emit("overlimit", actionType); return; } const diff = actionType === "minus" ? -props.step : +props.step; const value = format(addNumber(+current.value, diff)); setValue(value); emit(actionType); }; const onInput = (event) => { const input = event.target; const { value } = input; const { decimalLength } = props; let formatted = formatNumber(String(value), !props.integer); if (isDef(decimalLength) && formatted.includes(".")) { const pair = formatted.split("."); formatted = `${pair[0]}.${pair[1].slice(0, +decimalLength)}`; } if (props.beforeChange) { input.value = String(current.value); } else if (!isEqual(value, formatted)) { input.value = formatted; } const isNumeric = formatted === String(+formatted); setValue(isNumeric ? +formatted : formatted); }; const onFocus = (event) => { var _a; if (props.disableInput) { (_a = inputRef.value) == null ? void 0 : _a.blur(); } else { emit("focus", event); } }; const onBlur = (event) => { const input = event.target; const value = format(input.value, props.autoFixed); input.value = String(value); current.value = value; nextTick(() => { emit("blur", event); resetScroll(); }); }; let isLongPress; let longPressTimer; const longPressStep = () => { longPressTimer = setTimeout(() => { onChange(); longPressStep(); }, LONG_PRESS_INTERVAL); }; const onTouchStart = () => { if (props.longPress) { isLongPress = false; clearTimeout(longPressTimer); longPressTimer = setTimeout(() => { isLongPress = true; onChange(); longPressStep(); }, LONG_PRESS_START_TIME); } }; const onTouchEnd = (event) => { if (props.longPress) { clearTimeout(longPressTimer); if (isLongPress) { preventDefault(event); } } }; const onMousedown = (event) => { if (props.disableInput) { preventDefault(event); } }; const createListeners = (type) => ({ onClick: (event) => { preventDefault(event); actionType = type; onChange(); }, onTouchstartPassive: () => { actionType = type; onTouchStart(); }, onTouchend: onTouchEnd, onTouchcancel: onTouchEnd }); watch(() => [props.max, props.min, props.integer, props.decimalLength], check); watch(() => props.modelValue, (value) => { if (!isEqual(value, current.value)) { current.value = format(value); } }); watch(current, (value) => { emit("update:modelValue", value); emit("change", value, { name: props.name }); }); useCustomFieldValue(() => props.modelValue); return () => _createVNode("div", { "role": "group", "class": bem([props.theme]) }, [_withDirectives(_createVNode("button", _mergeProps({ "type": "button", "style": buttonStyle.value, "class": [bem("minus", { disabled: minusDisabled.value }), { [HAPTICS_FEEDBACK]: !minusDisabled.value }], "aria-disabled": minusDisabled.value || void 0 }, createListeners("minus")), null), [[_vShow, props.showMinus]]), _withDirectives(_createVNode("input", { "ref": inputRef, "type": props.integer ? "tel" : "text", "role": "spinbutton", "class": bem("input"), "value": current.value, "style": inputStyle.value, "disabled": props.disabled, "readonly": props.disableInput, "inputmode": props.integer ? "numeric" : "decimal", "placeholder": props.placeholder, "autocomplete": "off", "aria-valuemax": props.max, "aria-valuemin": props.min, "aria-valuenow": current.value, "onBlur": onBlur, "onInput": onInput, "onFocus": onFocus, "onMousedown": onMousedown }, null), [[_vShow, props.showInput]]), _withDirectives(_createVNode("button", _mergeProps({ "type": "button", "style": buttonStyle.value, "class": [bem("plus", { disabled: plusDisabled.value }), { [HAPTICS_FEEDBACK]: !plusDisabled.value }], "aria-disabled": plusDisabled.value || void 0 }, createListeners("plus")), null), [[_vShow, props.showPlus]])]); } }); export { stdin_default as default, stepperProps };