text: 'use strict';
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  var vue = require('vue');
  var shared = require('@vue/shared');
  var lodashUnified = require('lodash-unified');
  var core = require('@vueuse/core');
  require('../../../constants/index.js');
  require('../../../utils/index.js');
  require('../../../hooks/index.js');
  require('../../../tokens/index.js');
  var index = require('../../../hooks/use-locale/index.js');
  var index$1 = require('../../../hooks/use-namespace/index.js');
  var form = require('../../../tokens/form.js');
  var index$2 = require('../../../hooks/use-common-props/index.js');
  var error = require('../../../utils/error.js');
  var event = require('../../../constants/event.js');
  var scroll = require('../../../utils/dom/scroll.js');
  var aria = require('../../../constants/aria.js');
  var i18n = require('../../../utils/i18n.js');
  
  function useSelectStates(props) {
    const { t } = index.useLocale();
    return vue.reactive({
      options: /* @__PURE__ */ new Map(),
      cachedOptions: /* @__PURE__ */ new Map(),
      createdLabel: null,
      createdSelected: false,
      selected: props.multiple ? [] : {},
      inputLength: 20,
      inputWidth: 0,
      initialInputHeight: 0,
      optionsCount: 0,
      filteredOptionsCount: 0,
      visible: false,
      softFocus: false,
      selectedLabel: "",
      hoverIndex: -1,
      query: "",
      previousQuery: null,
      inputHovering: false,
      cachedPlaceHolder: "",
      currentPlaceholder: t("el.select.placeholder"),
      menuVisibleOnFocus: false,
      isOnComposition: false,
      isSilentBlur: false,
      prefixWidth: 11,
      tagInMultiLine: false
    });
  }
  const useSelect = (props, states, ctx) => {
    const { t } = index.useLocale();
    const ns = index$1.useNamespace("select");
    const reference = vue.ref(null);
    const input = vue.ref(null);
    const tooltipRef = vue.ref(null);
    const tags = vue.ref(null);
    const selectWrapper = vue.ref(null);
    const scrollbar = vue.ref(null);
    const hoverOption = vue.ref(-1);
    const queryChange = vue.shallowRef({ query: "" });
    const groupQueryChange = vue.shallowRef("");
    const elForm = vue.inject(form.formContextKey, {});
    const elFormItem = vue.inject(form.formItemContextKey, {});
    const readonly = vue.computed(() => !props.filterable || props.multiple || !states.visible);
    const selectDisabled = vue.computed(() => props.disabled || elForm.disabled);
    const showClose = vue.computed(() => {
      const hasValue = props.multiple ? Array.isArray(props.modelValue) && props.modelValue.length > 0 : props.modelValue !== void 0 && props.modelValue !== null && props.modelValue !== "";
      const criteria = props.clearable && !selectDisabled.value && states.inputHovering && hasValue;
      return criteria;
    });
    const iconComponent = vue.computed(() => props.remote && props.filterable ? "" : props.suffixIcon);
    const iconReverse = vue.computed(() => ns.is("reverse", iconComponent.value && states.visible));
    const debounce = vue.computed(() => props.remote ? 300 : 0);
    const emptyText = vue.computed(() => {
      if (props.loading) {
        return props.loadingText || t("el.select.loading");
      } else {
        if (props.remote && states.query === "" && states.options.size === 0)
          return false;
        if (props.filterable && states.query && states.options.size > 0 && states.filteredOptionsCount === 0) {
          return props.noMatchText || t("el.select.noMatch");
        }
        if (states.options.size === 0) {
          return props.noDataText || t("el.select.noData");
        }
      }
      return null;
    });
    const optionsArray = vue.computed(() => Array.from(states.options.values()));
    const cachedOptionsArray = vue.computed(() => Array.from(states.cachedOptions.values()));
    const showNewOption = vue.computed(() => {
      const hasExistingOption = optionsArray.value.filter((option) => {
        return !option.created;
      }).some((option) => {
        return option.currentLabel === states.query;
      });
      return props.filterable && props.allowCreate && states.query !== "" && !hasExistingOption;
    });
    const selectSize = index$2.useSize();
    const collapseTagSize = vue.computed(() => ["small"].includes(selectSize.value) ? "small" : "default");
    const dropMenuVisible = vue.computed({
      get() {
        return states.visible && emptyText.value !== false;
      },
      set(val) {
        states.visible = val;
      }
    });
    vue.watch(() => selectDisabled.value, () => {
      vue.nextTick(() => {
        resetInputHeight();
      });
    });
    vue.watch(() => props.placeholder, (val) => {
      states.cachedPlaceHolder = states.currentPlaceholder = val;
    });
    vue.watch(() => props.modelValue, (val, oldVal) => {
      var _a;
      if (props.multiple) {
        resetInputHeight();
        if (val && val.length > 0 || input.value && states.query !== "") {
          states.currentPlaceholder = "";
        } else {
          states.currentPlaceholder = states.cachedPlaceHolder;
        }
        if (props.filterable && !props.reserveKeyword) {
          states.query = "";
          handleQueryChange(states.query);
        }
      }
      setSelected();
      if (props.filterable && !props.multiple) {
        states.inputLength = 20;
      }
      if (!lodashUnified.isEqual(val, oldVal)) {
        (_a = elFormItem.validate) == null ? void 0 : _a.call(elFormItem, "change").catch((err) => error.debugWarn(err));
      }
    }, {
      flush: "post",
      deep: true
    });
    vue.watch(() => states.visible, (val) => {
      var _a, _b, _c;
      if (!val) {
        input.value && input.value.blur();
        states.query = "";
        states.previousQuery = null;
        states.selectedLabel = "";
        states.inputLength = 20;
        states.menuVisibleOnFocus = false;
        resetHoverIndex();
        vue.nextTick(() => {
          if (input.value && input.value.value === "" && states.selected.length === 0) {
            states.currentPlaceholder = states.cachedPlaceHolder;
          }
        });
        if (!props.multiple) {
          if (states.selected) {
            if (props.filterable && props.allowCreate && states.createdSelected && states.createdLabel) {
              states.selectedLabel = states.createdLabel;
            } else {
              states.selectedLabel = states.selected.currentLabel;
            }
            if (props.filterable)
              states.query = states.selectedLabel;
          }
          if (props.filterable) {
            states.currentPlaceholder = states.cachedPlaceHolder;
          }
        }
      } else {
        (_b = (_a = tooltipRef.value) == null ? void 0 : _a.updatePopper) == null ? void 0 : _b.call(_a);
        if (props.filterable) {
          states.filteredOptionsCount = states.optionsCount;
          states.query = props.remote ? "" : states.selectedLabel;
          if (props.multiple) {
            (_c = input.value) == null ? void 0 : _c.focus();
          } else {
            if (states.selectedLabel) {
              states.currentPlaceholder = `${states.selectedLabel}`;
              states.selectedLabel = "";
            }
          }
          handleQueryChange(states.query);
          if (!props.multiple && !props.remote) {
            queryChange.value.query = "";
            vue.triggerRef(queryChange);
            vue.triggerRef(groupQueryChange);
          }
        }
      }
      ctx.emit("visible-change", val);
    });
    vue.watch(() => states.options.entries(), () => {
      var _a, _b, _c;
      if (!core.isClient)
        return;
      (_b = (_a = tooltipRef.value) == null ? void 0 : _a.updatePopper) == null ? void 0 : _b.call(_a);
      if (props.multiple) {
        resetInputHeight();
      }
      const inputs = ((_c = selectWrapper.value) == null ? void 0 : _c.querySelectorAll("input")) || [];
      if (!Array.from(inputs).includes(document.activeElement)) {
        setSelected();
      }
      if (props.defaultFirstOption && (props.filterable || props.remote) && states.filteredOptionsCount) {
        checkDefaultFirstOption();
      }
    }, {
      flush: "post"
    });
    vue.watch(() => states.hoverIndex, (val) => {
      if (typeof val === "number" && val > -1) {
        hoverOption.value = optionsArray.value[val] || {};
      }
      optionsArray.value.forEach((option) => {
        option.hover = hoverOption.value === option;
      });
    });
    const resetInputHeight = () => {
      if (props.collapseTags && !props.filterable)
        return;
      vue.nextTick(() => {
        var _a, _b;
        if (!reference.value)
          return;
        const inputChildNodes = reference.value.$el.childNodes;
        const input2 = Array.from(inputChildNodes).find((item) => item.tagName === "INPUT");
        const _tags = tags.value;
        const sizeInMap = states.initialInputHeight || 40;
        input2.style.height = states.selected.length === 0 ? `${sizeInMap}px` : `${Math.max(_tags ? _tags.clientHeight + (_tags.clientHeight > sizeInMap ? 6 : 0) : 0, sizeInMap)}px`;
        states.tagInMultiLine = Number.parseFloat(input2.style.height) >= sizeInMap;
        if (states.visible && emptyText.value !== false) {
          (_b = (_a = tooltipRef.value) == null ? void 0 : _a.updatePopper) == null ? void 0 : _b.call(_a);
        }
      });
    };
    const handleQueryChange = (val) => {
      if (states.previousQuery === val || states.isOnComposition)
        return;
      if (states.previousQuery === null && (typeof props.filterMethod === "function" || typeof props.remoteMethod === "function")) {
        states.previousQuery = val;
        return;
      }
      states.previousQuery = val;
      vue.nextTick(() => {
        var _a, _b;
        if (states.visible)
          (_b = (_a = tooltipRef.value) == null ? void 0 : _a.updatePopper) == null ? void 0 : _b.call(_a);
      });
      states.hoverIndex = -1;
      if (props.multiple && props.filterable) {
        vue.nextTick(() => {
          const length = input.value.value.length * 15 + 20;
          states.inputLength = props.collapseTags ? Math.min(50, length) : length;
          managePlaceholder();
          resetInputHeight();
        });
      }
      if (props.remote && typeof props.remoteMethod === "function") {
        states.hoverIndex = -1;
        props.remoteMethod(val);
      } else if (typeof props.filterMethod === "function") {
        props.filterMethod(val);
        vue.triggerRef(groupQueryChange);
      } else {
        states.filteredOptionsCount = states.optionsCount;
        queryChange.value.query = val;
        vue.triggerRef(queryChange);
        vue.triggerRef(groupQueryChange);
      }
      if (props.defaultFirstOption && (props.filterable || props.remote) && states.filteredOptionsCount) {
        checkDefaultFirstOption();
      }
    };
    const managePlaceholder = () => {
      if (states.currentPlaceholder !== "") {
        states.currentPlaceholder = input.value.value ? "" : states.cachedPlaceHolder;
      }
    };
    const checkDefaultFirstOption = () => {
      const optionsInDropdown = optionsArray.value.filter((n) => n.visible && !n.disabled && !n.states.groupDisabled);
      const userCreatedOption = optionsInDropdown.find((n) => n.created);
      const firstOriginOption = optionsInDropdown[0];
      states.hoverIndex = getValueIndex(optionsArray.value, userCreatedOption || firstOriginOption);
    };
    const setSelected = () => {
      var _a;
      if (!props.multiple) {
        const option = getOption(props.modelValue);
        if ((_a = option.props) == null ? void 0 : _a.created) {
          states.createdLabel = option.props.value;
          states.createdSelected = true;
        } else {
          states.createdSelected = false;
        }
        states.selectedLabel = option.currentLabel;
        states.selected = option;
        if (props.filterable)
          states.query = states.selectedLabel;
        return;
      } else {
        states.selectedLabel = "";
      }
      const result = [];
      if (Array.isArray(props.modelValue)) {
        props.modelValue.forEach((value) => {
          result.push(getOption(value));
        });
      }
      states.selected = result;
      vue.nextTick(() => {
        resetInputHeight();
      });
    };
    const getOption = (value) => {
      let option;
      const isObjectValue = shared.toRawType(value).toLowerCase() === "object";
      const isNull = shared.toRawType(value).toLowerCase() === "null";
      const isUndefined = shared.toRawType(value).toLowerCase() === "undefined";
      for (let i = states.cachedOptions.size - 1; i >= 0; i--) {
        const cachedOption = cachedOptionsArray.value[i];
        const isEqualValue = isObjectValue ? lodashUnified.get(cachedOption.value, props.valueKey) === lodashUnified.get(value, props.valueKey) : cachedOption.value === value;
        if (isEqualValue) {
          option = {
            value,
            currentLabel: cachedOption.currentLabel,
            isDisabled: cachedOption.isDisabled
          };
          break;
        }
      }
      if (option)
        return option;
      const label = isObjectValue ? value.label : !isNull && !isUndefined ? value : "";
      const newOption = {
        value,
        currentLabel: label
      };
      if (props.multiple) {
        ;
        newOption.hitState = false;
      }
      return newOption;
    };
    const resetHoverIndex = () => {
      setTimeout(() => {
        const valueKey = props.valueKey;
        if (!props.multiple) {
          states.hoverIndex = optionsArray.value.findIndex((item) => {
            return getValueKey(item) === getValueKey(states.selected);
          });
        } else {
          if (states.selected.length > 0) {
            states.hoverIndex = Math.min.apply(null, states.selected.map((selected) => {
              return optionsArray.value.findIndex((item) => {
                return lodashUnified.get(item, valueKey) === lodashUnified.get(selected, valueKey);
              });
            }));
          } else {
            states.hoverIndex = -1;
          }
        }
      }, 300);
    };
    const handleResize = () => {
      var _a, _b;
      resetInputWidth();
      (_b = (_a = tooltipRef.value) == null ? void 0 : _a.updatePopper) == null ? void 0 : _b.call(_a);
      if (props.multiple && !props.filterable)
        resetInputHeight();
    };
    const resetInputWidth = () => {
      var _a;
      states.inputWidth = (_a = reference.value) == null ? void 0 : _a.$el.getBoundingClientRect().width;
    };
    const onInputChange = () => {
      if (props.filterable && states.query !== states.selectedLabel) {
        states.query = states.selectedLabel;
        handleQueryChange(states.query);
      }
    };
    const debouncedOnInputChange = lodashUnified.debounce(() => {
      onInputChange();
    }, debounce.value);
    const debouncedQueryChange = lodashUnified.debounce((e) => {
      handleQueryChange(e.target.value);
    }, debounce.value);
    const emitChange = (val) => {
      if (!lodashUnified.isEqual(props.modelValue, val)) {
        ctx.emit(event.CHANGE_EVENT, val);
      }
    };
    const deletePrevTag = (e) => {
      if (e.target.value.length <= 0 && !toggleLastOptionHitState()) {
        const value = props.modelValue.slice();
        value.pop();
        ctx.emit(event.UPDATE_MODEL_EVENT, value);
        emitChange(value);
      }
      if (e.target.value.length === 1 && props.modelValue.length === 0) {
        states.currentPlaceholder = states.cachedPlaceHolder;
      }
    };
    const deleteTag = (event$1, tag) => {
      const index = states.selected.indexOf(tag);
      if (index > -1 && !selectDisabled.value) {
        const value = props.modelValue.slice();
        value.splice(index, 1);
        ctx.emit(event.UPDATE_MODEL_EVENT, value);
        emitChange(value);
        ctx.emit("remove-tag", tag.value);
      }
      event$1.stopPropagation();
    };
    const deleteSelected = (event$1) => {
      event$1.stopPropagation();
      const value = props.multiple ? [] : "";
      if (typeof value !== "string") {
        for (const item of states.selected) {
          if (item.isDisabled)
            value.push(item.value);
        }
      }
      ctx.emit(event.UPDATE_MODEL_EVENT, value);
      emitChange(value);
      states.visible = false;
      ctx.emit("clear");
    };
    const handleOptionSelect = (option, byClick) => {
      var _a;
      if (props.multiple) {
        const value = (props.modelValue || []).slice();
        const optionIndex = getValueIndex(value, option.value);
        if (optionIndex > -1) {
          value.splice(optionIndex, 1);
        } else if (props.multipleLimit <= 0 || value.length < props.multipleLimit) {
          value.push(option.value);
        }
        ctx.emit(event.UPDATE_MODEL_EVENT, value);
        emitChange(value);
        if (option.created) {
          states.query = "";
          handleQueryChange("");
          states.inputLength = 20;
        }
        if (props.filterable)
          (_a = input.value) == null ? void 0 : _a.focus();
      } else {
        ctx.emit(event.UPDATE_MODEL_EVENT, option.value);
        emitChange(option.value);
        states.visible = false;
      }
      states.isSilentBlur = byClick;
      setSoftFocus();
      if (states.visible)
        return;
      vue.nextTick(() => {
        scrollToOption(option);
      });
    };
    const getValueIndex = (arr = [], value) => {
      if (!shared.isObject(value))
        return arr.indexOf(value);
      const valueKey = props.valueKey;
      let index = -1;
      arr.some((item, i) => {
        if (lodashUnified.get(item, valueKey) === lodashUnified.get(value, valueKey)) {
          index = i;
          return true;
        }
        return false;
      });
      return index;
    };
    const setSoftFocus = () => {
      states.softFocus = true;
      const _input = input.value || reference.value;
      if (_input) {
        _input == null ? void 0 : _input.focus();
      }
    };
    const scrollToOption = (option) => {
      var _a, _b, _c, _d, _e;
      const targetOption = Array.isArray(option) ? option[0] : option;
      let target = null;
      if (targetOption == null ? void 0 : targetOption.value) {
        const options = optionsArray.value.filter((item) => item.value === targetOption.value);
        if (options.length > 0) {
          target = options[0].$el;
        }
      }
      if (tooltipRef.value && target) {
        const menu = (_d = (_c = (_b = (_a = tooltipRef.value) == null ? void 0 : _a.popperRef) == null ? void 0 : _b.contentRef) == null ? void 0 : _c.querySelector) == null ? void 0 : _d.call(_c, `.${ns.be("dropdown", "wrap")}`);
        if (menu) {
          scroll.scrollIntoView(menu, target);
        }
      }
      (_e = scrollbar.value) == null ? void 0 : _e.handleScroll();
    };
    const onOptionCreate = (vm) => {
      states.optionsCount++;
      states.filteredOptionsCount++;
      states.options.set(vm.value, vm);
      states.cachedOptions.set(vm.value, vm);
    };
    const onOptionDestroy = (key, vm) => {
      if (states.options.get(key) === vm) {
        states.optionsCount--;
        states.filteredOptionsCount--;
        states.options.delete(key);
      }
    };
    const resetInputState = (e) => {
      if (e.code !== aria.EVENT_CODE.backspace)
        toggleLastOptionHitState(false);
      states.inputLength = input.value.value.length * 15 + 20;
      resetInputHeight();
    };
    const toggleLastOptionHitState = (hit) => {
      if (!Array.isArray(states.selected))
        return;
      const option = states.selected[states.selected.length - 1];
      if (!option)
        return;
      if (hit === true || hit === false) {
        option.hitState = hit;
        return hit;
      }
      option.hitState = !option.hitState;
      return option.hitState;
    };
    const handleComposition = (event) => {
      const text = event.target.value;
      if (event.type === "compositionend") {
        states.isOnComposition = false;
        vue.nextTick(() => handleQueryChange(text));
      } else {
        const lastCharacter = text[text.length - 1] || "";
        states.isOnComposition = !i18n.isKorean(lastCharacter);
      }
    };
    const handleMenuEnter = () => {
      vue.nextTick(() => scrollToOption(states.selected));
    };
    const handleFocus = (event) => {
      if (!states.softFocus) {
        if (props.automaticDropdown || props.filterable) {
          if (props.filterable && !states.visible) {
            states.menuVisibleOnFocus = true;
          }
          states.visible = true;
        }
        ctx.emit("focus", event);
      } else {
        states.softFocus = false;
      }
    };
    const blur = () => {
      var _a;
      states.visible = false;
      (_a = reference.value) == null ? void 0 : _a.blur();
    };
    const handleBlur = (event) => {
      vue.nextTick(() => {
        if (states.isSilentBlur) {
          states.isSilentBlur = false;
        } else {
          ctx.emit("blur", event);
        }
      });
      states.softFocus = false;
    };
    const handleClearClick = (event) => {
      deleteSelected(event);
    };
    const handleClose = () => {
      states.visible = false;
    };
    const toggleMenu = () => {
      var _a;
      if (props.automaticDropdown)
        return;
      if (!selectDisabled.value) {
        if (states.menuVisibleOnFocus) {
          states.menuVisibleOnFocus = false;
        } else {
          states.visible = !states.visible;
        }
        if (states.visible) {
          ;
          (_a = input.value || reference.value) == null ? void 0 : _a.focus();
        }
      }
    };
    const selectOption = () => {
      if (!states.visible) {
        toggleMenu();
      } else {
        if (optionsArray.value[states.hoverIndex]) {
          handleOptionSelect(optionsArray.value[states.hoverIndex], void 0);
        }
      }
    };
    const getValueKey = (item) => {
      return shared.isObject(item.value) ? lodashUnified.get(item.value, props.valueKey) : item.value;
    };
    const optionsAllDisabled = vue.computed(() => optionsArray.value.filter((option) => option.visible).every((option) => option.disabled));
    const navigateOptions = (direction) => {
      if (!states.visible) {
        states.visible = true;
        return;
      }
      if (states.options.size === 0 || states.filteredOptionsCount === 0)
        return;
      if (states.isOnComposition)
        return;
      if (!optionsAllDisabled.value) {
        if (direction === "next") {
          states.hoverIndex++;
          if (states.hoverIndex === states.options.size) {
            states.hoverIndex = 0;
          }
        } else if (direction === "prev") {
          states.hoverIndex--;
          if (states.hoverIndex < 0) {
            states.hoverIndex = states.options.size - 1;
          }
        }
        const option = optionsArray.value[states.hoverIndex];
        if (option.disabled === true || option.states.groupDisabled === true || !option.visible) {
          navigateOptions(direction);
        }
        vue.nextTick(() => scrollToOption(hoverOption.value));
      }
    };
    return {
      optionsArray,
      selectSize,
      handleResize,
      debouncedOnInputChange,
      debouncedQueryChange,
      deletePrevTag,
      deleteTag,
      deleteSelected,
      handleOptionSelect,
      scrollToOption,
      readonly,
      resetInputHeight,
      showClose,
      iconComponent,
      iconReverse,
      showNewOption,
      collapseTagSize,
      setSelected,
      managePlaceholder,
      selectDisabled,
      emptyText,
      toggleLastOptionHitState,
      resetInputState,
      handleComposition,
      onOptionCreate,
      onOptionDestroy,
      handleMenuEnter,
      handleFocus,
      blur,
      handleBlur,
      handleClearClick,
      handleClose,
      toggleMenu,
      selectOption,
      getValueKey,
      navigateOptions,
      dropMenuVisible,
      queryChange,
      groupQueryChange,
      reference,
      input,
      tooltipRef,
      tags,
      selectWrapper,
      scrollbar
    };
  };
  
  exports.useSelect = useSelect;
  exports.useSelectStates = useSelectStates;
  //# sourceMappingURL=useSelect.js.map
  