{"version":3,"file":"input-number2.mjs","names":[],"sources":["../../../../../../packages/components/input-number/src/input-number.vue"],"sourcesContent":["<template>\n  <div\n    :class=\"[\n      ns.b(),\n      ns.m(inputNumberSize),\n      ns.is('disabled', inputNumberDisabled),\n      ns.is('without-controls', !controls),\n      ns.is('controls-right', controlsAtRight),\n      ns.is(align, !!align),\n    ]\"\n    @dragstart.prevent\n  >\n    <span\n      v-if=\"controls\"\n      v-repeat-click=\"decrease\"\n      role=\"button\"\n      :aria-label=\"t('el.inputNumber.decrease')\"\n      :class=\"[ns.e('decrease'), ns.is('disabled', minDisabled)]\"\n      @keydown.enter=\"decrease\"\n    >\n      <slot name=\"decrease-icon\">\n        <el-icon>\n          <arrow-down v-if=\"controlsAtRight\" />\n          <minus v-else />\n        </el-icon>\n      </slot>\n    </span>\n    <span\n      v-if=\"controls\"\n      v-repeat-click=\"increase\"\n      role=\"button\"\n      :aria-label=\"t('el.inputNumber.increase')\"\n      :class=\"[ns.e('increase'), ns.is('disabled', maxDisabled)]\"\n      @keydown.enter=\"increase\"\n    >\n      <slot name=\"increase-icon\">\n        <el-icon>\n          <arrow-up v-if=\"controlsAtRight\" />\n          <plus v-else />\n        </el-icon>\n      </slot>\n    </span>\n    <el-input\n      :id=\"id\"\n      ref=\"input\"\n      type=\"number\"\n      :step=\"step\"\n      :model-value=\"displayValue\"\n      :placeholder=\"placeholder\"\n      :readonly=\"readonly\"\n      :disabled=\"inputNumberDisabled\"\n      :size=\"inputNumberSize\"\n      :max=\"max\"\n      :min=\"min\"\n      :name=\"name\"\n      :aria-label=\"ariaLabel\"\n      :validate-event=\"false\"\n      :inputmode=\"inputmode\"\n      @keydown=\"handleKeydown\"\n      @blur=\"handleBlur\"\n      @focus=\"handleFocus\"\n      @input=\"handleInput\"\n      @change=\"handleInputChange\"\n    >\n      <template v-if=\"$slots.prefix\" #prefix>\n        <slot name=\"prefix\" />\n      </template>\n      <template v-if=\"$slots.suffix\" #suffix>\n        <slot name=\"suffix\" />\n      </template>\n    </el-input>\n  </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, onMounted, onUpdated, reactive, ref, watch } from 'vue'\nimport { isNil } from 'lodash-unified'\nimport { ElInput } from '@element-plus/components/input'\nimport { ElIcon } from '@element-plus/components/icon'\nimport {\n  useFormDisabled,\n  useFormItem,\n  useFormSize,\n} from '@element-plus/components/form'\nimport { vRepeatClick } from '@element-plus/directives'\nimport { useLocale, useNamespace } from '@element-plus/hooks'\nimport {\n  debugWarn,\n  getEventCode,\n  getEventKey,\n  isNumber,\n  isString,\n  isUndefined,\n  throwError,\n} from '@element-plus/utils'\nimport { ArrowDown, ArrowUp, Minus, Plus } from '@element-plus/icons-vue'\nimport {\n  CHANGE_EVENT,\n  EVENT_CODE,\n  INPUT_EVENT,\n  UPDATE_MODEL_EVENT,\n} from '@element-plus/constants'\nimport { inputNumberEmits } from './input-number'\n\nimport type { InputInstance } from '@element-plus/components/input'\nimport type { InputNumberProps } from './input-number'\n\ndefineOptions({\n  name: 'ElInputNumber',\n})\n\nconst props = withDefaults(defineProps<InputNumberProps>(), {\n  id: undefined,\n  disabled: undefined,\n  step: 1,\n  max: Number.MAX_SAFE_INTEGER,\n  min: Number.MIN_SAFE_INTEGER,\n  stepStrictly: false,\n  readonly: false,\n  controls: true,\n  controlsPosition: '',\n  valueOnClear: null,\n  validateEvent: true,\n  inputmode: undefined,\n  align: 'center',\n})\nconst emit = defineEmits(inputNumberEmits)\n\nconst { t } = useLocale()\nconst ns = useNamespace('input-number')\nconst input = ref<InputInstance>()\n\ninterface Data {\n  currentValue: number | null | undefined\n  userInput: null | number | string\n}\nconst data = reactive<Data>({\n  currentValue: props.modelValue,\n  userInput: null,\n})\n\nconst { formItem } = useFormItem()\n\nconst minDisabled = computed(\n  () => isNumber(props.modelValue) && props.modelValue <= props.min\n)\nconst maxDisabled = computed(\n  () => isNumber(props.modelValue) && props.modelValue >= props.max\n)\n\nconst numPrecision = computed(() => {\n  const stepPrecision = getPrecision(props.step)\n  if (!isUndefined(props.precision)) {\n    if (stepPrecision > props.precision) {\n      debugWarn(\n        'InputNumber',\n        'precision should not be less than the decimal places of step'\n      )\n    }\n    return props.precision\n  } else {\n    return Math.max(getPrecision(props.modelValue), stepPrecision)\n  }\n})\nconst controlsAtRight = computed(() => {\n  return props.controls && props.controlsPosition === 'right'\n})\n\nconst inputNumberSize = useFormSize()\nconst inputNumberDisabled = useFormDisabled()\n\nconst displayValue = computed(() => {\n  if (data.userInput !== null) {\n    return data.userInput\n  }\n  let currentValue: number | string | undefined | null = data.currentValue\n  if (isNil(currentValue)) return ''\n  if (isNumber(currentValue)) {\n    if (Number.isNaN(currentValue)) return ''\n    if (!isUndefined(props.precision)) {\n      currentValue = currentValue.toFixed(props.precision)\n    }\n  }\n  return currentValue\n})\nconst toPrecision = (num: number, pre?: number) => {\n  if (isUndefined(pre)) pre = numPrecision.value\n  if (pre === 0) return Math.round(num)\n  let snum = String(num)\n  const pointPos = snum.indexOf('.')\n  if (pointPos === -1) return num\n  const nums = snum.replace('.', '').split('')\n  const datum = nums[pointPos + pre]\n  if (!datum) return num\n  const length = snum.length\n  if (snum.charAt(length - 1) === '5') {\n    snum = `${snum.slice(0, Math.max(0, length - 1))}6`\n  }\n  return Number.parseFloat(Number(snum).toFixed(pre))\n}\nconst getPrecision = (value: number | null | undefined) => {\n  if (isNil(value)) return 0\n  const valueString = value.toString()\n  const dotPosition = valueString.indexOf('.')\n  let precision = 0\n  if (dotPosition !== -1) {\n    precision = valueString.length - dotPosition - 1\n  }\n  return precision\n}\nconst ensurePrecision = (val: number, coefficient: 1 | -1 = 1) => {\n  if (!isNumber(val)) return data.currentValue\n  if (val >= Number.MAX_SAFE_INTEGER && coefficient === 1) {\n    debugWarn(\n      'InputNumber',\n      'The value has reached the maximum safe integer limit.'\n    )\n    return val\n  } else if (val <= Number.MIN_SAFE_INTEGER && coefficient === -1) {\n    debugWarn(\n      'InputNumber',\n      'The value has reached the minimum safe integer limit.'\n    )\n    return val\n  }\n\n  // Solve the accuracy problem of JS decimal calculation by converting the value to integer.\n  return toPrecision(val + props.step * coefficient)\n}\nconst handleKeydown = (event: KeyboardEvent | Event) => {\n  const code = getEventCode(event as KeyboardEvent)\n  const key = getEventKey(event as KeyboardEvent)\n\n  if (props.disabledScientific && ['e', 'E'].includes(key)) {\n    event.preventDefault()\n    return\n  }\n\n  switch (code) {\n    case EVENT_CODE.up: {\n      event.preventDefault()\n      increase()\n      break\n    }\n    case EVENT_CODE.down: {\n      event.preventDefault()\n      decrease()\n      break\n    }\n  }\n}\nconst increase = () => {\n  if (props.readonly || inputNumberDisabled.value || maxDisabled.value) return\n  const value = Number(displayValue.value) || 0\n  const newVal = ensurePrecision(value)\n  setCurrentValue(newVal)\n  emit(INPUT_EVENT, data.currentValue)\n  setCurrentValueToModelValue()\n}\nconst decrease = () => {\n  if (props.readonly || inputNumberDisabled.value || minDisabled.value) return\n  const value = Number(displayValue.value) || 0\n  const newVal = ensurePrecision(value, -1)\n  setCurrentValue(newVal)\n  emit(INPUT_EVENT, data.currentValue)\n  setCurrentValueToModelValue()\n}\nconst verifyValue = (\n  value: number | string | null | undefined,\n  update?: boolean\n): number | null | undefined => {\n  const { max, min, step, precision, stepStrictly, valueOnClear } = props\n  if (max < min) {\n    throwError('InputNumber', 'min should not be greater than max.')\n  }\n  let newVal = Number(value)\n  if (isNil(value) || Number.isNaN(newVal)) {\n    return null\n  }\n  if (value === '') {\n    if (valueOnClear === null) {\n      return null\n    }\n    newVal = isString(valueOnClear) ? { min, max }[valueOnClear] : valueOnClear\n  }\n  if (stepStrictly) {\n    newVal = toPrecision(\n      Math.round(toPrecision(newVal / step)) * step,\n      precision\n    )\n    if (newVal !== value) {\n      update && emit(UPDATE_MODEL_EVENT, newVal)\n    }\n  }\n  if (!isUndefined(precision)) {\n    newVal = toPrecision(newVal, precision)\n  }\n  if (newVal > max || newVal < min) {\n    newVal = newVal > max ? max : min\n    update && emit(UPDATE_MODEL_EVENT, newVal)\n  }\n  return newVal\n}\nconst setCurrentValue = (\n  value: number | string | null | undefined,\n  emitChange = true\n) => {\n  const oldVal = data.currentValue\n  const newVal = verifyValue(value)\n  if (!emitChange) {\n    emit(UPDATE_MODEL_EVENT, newVal!)\n    return\n  }\n  data.userInput = null\n  if (oldVal === newVal && value) return\n  emit(UPDATE_MODEL_EVENT, newVal!)\n  if (oldVal !== newVal) {\n    emit(CHANGE_EVENT, newVal!, oldVal!)\n  }\n  if (props.validateEvent) {\n    formItem?.validate?.('change').catch((err) => debugWarn(err))\n  }\n  data.currentValue = newVal\n}\nconst handleInput = (value: string) => {\n  data.userInput = value\n  const newVal = value === '' ? null : Number(value)\n  emit(INPUT_EVENT, newVal)\n  setCurrentValue(newVal, false)\n}\nconst handleInputChange = (value: string) => {\n  const newVal = value !== '' ? Number(value) : ''\n  if ((isNumber(newVal) && !Number.isNaN(newVal)) || value === '') {\n    setCurrentValue(newVal)\n  }\n  setCurrentValueToModelValue()\n  data.userInput = null\n}\n\nconst focus = () => {\n  input.value?.focus?.()\n}\n\nconst blur = () => {\n  input.value?.blur?.()\n}\n\nconst handleFocus = (event: MouseEvent | FocusEvent) => {\n  emit('focus', event)\n}\n\nconst handleBlur = (event: MouseEvent | FocusEvent) => {\n  data.userInput = null\n  // When non-numeric content is entered into a numeric input box,\n  // the content displayed on the page is not cleared after the value is cleared. #18533\n  // https://bugzilla.mozilla.org/show_bug.cgi?id=1398528\n  if (data.currentValue === null && input.value?.input) {\n    input.value.input.value = ''\n  }\n  emit('blur', event)\n  if (props.validateEvent) {\n    formItem?.validate?.('blur').catch((err) => debugWarn(err))\n  }\n}\n\nconst setCurrentValueToModelValue = () => {\n  if (data.currentValue !== props.modelValue) {\n    data.currentValue = props.modelValue\n  }\n}\nconst handleWheel = (e: WheelEvent) => {\n  if (document.activeElement === e.target) e.preventDefault()\n}\n\nwatch(\n  () => props.modelValue,\n  (value, oldValue) => {\n    const newValue = verifyValue(value, true)\n    if (data.userInput === null && newValue !== oldValue) {\n      data.currentValue = newValue\n    }\n  },\n  { immediate: true }\n)\n\nwatch(\n  () => props.precision,\n  () => {\n    data.currentValue = verifyValue(props.modelValue)\n  }\n)\nonMounted(() => {\n  const { min, max, modelValue } = props\n  const innerInput = input.value?.input as HTMLInputElement\n  innerInput.setAttribute('role', 'spinbutton')\n  if (Number.isFinite(max)) {\n    innerInput.setAttribute('aria-valuemax', String(max))\n  } else {\n    innerInput.removeAttribute('aria-valuemax')\n  }\n  if (Number.isFinite(min)) {\n    innerInput.setAttribute('aria-valuemin', String(min))\n  } else {\n    innerInput.removeAttribute('aria-valuemin')\n  }\n  innerInput.setAttribute(\n    'aria-valuenow',\n    data.currentValue || data.currentValue === 0\n      ? String(data.currentValue)\n      : ''\n  )\n  innerInput.setAttribute('aria-disabled', String(inputNumberDisabled.value))\n  if (!isNumber(modelValue) && modelValue != null) {\n    let val: number | null = Number(modelValue)\n    if (Number.isNaN(val)) {\n      val = null\n    }\n    emit(UPDATE_MODEL_EVENT, val!)\n  }\n  innerInput.addEventListener('wheel', handleWheel, { passive: false })\n})\nonUpdated(() => {\n  const innerInput = input.value?.input\n  innerInput?.setAttribute('aria-valuenow', `${data.currentValue ?? ''}`)\n})\ndefineExpose({\n  /** @description get focus the input component */\n  focus,\n  /** @description remove focus the input component */\n  blur,\n})\n</script>\n"],"mappings":""}