"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const aria = require("../../../constants/aria.js");
const event = require("../../../constants/event.js");
const event$1 = require("../../../utils/dom/event.js");
const types = require("../../../utils/types.js");
const error = require("../../../utils/error.js");
const index = require("../../../hooks/use-locale/index.js");
const index$1 = require("../../../hooks/use-namespace/index.js");
const index$2 = require("../../icon/index.js");
const useFormCommonProps = require("../../form/src/hooks/use-form-common-props.js");
const useFormItem = require("../../form/src/hooks/use-form-item.js");
const index$5 = require("../../input/index.js");
const index$4 = require("../../../directives/repeat-click/index.js");
const inputNumber = require("./input-number.js");
const index$3 = require("../../../../../@element-plus/icons-vue/dist/index.js");
const Vue = require("vue");
const isNil = require("../../../../../lodash-es/isNil.js");
const shared_esmBundler = require("../../../../../@vue/shared/dist/shared.esm-bundler.js");
const _hoisted_1 = ["aria-label"];
const _hoisted_2 = ["aria-label"];
var input_number_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ Vue.defineComponent({
  name: "ElInputNumber",
  __name: "input-number",
  props: inputNumber.inputNumberProps,
  emits: inputNumber.inputNumberEmits,
  setup(__props, { expose: __expose, emit: __emit }) {
    const props = __props;
    const emit = __emit;
    const { t } = index.useLocale();
    const ns = index$1.useNamespace("input-number");
    const input = Vue.ref();
    const data = Vue.reactive({
      currentValue: props.modelValue,
      userInput: null
    });
    const { formItem } = useFormItem.useFormItem();
    const minDisabled = Vue.computed(() => types.isNumber(props.modelValue) && props.modelValue <= props.min);
    const maxDisabled = Vue.computed(() => types.isNumber(props.modelValue) && props.modelValue >= props.max);
    const numPrecision = Vue.computed(() => {
      const stepPrecision = getPrecision(props.step);
      if (!types.isUndefined(props.precision)) {
        if (stepPrecision > props.precision) error.debugWarn("InputNumber", "precision should not be less than the decimal places of step");
        return props.precision;
      } else return Math.max(getPrecision(props.modelValue), stepPrecision);
    });
    const controlsAtRight = Vue.computed(() => {
      return props.controls && props.controlsPosition === "right";
    });
    const inputNumberSize = useFormCommonProps.useFormSize();
    const inputNumberDisabled = useFormCommonProps.useFormDisabled();
    const displayValue = Vue.computed(() => {
      if (data.userInput !== null) return data.userInput;
      let currentValue = data.currentValue;
      if (isNil.default(currentValue)) return "";
      if (types.isNumber(currentValue)) {
        if (Number.isNaN(currentValue)) return "";
        if (!types.isUndefined(props.precision)) currentValue = currentValue.toFixed(props.precision);
      }
      return currentValue;
    });
    const toPrecision = (num, pre) => {
      if (types.isUndefined(pre)) pre = numPrecision.value;
      if (pre === 0) return Math.round(num);
      let snum = String(num);
      const pointPos = snum.indexOf(".");
      if (pointPos === -1) return num;
      if (!snum.replace(".", "").split("")[pointPos + pre]) return num;
      const length = snum.length;
      if (snum.charAt(length - 1) === "5") snum = `${snum.slice(0, Math.max(0, length - 1))}6`;
      return Number.parseFloat(Number(snum).toFixed(pre));
    };
    const getPrecision = (value) => {
      if (isNil.default(value)) return 0;
      const valueString = value.toString();
      const dotPosition = valueString.indexOf(".");
      let precision = 0;
      if (dotPosition !== -1) precision = valueString.length - dotPosition - 1;
      return precision;
    };
    const ensurePrecision = (val, coefficient = 1) => {
      if (!types.isNumber(val)) return data.currentValue;
      if (val >= Number.MAX_SAFE_INTEGER && coefficient === 1) {
        error.debugWarn("InputNumber", "The value has reached the maximum safe integer limit.");
        return val;
      } else if (val <= Number.MIN_SAFE_INTEGER && coefficient === -1) {
        error.debugWarn("InputNumber", "The value has reached the minimum safe integer limit.");
        return val;
      }
      return toPrecision(val + props.step * coefficient);
    };
    const handleKeydown = (event2) => {
      const code = event$1.getEventCode(event2);
      const key = event$1.getEventKey(event2);
      if (props.disabledScientific && ["e", "E"].includes(key)) {
        event2.preventDefault();
        return;
      }
      switch (code) {
        case aria.EVENT_CODE.up:
          event2.preventDefault();
          increase();
          break;
        case aria.EVENT_CODE.down:
          event2.preventDefault();
          decrease();
          break;
      }
    };
    const increase = () => {
      if (props.readonly || inputNumberDisabled.value || maxDisabled.value) return;
      setCurrentValue(ensurePrecision(Number(displayValue.value) || 0));
      emit(event.INPUT_EVENT, data.currentValue);
      setCurrentValueToModelValue();
    };
    const decrease = () => {
      if (props.readonly || inputNumberDisabled.value || minDisabled.value) return;
      setCurrentValue(ensurePrecision(Number(displayValue.value) || 0, -1));
      emit(event.INPUT_EVENT, data.currentValue);
      setCurrentValueToModelValue();
    };
    const verifyValue = (value, update) => {
      const { max, min, step, precision, stepStrictly, valueOnClear } = props;
      if (max < min) error.throwError("InputNumber", "min should not be greater than max.");
      let newVal = Number(value);
      if (isNil.default(value) || Number.isNaN(newVal)) return null;
      if (value === "") {
        if (valueOnClear === null) return null;
        newVal = shared_esmBundler.isString(valueOnClear) ? {
          min,
          max
        }[valueOnClear] : valueOnClear;
      }
      if (stepStrictly) {
        newVal = toPrecision(Math.round(toPrecision(newVal / step)) * step, precision);
        if (newVal !== value) update && emit(event.UPDATE_MODEL_EVENT, newVal);
      }
      if (!types.isUndefined(precision)) newVal = toPrecision(newVal, precision);
      if (newVal > max || newVal < min) {
        newVal = newVal > max ? max : min;
        update && emit(event.UPDATE_MODEL_EVENT, newVal);
      }
      return newVal;
    };
    const setCurrentValue = (value, emitChange = true) => {
      var _a;
      const oldVal = data.currentValue;
      const newVal = verifyValue(value);
      if (!emitChange) {
        emit(event.UPDATE_MODEL_EVENT, newVal);
        return;
      }
      data.userInput = null;
      if (oldVal === newVal && value) return;
      emit(event.UPDATE_MODEL_EVENT, newVal);
      if (oldVal !== newVal) emit(event.CHANGE_EVENT, newVal, oldVal);
      if (props.validateEvent) (_a = formItem == null ? void 0 : formItem.validate) == null ? void 0 : _a.call(formItem, "change").catch((err) => error.debugWarn(err));
      data.currentValue = newVal;
    };
    const handleInput = (value) => {
      data.userInput = value;
      const newVal = value === "" ? null : Number(value);
      emit(event.INPUT_EVENT, newVal);
      setCurrentValue(newVal, false);
    };
    const handleInputChange = (value) => {
      const newVal = value !== "" ? Number(value) : "";
      if (types.isNumber(newVal) && !Number.isNaN(newVal) || value === "") setCurrentValue(newVal);
      setCurrentValueToModelValue();
      data.userInput = null;
    };
    const focus = () => {
      var _a, _b;
      (_b = (_a = input.value) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
    };
    const blur = () => {
      var _a, _b;
      (_b = (_a = input.value) == null ? void 0 : _a.blur) == null ? void 0 : _b.call(_a);
    };
    const handleFocus = (event2) => {
      emit("focus", event2);
    };
    const handleBlur = (event2) => {
      var _a, _b;
      data.userInput = null;
      if (data.currentValue === null && ((_a = input.value) == null ? void 0 : _a.input)) input.value.input.value = "";
      emit("blur", event2);
      if (props.validateEvent) (_b = formItem == null ? void 0 : formItem.validate) == null ? void 0 : _b.call(formItem, "blur").catch((err) => error.debugWarn(err));
    };
    const setCurrentValueToModelValue = () => {
      if (data.currentValue !== props.modelValue) data.currentValue = props.modelValue;
    };
    const handleWheel = (e) => {
      if (document.activeElement === e.target) e.preventDefault();
    };
    Vue.watch(() => props.modelValue, (value, oldValue) => {
      const newValue = verifyValue(value, true);
      if (data.userInput === null && newValue !== oldValue) data.currentValue = newValue;
    }, { immediate: true });
    Vue.watch(() => props.precision, () => {
      data.currentValue = verifyValue(props.modelValue);
    });
    Vue.onMounted(() => {
      var _a;
      const { min, max, modelValue } = props;
      const innerInput = (_a = input.value) == null ? void 0 : _a.input;
      innerInput.setAttribute("role", "spinbutton");
      if (Number.isFinite(max)) innerInput.setAttribute("aria-valuemax", String(max));
      else innerInput.removeAttribute("aria-valuemax");
      if (Number.isFinite(min)) innerInput.setAttribute("aria-valuemin", String(min));
      else innerInput.removeAttribute("aria-valuemin");
      innerInput.setAttribute("aria-valuenow", data.currentValue || data.currentValue === 0 ? String(data.currentValue) : "");
      innerInput.setAttribute("aria-disabled", String(inputNumberDisabled.value));
      if (!types.isNumber(modelValue) && modelValue != null) {
        let val = Number(modelValue);
        if (Number.isNaN(val)) val = null;
        emit(event.UPDATE_MODEL_EVENT, val);
      }
      innerInput.addEventListener("wheel", handleWheel, { passive: false });
    });
    Vue.onUpdated(() => {
      var _a, _b;
      (_b = (_a = input.value) == null ? void 0 : _a.input) == null ? void 0 : _b.setAttribute("aria-valuenow", `${data.currentValue ?? ""}`);
    });
    __expose({
      focus,
      blur
    });
    return (_ctx, _cache) => {
      return Vue.openBlock(), Vue.createElementBlock("div", {
        class: Vue.normalizeClass([
          Vue.unref(ns).b(),
          Vue.unref(ns).m(Vue.unref(inputNumberSize)),
          Vue.unref(ns).is("disabled", Vue.unref(inputNumberDisabled)),
          Vue.unref(ns).is("without-controls", !__props.controls),
          Vue.unref(ns).is("controls-right", controlsAtRight.value),
          Vue.unref(ns).is(__props.align, !!__props.align)
        ]),
        onDragstart: _cache[0] || (_cache[0] = Vue.withModifiers(() => {
        }, ["prevent"]))
      }, [
        __props.controls ? Vue.withDirectives((Vue.openBlock(), Vue.createElementBlock("span", {
          key: 0,
          role: "button",
          "aria-label": Vue.unref(t)("el.inputNumber.decrease"),
          class: Vue.normalizeClass([Vue.unref(ns).e("decrease"), Vue.unref(ns).is("disabled", minDisabled.value)]),
          onKeydown: Vue.withKeys(decrease, ["enter"])
        }, [Vue.renderSlot(_ctx.$slots, "decrease-icon", {}, () => [Vue.createVNode(Vue.unref(index$2.ElIcon), null, {
          default: Vue.withCtx(() => [controlsAtRight.value ? (Vue.openBlock(), Vue.createBlock(Vue.unref(index$3.ArrowDown), { key: 0 })) : (Vue.openBlock(), Vue.createBlock(Vue.unref(index$3.Minus), { key: 1 }))]),
          _: 1
        })])], 42, _hoisted_1)), [[Vue.unref(index$4.vRepeatClick), decrease]]) : Vue.createCommentVNode("v-if", true),
        __props.controls ? Vue.withDirectives((Vue.openBlock(), Vue.createElementBlock("span", {
          key: 1,
          role: "button",
          "aria-label": Vue.unref(t)("el.inputNumber.increase"),
          class: Vue.normalizeClass([Vue.unref(ns).e("increase"), Vue.unref(ns).is("disabled", maxDisabled.value)]),
          onKeydown: Vue.withKeys(increase, ["enter"])
        }, [Vue.renderSlot(_ctx.$slots, "increase-icon", {}, () => [Vue.createVNode(Vue.unref(index$2.ElIcon), null, {
          default: Vue.withCtx(() => [controlsAtRight.value ? (Vue.openBlock(), Vue.createBlock(Vue.unref(index$3.ArrowUp), { key: 0 })) : (Vue.openBlock(), Vue.createBlock(Vue.unref(index$3.Plus), { key: 1 }))]),
          _: 1
        })])], 42, _hoisted_2)), [[Vue.unref(index$4.vRepeatClick), increase]]) : Vue.createCommentVNode("v-if", true),
        Vue.createVNode(Vue.unref(index$5.ElInput), {
          id: __props.id,
          ref_key: "input",
          ref: input,
          type: "number",
          step: __props.step,
          "model-value": displayValue.value,
          placeholder: __props.placeholder,
          readonly: __props.readonly,
          disabled: Vue.unref(inputNumberDisabled),
          size: Vue.unref(inputNumberSize),
          max: __props.max,
          min: __props.min,
          name: __props.name,
          "aria-label": __props.ariaLabel,
          "validate-event": false,
          inputmode: __props.inputmode,
          onKeydown: handleKeydown,
          onBlur: handleBlur,
          onFocus: handleFocus,
          onInput: handleInput,
          onChange: handleInputChange
        }, Vue.createSlots({ _: 2 }, [_ctx.$slots.prefix ? {
          name: "prefix",
          fn: Vue.withCtx(() => [Vue.renderSlot(_ctx.$slots, "prefix")]),
          key: "0"
        } : void 0, _ctx.$slots.suffix ? {
          name: "suffix",
          fn: Vue.withCtx(() => [Vue.renderSlot(_ctx.$slots, "suffix")]),
          key: "1"
        } : void 0]), 1032, [
          "id",
          "step",
          "model-value",
          "placeholder",
          "readonly",
          "disabled",
          "size",
          "max",
          "min",
          "name",
          "aria-label",
          "inputmode"
        ])
      ], 34);
    };
  }
});
exports.default = input_number_vue_vue_type_script_setup_true_lang_default;
