import { createVNode, computed, ref, toRefs, reactive, watch, defineComponent, mergeProps } from "vue";
const inputNumberProps = {
  placeholder: {
    type: String
  },
  disabled: {
    type: Boolean,
    default: false
  },
  step: {
    type: Number,
    default: 1
  },
  max: {
    type: Number,
    default: Infinity
  },
  min: {
    type: Number,
    default: -Infinity
  },
  size: {
    type: String,
    default: ""
  },
  modelValue: {
    type: Number
  },
  precision: {
    type: Number
  }
};
function createBem(namespace, element, modifier) {
  let cls = namespace;
  if (element) {
    cls += `__${element}`;
  }
  if (modifier) {
    cls += `--${modifier}`;
  }
  return cls;
}
function useNamespace(block, needDot = false) {
  const namespace = needDot ? `.devui-${block}` : `devui-${block}`;
  const b = () => createBem(namespace);
  const e = (element) => element ? createBem(namespace, element) : "";
  const m = (modifier) => modifier ? createBem(namespace, "", modifier) : "";
  const em = (element, modifier) => element && modifier ? createBem(namespace, element, modifier) : "";
  return {
    b,
    e,
    m,
    em
  };
}
const ns$1 = useNamespace("input-number");
function IncIcon() {
  return createVNode("svg", {
    "class": ns$1.e("icon-arrow"),
    "width": "1em",
    "height": "1em",
    "viewBox": "0 0 16 16",
    "version": "1.1",
    "xmlns": "http://www.w3.org/2000/svg"
  }, [createVNode("g", {
    "stroke": "none",
    "stroke-width": "1",
    "fill": "none",
    "fill-rule": "evenodd"
  }, [createVNode("path", {
    "d": "M12.1464466,6.85355339 L8.35355339,10.6464466 C8.15829124,10.8417088 7.84170876,10.8417088 7.64644661,10.6464466           L3.85355339,6.85355339 C3.65829124,6.65829124 3.65829124,6.34170876 3.85355339,6.14644661 C3.94732158,6.05267842           4.07449854,6 4.20710678,6 L11.7928932,6 C12.0690356,6 12.2928932,6.22385763 12.2928932,6.5 C12.2928932,6.63260824           12.2402148,6.7597852 12.1464466,6.85355339 Z",
    "fill-rule": "nonzero"
  }, null)])]);
}
function DecIcon() {
  return createVNode("svg", {
    "class": ns$1.e("icon-arrow"),
    "width": "1em",
    "height": "1em",
    "viewBox": "0 0 16 16",
    "version": "1.1",
    "xmlns": "http://www.w3.org/2000/svg"
  }, [createVNode("g", {
    "stroke": "none",
    "stroke-width": "1",
    "fill": "none",
    "fill-rule": "evenodd"
  }, [createVNode("path", {
    "d": "M12.1464466,6.85355339 L8.35355339,10.6464466 C8.15829124,10.8417088 7.84170876,10.8417088 7.64644661,10.6464466           L3.85355339,6.85355339 C3.65829124,6.65829124 3.65829124,6.34170876 3.85355339,6.14644661 C3.94732158,6.05267842           4.07449854,6 4.20710678,6 L11.7928932,6 C12.0690356,6 12.2928932,6.22385763 12.2928932,6.5 C12.2928932,6.63260824           12.2402148,6.7597852 12.1464466,6.85355339 Z",
    "fill-rule": "nonzero"
  }, null)])]);
}
const isNumber = (value) => typeof value === "number";
const isUndefined = (value) => value === void 0;
const isNull = (value) => value === null;
const ns = useNamespace("input-number");
function useRender(props, ctx) {
  const { style, class: customClass, ...otherAttrs } = ctx.attrs;
  const customStyle = { style };
  const wrapClass = computed(() => [
    {
      [ns.b()]: true
    },
    customClass
  ]);
  const controlButtonsClass = computed(() => ({
    [ns.e("control-buttons")]: true,
    disabled: props.disabled,
    [ns.m(props.size)]: true
  }));
  const inputWrapClass = computed(() => ({
    [ns.e("input-wrap")]: true,
    [ns.m(props.size)]: true
  }));
  const inputInnerClass = computed(() => ({
    [ns.e("input-box")]: true,
    disabled: props.disabled
  }));
  return { wrapClass, customStyle, otherAttrs, controlButtonsClass, inputWrapClass, inputInnerClass };
}
function useExpose(ctx) {
  const inputRef = ref();
  const focus = () => {
    inputRef.value.focus();
  };
  const blur = () => {
    inputRef.value.blur();
  };
  const select = () => {
    inputRef.value.select();
  };
  ctx.expose({ focus, blur, select });
  return { inputRef };
}
function getPrecision(pre) {
  let precision = 0;
  if (isUndefined(pre)) {
    return precision;
  }
  const preString = pre.toString();
  const dotIndex = preString.indexOf(".");
  if (dotIndex !== -1) {
    precision = preString.length - dotIndex - 1;
  }
  return precision;
}
function useEvent(props, ctx, inputRef) {
  const { min, max, step, disabled } = toRefs(props);
  const state = reactive({
    currentValue: props.modelValue || "",
    userInputValue: void 0
  });
  const numPrecision = computed(() => {
    if (!isUndefined(props.precision)) {
      return props.precision;
    } else {
      return Math.max(getPrecision(props.modelValue), getPrecision(step.value));
    }
  });
  const inputVal = computed(() => {
    if (!isUndefined(state.userInputValue)) {
      return state.userInputValue;
    }
    let currentValue = state.currentValue;
    if (currentValue === "" || isUndefined(currentValue) || Number.isNaN(currentValue)) {
      return "";
    }
    if (isNumber(currentValue)) {
      currentValue = currentValue.toFixed(numPrecision.value);
    }
    return currentValue;
  });
  const toPrecision = (num) => {
    return Number.parseFloat(num.toFixed(numPrecision.value));
  };
  const computeByStep = (val, addOrNot = 1) => {
    if (!isNumber(val)) {
      return state.currentValue;
    }
    return toPrecision(val + step.value * addOrNot);
  };
  const correctValue = (value, shouldUpdate) => {
    if (value === "" || isUndefined(value) || isNull(value) || Number.isNaN(value)) {
      return void 0;
    }
    let newVal = Number(value);
    newVal = toPrecision(newVal);
    if (newVal > max.value || newVal < min.value) {
      newVal = newVal > max.value ? max.value : min.value;
      shouldUpdate && ctx.emit("update:modelValue", newVal);
    }
    return newVal;
  };
  const setCurrentValue = (value) => {
    const oldVal = state.currentValue;
    const newVal = correctValue(value);
    if (oldVal === newVal) {
      return;
    }
    state.userInputValue = void 0;
    ctx.emit("update:modelValue", newVal);
    ctx.emit("input", newVal);
    ctx.emit("change", newVal, oldVal);
    state.currentValue = newVal;
  };
  const minDisabled = computed(() => isNumber(state.currentValue) && computeByStep(state.currentValue, -1) < props.min);
  const maxDisabled = computed(() => isNumber(state.currentValue) && computeByStep(state.currentValue) > props.max);
  const onAdd = () => {
    if (disabled.value || maxDisabled.value) {
      return;
    }
    inputRef.value.focus();
    const newVal = computeByStep(state.currentValue || 0);
    setCurrentValue(newVal);
  };
  const onSubtract = () => {
    if (disabled.value || minDisabled.value) {
      return;
    }
    inputRef.value.focus();
    const newVal = computeByStep(state.currentValue || 0, -1);
    setCurrentValue(newVal);
  };
  watch(() => props.modelValue, (val) => {
    state.currentValue = correctValue(val, true);
    state.userInputValue = void 0;
  }, { immediate: true });
  const onInput = (event) => {
    const value = event.target.value;
    state.userInputValue = value;
  };
  const onChange = (event) => {
    const value = event.target.value;
    const newVal = value !== "" ? Number(value) : "";
    if (isNumber(newVal) && !Number.isNaN(newVal) || value === "") {
      setCurrentValue(newVal);
    }
    state.userInputValue = void 0;
  };
  return { inputVal, minDisabled, maxDisabled, onAdd, onSubtract, onInput, onChange };
}
var inputNumber = "";
var InputNumber = defineComponent({
  name: "DInputNumber",
  props: inputNumberProps,
  emits: ["update:modelValue", "change", "input"],
  setup(props, ctx) {
    const {
      disabled
    } = toRefs(props);
    const {
      wrapClass,
      customStyle,
      otherAttrs,
      controlButtonsClass,
      inputWrapClass,
      inputInnerClass
    } = useRender(props, ctx);
    const {
      inputRef
    } = useExpose(ctx);
    const {
      inputVal,
      minDisabled,
      maxDisabled,
      onAdd,
      onSubtract,
      onInput,
      onChange
    } = useEvent(props, ctx, inputRef);
    return () => createVNode("div", mergeProps({
      "class": wrapClass.value
    }, customStyle), [createVNode("div", {
      "class": controlButtonsClass.value
    }, [createVNode("span", {
      "class": ["control-button control-inc", {
        disabled: maxDisabled.value
      }],
      "onClick": onAdd
    }, [createVNode(IncIcon, null, null)]), createVNode("span", {
      "class": ["control-button control-dec", {
        disabled: minDisabled.value
      }],
      "onClick": onSubtract
    }, [createVNode(DecIcon, null, null)])]), createVNode("div", {
      "class": inputWrapClass.value
    }, [createVNode("input", mergeProps({
      "type": "number",
      "ref": inputRef,
      "value": inputVal.value,
      "placeholder": props.placeholder,
      "disabled": disabled.value,
      "class": inputInnerClass.value
    }, otherAttrs, {
      "onInput": onInput,
      "onChange": onChange
    }), null)])]);
  }
});
var index = {
  title: "InputNumber \u6570\u5B57\u8F93\u5165\u6846",
  category: "\u6570\u636E\u5F55\u5165",
  status: "50%",
  install(app) {
    app.component(InputNumber.name, InputNumber);
  }
};
export { InputNumber, index as default };
