{"version":3,"file":"input2.mjs","names":[],"sources":["../../../../../../packages/components/input/src/input.vue"],"sourcesContent":["<template>\n  <div\n    :class=\"[\n      containerKls,\n      {\n        [nsInput.bm('group', 'append')]: $slots.append,\n        [nsInput.bm('group', 'prepend')]: $slots.prepend,\n      },\n    ]\"\n    :style=\"containerStyle\"\n    @mouseenter=\"handleMouseEnter\"\n    @mouseleave=\"handleMouseLeave\"\n  >\n    <!-- input -->\n    <template v-if=\"type !== 'textarea'\">\n      <!-- prepend slot -->\n      <div v-if=\"$slots.prepend\" :class=\"nsInput.be('group', 'prepend')\">\n        <slot name=\"prepend\" />\n      </div>\n\n      <div ref=\"wrapperRef\" :class=\"wrapperKls\">\n        <!-- prefix slot -->\n        <span v-if=\"$slots.prefix || prefixIcon\" :class=\"nsInput.e('prefix')\">\n          <span :class=\"nsInput.e('prefix-inner')\">\n            <slot name=\"prefix\" />\n            <el-icon v-if=\"prefixIcon\" :class=\"nsInput.e('icon')\">\n              <component :is=\"prefixIcon\" />\n            </el-icon>\n          </span>\n        </span>\n\n        <input\n          :id=\"inputId\"\n          ref=\"input\"\n          :class=\"nsInput.e('inner')\"\n          v-bind=\"attrs\"\n          :name=\"name\"\n          :minlength=\"minlength\"\n          :maxlength=\"maxlength\"\n          :type=\"showPassword ? (passwordVisible ? 'text' : 'password') : type\"\n          :disabled=\"inputDisabled\"\n          :readonly=\"readonly\"\n          :autocomplete=\"autocomplete\"\n          :tabindex=\"tabindex\"\n          :aria-label=\"ariaLabel\"\n          :placeholder=\"placeholder\"\n          :style=\"inputStyle\"\n          :form=\"form\"\n          :autofocus=\"autofocus\"\n          :role=\"containerRole\"\n          :inputmode=\"inputmode\"\n          @compositionstart=\"handleCompositionStart\"\n          @compositionupdate=\"handleCompositionUpdate\"\n          @compositionend=\"handleCompositionEnd\"\n          @input=\"handleInput\"\n          @change=\"handleChange\"\n          @keydown=\"handleKeydown\"\n        />\n\n        <!-- suffix slot -->\n        <span v-if=\"suffixVisible\" :class=\"nsInput.e('suffix')\">\n          <span :class=\"nsInput.e('suffix-inner')\">\n            <template\n              v-if=\"!showClear || !showPwdVisible || !isWordLimitVisible\"\n            >\n              <slot name=\"suffix\" />\n              <el-icon v-if=\"suffixIcon\" :class=\"nsInput.e('icon')\">\n                <component :is=\"suffixIcon\" />\n              </el-icon>\n            </template>\n            <el-icon\n              v-if=\"showClear\"\n              :class=\"[nsInput.e('icon'), nsInput.e('clear')]\"\n              @mousedown.prevent=\"NOOP\"\n              @click=\"clear\"\n            >\n              <component :is=\"clearIcon\" />\n            </el-icon>\n            <el-icon\n              v-if=\"showPwdVisible\"\n              :class=\"[nsInput.e('icon'), nsInput.e('password')]\"\n              @click=\"handlePasswordVisible\"\n              @mousedown.prevent=\"NOOP\"\n              @mouseup.prevent=\"NOOP\"\n            >\n              <slot name=\"password-icon\" :visible=\"passwordVisible\">\n                <component :is=\"passwordIcon\" />\n              </slot>\n            </el-icon>\n            <span\n              v-if=\"isWordLimitVisible\"\n              :class=\"[\n                nsInput.e('count'),\n                nsInput.is('outside', wordLimitPosition === 'outside'),\n              ]\"\n            >\n              <span :class=\"nsInput.e('count-inner')\">\n                {{ textLength }} / {{ maxlength }}\n              </span>\n            </span>\n            <el-icon\n              v-if=\"validateState && validateIcon && needStatusIcon\"\n              :class=\"[\n                nsInput.e('icon'),\n                nsInput.e('validateIcon'),\n                nsInput.is('loading', validateState === 'validating'),\n              ]\"\n            >\n              <component :is=\"validateIcon\" />\n            </el-icon>\n          </span>\n        </span>\n      </div>\n\n      <!-- append slot -->\n      <div v-if=\"$slots.append\" :class=\"nsInput.be('group', 'append')\">\n        <slot name=\"append\" />\n      </div>\n    </template>\n\n    <!-- textarea -->\n    <template v-else>\n      <textarea\n        :id=\"inputId\"\n        ref=\"textarea\"\n        :class=\"[\n          nsTextarea.e('inner'),\n          nsInput.is('focus', isFocused),\n          nsTextarea.is('clearable', clearable),\n        ]\"\n        v-bind=\"attrs\"\n        :name=\"name\"\n        :minlength=\"minlength\"\n        :maxlength=\"maxlength\"\n        :tabindex=\"tabindex\"\n        :disabled=\"inputDisabled\"\n        :readonly=\"readonly\"\n        :autocomplete=\"autocomplete\"\n        :style=\"textareaStyle\"\n        :aria-label=\"ariaLabel\"\n        :placeholder=\"placeholder\"\n        :form=\"form\"\n        :autofocus=\"autofocus\"\n        :rows=\"rows\"\n        :role=\"containerRole\"\n        :inputmode=\"inputmode\"\n        @compositionstart=\"handleCompositionStart\"\n        @compositionupdate=\"handleCompositionUpdate\"\n        @compositionend=\"handleCompositionEnd\"\n        @input=\"handleInput\"\n        @focus=\"handleFocus\"\n        @blur=\"handleBlur\"\n        @change=\"handleChange\"\n        @keydown=\"handleKeydown\"\n      />\n      <el-icon\n        v-if=\"showClear\"\n        :class=\"[nsTextarea.e('icon'), nsTextarea.e('clear')]\"\n        @mousedown.prevent=\"NOOP\"\n        @click=\"clear\"\n      >\n        <component :is=\"clearIcon\" />\n      </el-icon>\n      <span\n        v-if=\"isWordLimitVisible\"\n        :style=\"countStyle\"\n        :class=\"[\n          nsInput.e('count'),\n          nsInput.is('outside', wordLimitPosition === 'outside'),\n        ]\"\n      >\n        {{ textLength }} / {{ maxlength }}\n      </span>\n    </template>\n  </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport {\n  computed,\n  nextTick,\n  onMounted,\n  ref,\n  shallowRef,\n  toRef,\n  useAttrs as useRawAttrs,\n  useSlots,\n  watch,\n} from 'vue'\nimport { useResizeObserver } from '@vueuse/core'\nimport { isNil } from 'lodash-unified'\nimport { ElIcon } from '@element-plus/components/icon'\nimport { Hide, View } from '@element-plus/icons-vue'\nimport {\n  useFormDisabled,\n  useFormItem,\n  useFormItemInputId,\n  useFormSize,\n} from '@element-plus/components/form'\nimport {\n  NOOP,\n  ValidateComponentsMap,\n  debugWarn,\n  isClient,\n  isObject,\n} from '@element-plus/utils'\nimport {\n  useAttrs,\n  useComposition,\n  useCursor,\n  useFocusController,\n  useNamespace,\n} from '@element-plus/hooks'\nimport {\n  CHANGE_EVENT,\n  INPUT_EVENT,\n  UPDATE_MODEL_EVENT,\n} from '@element-plus/constants'\nimport { calcTextareaHeight, looseToNumber } from './utils'\nimport { inputEmits, inputPropsDefaults } from './input'\n\nimport type { StyleValue } from 'vue'\nimport type { InputProps } from './input'\n\ntype TargetElement = HTMLInputElement | HTMLTextAreaElement\n\nconst COMPONENT_NAME = 'ElInput'\ndefineOptions({\n  name: COMPONENT_NAME,\n  inheritAttrs: false,\n})\nconst props = withDefaults(defineProps<InputProps>(), inputPropsDefaults)\nconst emit = defineEmits(inputEmits)\n\nconst rawAttrs = useRawAttrs()\nconst attrs = useAttrs()\nconst slots = useSlots()\n\nconst containerKls = computed(() => [\n  props.type === 'textarea' ? nsTextarea.b() : nsInput.b(),\n  nsInput.m(inputSize.value),\n  nsInput.is('disabled', inputDisabled.value),\n  nsInput.is('exceed', inputExceed.value),\n  {\n    [nsInput.b('group')]: slots.prepend || slots.append,\n    [nsInput.m('prefix')]: slots.prefix || props.prefixIcon,\n    [nsInput.m('suffix')]:\n      slots.suffix || props.suffixIcon || props.clearable || props.showPassword,\n    [nsInput.bm('suffix', 'password-clear')]:\n      showClear.value && showPwdVisible.value,\n    [nsInput.b('hidden')]: props.type === 'hidden',\n  },\n  rawAttrs.class,\n])\n\nconst wrapperKls = computed(() => [\n  nsInput.e('wrapper'),\n  nsInput.is('focus', isFocused.value),\n])\n\nconst { form: elForm, formItem: elFormItem } = useFormItem()\nconst { inputId } = useFormItemInputId(props, {\n  formItemContext: elFormItem,\n})\nconst inputSize = useFormSize()\nconst inputDisabled = useFormDisabled()\nconst nsInput = useNamespace('input')\nconst nsTextarea = useNamespace('textarea')\n\nconst input = shallowRef<HTMLInputElement>()\nconst textarea = shallowRef<HTMLTextAreaElement>()\n\nconst hovering = ref(false)\nconst passwordVisible = ref(false)\nconst countStyle = ref<StyleValue>()\nconst textareaCalcStyle = shallowRef(props.inputStyle)\n\nconst _ref = computed(() => input.value || textarea.value)\n\n// wrapperRef for type=\"text\", handleFocus and handleBlur for type=\"textarea\"\nconst { wrapperRef, isFocused, handleFocus, handleBlur } = useFocusController(\n  _ref,\n  {\n    disabled: inputDisabled,\n    afterBlur() {\n      if (props.validateEvent) {\n        elFormItem?.validate?.('blur').catch((err) => debugWarn(err))\n      }\n    },\n  }\n)\n\nconst needStatusIcon = computed(() => elForm?.statusIcon ?? false)\nconst validateState = computed(() => elFormItem?.validateState || '')\nconst validateIcon = computed(\n  () => validateState.value && ValidateComponentsMap[validateState.value]\n)\nconst passwordIcon = computed(() => (passwordVisible.value ? View : Hide))\nconst containerStyle = computed<StyleValue>(() => [\n  rawAttrs.style as StyleValue,\n])\nconst textareaStyle = computed<StyleValue>(() => [\n  props.inputStyle,\n  textareaCalcStyle.value,\n  { resize: props.resize },\n])\nconst nativeInputValue = computed(() =>\n  isNil(props.modelValue) ? '' : String(props.modelValue)\n)\nconst showClear = computed(\n  () =>\n    props.clearable &&\n    !inputDisabled.value &&\n    !props.readonly &&\n    !!nativeInputValue.value &&\n    (isFocused.value || hovering.value)\n)\nconst showPwdVisible = computed(\n  () => props.showPassword && !inputDisabled.value && !!nativeInputValue.value\n)\nconst isWordLimitVisible = computed(\n  () =>\n    props.showWordLimit &&\n    !!props.maxlength &&\n    (props.type === 'text' || props.type === 'textarea') &&\n    !inputDisabled.value &&\n    !props.readonly &&\n    !props.showPassword\n)\nconst textLength = computed(() => nativeInputValue.value.length)\nconst inputExceed = computed(\n  () =>\n    // show exceed style if length of initial value greater then maxlength\n    !!isWordLimitVisible.value && textLength.value > Number(props.maxlength)\n)\nconst suffixVisible = computed(\n  () =>\n    !!slots.suffix ||\n    !!props.suffixIcon ||\n    showClear.value ||\n    props.showPassword ||\n    isWordLimitVisible.value ||\n    (!!validateState.value && needStatusIcon.value)\n)\nconst hasModelModifiers = computed(\n  () => !!Object.keys(props.modelModifiers).length\n)\n\nconst [recordCursor, setCursor] = useCursor(input)\n\nuseResizeObserver(textarea, (entries) => {\n  onceInitSizeTextarea()\n  if (\n    !isWordLimitVisible.value ||\n    (props.resize !== 'both' && props.resize !== 'horizontal')\n  )\n    return\n  const entry = entries[0]\n  const { width } = entry.contentRect\n  countStyle.value = {\n    /** right: 100% - width + padding(22) - right(10) */\n    right: `calc(100% - ${width + 22 - 10}px)`,\n  }\n})\n\nconst resizeTextarea = () => {\n  const { type, autosize } = props\n\n  if (!isClient || type !== 'textarea' || !textarea.value) return\n\n  if (autosize) {\n    const minRows = isObject(autosize) ? autosize.minRows : undefined\n    const maxRows = isObject(autosize) ? autosize.maxRows : undefined\n    const textareaStyle = calcTextareaHeight(textarea.value, minRows, maxRows)\n\n    // If the scrollbar is displayed, the height of the textarea needs more space than the calculated height.\n    // If set textarea height in this case, the scrollbar will not hide.\n    // So we need to hide scrollbar first, and reset it in next tick.\n    // see https://github.com/element-plus/element-plus/issues/8825\n    textareaCalcStyle.value = {\n      overflowY: 'hidden',\n      ...textareaStyle,\n    }\n\n    nextTick(() => {\n      // NOTE: Force repaint to make sure the style set above is applied.\n      textarea.value!.offsetHeight\n      textareaCalcStyle.value = textareaStyle\n    })\n  } else {\n    textareaCalcStyle.value = {\n      minHeight: calcTextareaHeight(textarea.value).minHeight,\n    }\n  }\n}\n\nconst createOnceInitResize = (resizeTextarea: () => void) => {\n  let isInit = false\n  return () => {\n    if (isInit || !props.autosize) return\n    const isElHidden = textarea.value?.offsetParent === null\n    if (!isElHidden) {\n      setTimeout(resizeTextarea)\n      isInit = true\n    }\n  }\n}\n// fix: https://github.com/element-plus/element-plus/issues/12074\nconst onceInitSizeTextarea = createOnceInitResize(resizeTextarea)\n\nconst setNativeInputValue = () => {\n  const input = _ref.value\n  const formatterValue = props.formatter\n    ? props.formatter(nativeInputValue.value)\n    : nativeInputValue.value\n  if (!input || input.value === formatterValue || props.type === 'file') return\n  input.value = formatterValue\n}\n\nconst formatValue = (value: string) => {\n  const { trim, number } = props.modelModifiers\n  if (trim) {\n    value = value.trim()\n  }\n  if (number) {\n    value = `${looseToNumber(value)}`\n  }\n  if (props.formatter && props.parser) {\n    value = props.parser(value)\n  }\n  return value\n}\n\nconst handleInput = async (event: Event) => {\n  // should not emit input during composition\n  // see: https://github.com/ElemeFE/element/issues/10516\n  if (isComposing.value) return\n\n  const { lazy } = props.modelModifiers\n  let { value } = event.target as TargetElement\n  if (lazy) {\n    emit(INPUT_EVENT, value)\n    return\n  }\n\n  value = formatValue(value)\n\n  // hack for https://github.com/ElemeFE/element/issues/8548\n  // should remove the following line when we don't support IE\n  if (String(value) === nativeInputValue.value) {\n    // preserve native features while being compatible with #9501\n    if (props.formatter) {\n      setNativeInputValue()\n    }\n    return\n  }\n\n  recordCursor()\n  emit(UPDATE_MODEL_EVENT, value)\n  emit(INPUT_EVENT, value)\n\n  // ensure native input value is controlled\n  // see: https://github.com/ElemeFE/element/issues/12850\n  await nextTick()\n\n  if ((props.formatter && props.parser) || !hasModelModifiers.value) {\n    setNativeInputValue()\n  }\n  setCursor()\n}\n\nconst handleChange = async (event: Event) => {\n  let { value } = event.target as TargetElement\n\n  value = formatValue(value)\n  if (props.modelModifiers.lazy) {\n    emit(UPDATE_MODEL_EVENT, value)\n  }\n  emit(CHANGE_EVENT, value, event)\n\n  await nextTick()\n  setNativeInputValue()\n}\n\nconst {\n  isComposing,\n  handleCompositionStart,\n  handleCompositionUpdate,\n  handleCompositionEnd,\n} = useComposition({ emit, afterComposition: handleInput })\n\nconst handlePasswordVisible = () => {\n  passwordVisible.value = !passwordVisible.value\n}\n\nconst focus = () => _ref.value?.focus()\n\nconst blur = () => _ref.value?.blur()\n\nconst handleMouseLeave = (evt: MouseEvent) => {\n  hovering.value = false\n  emit('mouseleave', evt)\n}\n\nconst handleMouseEnter = (evt: MouseEvent) => {\n  hovering.value = true\n  emit('mouseenter', evt)\n}\n\nconst handleKeydown = (evt: KeyboardEvent) => {\n  emit('keydown', evt)\n}\n\nconst select = () => {\n  _ref.value?.select()\n}\n\nconst clear = (evt?: MouseEvent) => {\n  emit(UPDATE_MODEL_EVENT, '')\n  emit(CHANGE_EVENT, '')\n  emit('clear', evt)\n  emit(INPUT_EVENT, '')\n}\n\nwatch(\n  () => props.modelValue,\n  () => {\n    nextTick(() => resizeTextarea())\n    if (props.validateEvent) {\n      elFormItem?.validate?.('change').catch((err) => debugWarn(err))\n    }\n  }\n)\n\n// native input value is set explicitly\n// do not use v-model / :value in template\n// see: https://github.com/ElemeFE/element/issues/14521\nwatch(nativeInputValue, (newValue) => {\n  if (!_ref.value) {\n    return\n  }\n  const { trim, number } = props.modelModifiers\n  const elValue = _ref.value.value\n  const displayValue =\n    (number || props.type === 'number') && !/^0\\d/.test(elValue)\n      ? `${looseToNumber(elValue)}`\n      : elValue\n\n  if (displayValue === newValue) {\n    return\n  }\n\n  if (document.activeElement === _ref.value && _ref.value.type !== 'range') {\n    if (trim && displayValue.trim() === newValue) {\n      return\n    }\n  }\n\n  setNativeInputValue()\n})\n\n// when change between <input> and <textarea>,\n// update DOM dependent value and styles\n// https://github.com/ElemeFE/element/issues/14857\nwatch(\n  () => props.type,\n  async () => {\n    await nextTick()\n    setNativeInputValue()\n    resizeTextarea()\n  }\n)\n\nonMounted(() => {\n  if (!props.formatter && props.parser) {\n    debugWarn(\n      COMPONENT_NAME,\n      'If you set the parser, you also need to set the formatter.'\n    )\n  }\n  setNativeInputValue()\n  nextTick(resizeTextarea)\n})\n\ndefineExpose({\n  /** @description HTML input element */\n  input,\n  /** @description HTML textarea element */\n  textarea,\n  /** @description HTML element, input or textarea */\n  ref: _ref,\n  /** @description style of textarea. */\n  textareaStyle,\n\n  /** @description from props (used on unit test) */\n  autosize: toRef(props, 'autosize'),\n\n  /** @description is input composing */\n  isComposing,\n\n  /** @description HTML input element native method */\n  focus,\n  /** @description HTML input element native method */\n  blur,\n  /** @description HTML input element native method */\n  select,\n  /** @description clear input value */\n  clear,\n  /** @description resize textarea. */\n  resizeTextarea,\n})\n</script>\n"],"mappings":""}