"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const vue = require("vue");
const comp = require("../../ui/src/comp.js");
const XEUtils = require("xe-utils");
require("../../ui/index.js");
const dom = require("../../ui/src/dom.js");
const utils = require("../../ui/src/utils.js");
const vn = require("../../ui/src/vn.js");
const config = require("../../../../@vxe-ui/core/es/src/config.js");
const useFns = require("../../../../@vxe-ui/core/es/src/useFns.js");
const i18n = require("../../../../@vxe-ui/core/es/src/i18n.js");
const event = require("../../../../@vxe-ui/core/es/src/event.js");
const icon = require("../../../../@vxe-ui/core/es/src/icon.js");
const index_esm = require("../../../../@vxe-ui/core/es/index.esm.js");
const renderer = require("../../../../@vxe-ui/core/es/src/renderer.js");
const VxeIconPickerComponent = comp.defineVxeComponent({
  name: "VxeIconPicker",
  props: {
    modelValue: String,
    placeholder: String,
    clearable: Boolean,
    size: {
      type: String,
      default: () => config.getConfig().iconPicker.size || config.getConfig().size
    },
    className: [String, Function],
    /**
     * 已废弃，请使用 popupConfig.className
     * @deprecated
     */
    popupClassName: [String, Function],
    showIconTitle: {
      type: Boolean,
      default: () => config.getConfig().iconPicker.showIconTitle
    },
    readonly: {
      type: Boolean,
      default: null
    },
    disabled: {
      type: Boolean,
      default: null
    },
    icons: Array,
    placement: String,
    popupConfig: Object,
    transfer: {
      type: Boolean,
      default: null
    }
  },
  emits: [
    "update:modelValue",
    "change",
    "clear",
    "click"
  ],
  setup(props, context) {
    const { emit } = context;
    const $xeModal = vue.inject("$xeModal", null);
    const $xeDrawer = vue.inject("$xeDrawer", null);
    const $xeTable = vue.inject("$xeTable", null);
    const $xeForm = vue.inject("$xeForm", null);
    const formItemInfo = vue.inject("xeFormItemInfo", null);
    const xID = XEUtils.uniqueId();
    const { computeSize } = useFns.useSize(props);
    const reactData = vue.reactive({
      initialized: false,
      selectIcon: `${props.modelValue || ""}`,
      panelIndex: 0,
      panelStyle: {},
      panelPlacement: null,
      visiblePanel: false,
      isAniVisible: false,
      isActivated: false
    });
    const internalData = {
      // hpTimeout: undefined
    };
    const refElem = vue.ref();
    const refInput = vue.ref();
    const refOptionPanel = vue.ref();
    const refMaps = {
      refElem
    };
    const $xeIconPicker = {
      xID,
      props,
      context,
      reactData,
      getRefMaps: () => refMaps
    };
    let iconPickerMethods = {};
    const computeFormReadonly = vue.computed(() => {
      const { readonly } = props;
      if (readonly === null) {
        if ($xeForm) {
          return $xeForm.props.readonly;
        }
        return false;
      }
      return readonly;
    });
    const computeIsDisabled = vue.computed(() => {
      const { disabled } = props;
      if (disabled === null) {
        if ($xeForm) {
          return $xeForm.props.disabled;
        }
        return false;
      }
      return disabled;
    });
    const computeBtnTransfer = vue.computed(() => {
      const { transfer } = props;
      const popupOpts = computePopupOpts.value;
      if (XEUtils.isBoolean(popupOpts.transfer)) {
        return popupOpts.transfer;
      }
      if (transfer === null) {
        const globalTransfer = config.getConfig().iconPicker.transfer;
        if (XEUtils.isBoolean(globalTransfer)) {
          return globalTransfer;
        }
        if ($xeTable || $xeModal || $xeDrawer || $xeForm) {
          return true;
        }
      }
      return transfer;
    });
    const computeInpPlaceholder = vue.computed(() => {
      const { placeholder } = props;
      if (placeholder) {
        return utils.getFuncText(placeholder);
      }
      const globalPlaceholder = config.getConfig().select.placeholder;
      if (globalPlaceholder) {
        return utils.getFuncText(globalPlaceholder);
      }
      return i18n.getI18n("vxe.base.pleaseSelect");
    });
    const computeIconList = vue.computed(() => {
      let { icons } = props;
      if (!icons || !icons.length) {
        icons = config.getConfig().iconPicker.icons || [];
      }
      return icons.map((item) => {
        if (XEUtils.isString(item)) {
          return {
            title: item,
            icon: `vxe-icon-${`${item || ""}`.replace(/^vxe-icon-/, "")}`
          };
        }
        return {
          title: `${item.title || ""}`,
          icon: item.icon || "",
          iconRender: item.iconRender
        };
      });
    });
    const computePopupOpts = vue.computed(() => {
      return Object.assign({}, config.getConfig().iconPicker.popupConfig, props.popupConfig);
    });
    const computeIconGroupList = vue.computed(() => {
      const iconList = computeIconList.value;
      return XEUtils.chunk(iconList, 4);
    });
    const computeSelectIconItem = vue.computed(() => {
      const { selectIcon } = reactData;
      const iconList = computeIconList.value;
      return selectIcon ? iconList.find((item) => item.icon === selectIcon) : null;
    });
    const updateZindex = () => {
      if (reactData.panelIndex < utils.getLastZIndex()) {
        reactData.panelIndex = utils.nextZIndex();
      }
    };
    const updatePlacement = () => {
      const { placement } = props;
      const { panelIndex } = reactData;
      const targetElem = refElem.value;
      const panelElem = refOptionPanel.value;
      const btnTransfer = computeBtnTransfer.value;
      const popupOpts = computePopupOpts.value;
      const handleStyle = () => {
        const ppObj = dom.updatePanelPlacement(targetElem, panelElem, {
          placement: popupOpts.placement || placement,
          teleportTo: btnTransfer
        });
        const panelStyle = Object.assign(ppObj.style, {
          zIndex: panelIndex
        });
        reactData.panelStyle = panelStyle;
        reactData.panelPlacement = ppObj.placement;
      };
      handleStyle();
      return vue.nextTick().then(handleStyle);
    };
    const showOptionPanel = () => {
      const { hpTimeout } = internalData;
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        if (hpTimeout) {
          clearTimeout(hpTimeout);
          internalData.hpTimeout = void 0;
        }
        if (!reactData.initialized) {
          reactData.initialized = true;
        }
        reactData.isActivated = true;
        reactData.isAniVisible = true;
        setTimeout(() => {
          reactData.visiblePanel = true;
          updatePlacement();
        }, 10);
        updateZindex();
        updatePlacement();
      }
    };
    const hideOptionPanel = () => {
      reactData.visiblePanel = false;
      internalData.hpTimeout = setTimeout(() => {
        reactData.isAniVisible = false;
      }, 350);
    };
    const changeEvent = (evnt, selectValue) => {
      reactData.selectIcon = selectValue;
      if (selectValue !== props.modelValue) {
        emit("update:modelValue", selectValue);
        dispatchEvent("change", { value: selectValue }, evnt);
        if ($xeForm && formItemInfo) {
          $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, selectValue);
        }
      }
    };
    const focusEvent = () => {
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        if (!reactData.visiblePanel) {
          showOptionPanel();
        }
      }
    };
    const blurEvent = () => {
      reactData.isActivated = false;
    };
    const clearValueEvent = (evnt, selectValue) => {
      changeEvent(evnt, selectValue);
      dispatchEvent("clear", { value: selectValue }, evnt);
    };
    const clearEvent = (params, evnt) => {
      clearValueEvent(evnt, null);
      hideOptionPanel();
    };
    const togglePanelEvent = (evnt) => {
      evnt.preventDefault();
      if (reactData.visiblePanel) {
        hideOptionPanel();
      } else {
        showOptionPanel();
      }
    };
    const clickEvent = (evnt) => {
      togglePanelEvent(evnt);
      dispatchEvent("click", {}, evnt);
    };
    const handleGlobalMousewheelEvent = (evnt) => {
      const { visiblePanel } = reactData;
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        if (visiblePanel) {
          const panelElem = refOptionPanel.value;
          if (dom.getEventTargetNode(evnt, panelElem).flag) {
            updatePlacement();
          } else {
            hideOptionPanel();
          }
        }
      }
    };
    const handleGlobalMousedownEvent = (evnt) => {
      const { visiblePanel } = reactData;
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        const el = refElem.value;
        const panelElem = refOptionPanel.value;
        reactData.isActivated = dom.getEventTargetNode(evnt, el).flag || dom.getEventTargetNode(evnt, panelElem).flag;
        if (visiblePanel && !reactData.isActivated) {
          hideOptionPanel();
        }
      }
    };
    const handleGlobalKeydownEvent = (evnt) => {
      const { clearable } = props;
      const { visiblePanel } = reactData;
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        const isTab = event.globalEvents.hasKey(evnt, event.GLOBAL_EVENT_KEYS.TAB);
        const isEnter = event.globalEvents.hasKey(evnt, event.GLOBAL_EVENT_KEYS.ENTER);
        const isEsc = event.globalEvents.hasKey(evnt, event.GLOBAL_EVENT_KEYS.ESCAPE);
        const isUpArrow = event.globalEvents.hasKey(evnt, event.GLOBAL_EVENT_KEYS.ARROW_UP);
        const isDwArrow = event.globalEvents.hasKey(evnt, event.GLOBAL_EVENT_KEYS.ARROW_DOWN);
        const isDel = event.globalEvents.hasKey(evnt, event.GLOBAL_EVENT_KEYS.DELETE);
        const isSpacebar = event.globalEvents.hasKey(evnt, event.GLOBAL_EVENT_KEYS.SPACEBAR);
        if (isTab) {
          reactData.isActivated = false;
        }
        if (visiblePanel) {
          if (isEsc || isTab) {
            hideOptionPanel();
          } else if (isEnter) {
            evnt.preventDefault();
            evnt.stopPropagation();
          } else if (isUpArrow || isDwArrow) {
            evnt.preventDefault();
          } else if (isSpacebar) {
            evnt.preventDefault();
          }
        } else if ((isUpArrow || isDwArrow || isEnter || isSpacebar) && reactData.isActivated) {
          evnt.preventDefault();
          showOptionPanel();
        }
        if (reactData.isActivated) {
          if (isDel && clearable) {
            clearValueEvent(evnt, null);
          }
        }
      }
    };
    const handleGlobalBlurEvent = () => {
      const { visiblePanel, isActivated } = reactData;
      if (visiblePanel) {
        hideOptionPanel();
      }
      if (isActivated) {
        reactData.isActivated = false;
      }
      if (visiblePanel || isActivated) {
        const $input = refInput.value;
        if ($input) {
          $input.blur();
        }
      }
    };
    const dispatchEvent = (type, params, evnt) => {
      emit(type, event.createEvent(evnt, { $iconPicker: $xeIconPicker }, params));
    };
    iconPickerMethods = {
      dispatchEvent,
      isPanelVisible() {
        return reactData.visiblePanel;
      },
      togglePanel() {
        if (reactData.visiblePanel) {
          hideOptionPanel();
        } else {
          showOptionPanel();
        }
        return vue.nextTick();
      },
      hidePanel() {
        if (reactData.visiblePanel) {
          hideOptionPanel();
        }
        return vue.nextTick();
      },
      showPanel() {
        if (!reactData.visiblePanel) {
          showOptionPanel();
        }
        return vue.nextTick();
      },
      focus() {
        const $input = refInput.value;
        reactData.isActivated = true;
        if ($input) {
          $input.blur();
        }
        return vue.nextTick();
      },
      blur() {
        const $input = refInput.value;
        if ($input) {
          $input.blur();
        }
        reactData.isActivated = false;
        return vue.nextTick();
      }
    };
    const handleClickIconEvent = (evnt, item) => {
      const value = item.icon;
      changeEvent(evnt, value);
      hideOptionPanel();
    };
    Object.assign($xeIconPicker, iconPickerMethods);
    const renderIconWrapper = () => {
      const { showIconTitle } = props;
      const iconGroupList = computeIconGroupList.value;
      const isDisabled = computeIsDisabled.value;
      return vue.h("div", {
        class: "vxe-ico-picker--list-wrapper"
      }, iconGroupList.map((list) => {
        return vue.h("div", {
          class: "vxe-ico-picker--list"
        }, list.map((item) => {
          const { iconRender } = item;
          const compConf = iconRender ? renderer.renderer.get(iconRender.name) : null;
          const oIconMethod = compConf ? compConf.renderIconPickerOptionIcon : null;
          return vue.h("div", {
            class: "vxe-ico-picker--item",
            onClick(evnt) {
              if (!isDisabled) {
                handleClickIconEvent(evnt, item);
              }
            }
          }, [
            vue.h("div", {
              class: "vxe-ico-picker--item-icon"
            }, oIconMethod && iconRender ? vn.getSlotVNs(oIconMethod(iconRender, { $iconPicker: $xeIconPicker, option: item })) : [
              vue.h("i", {
                class: item.icon || ""
              })
            ]),
            showIconTitle ? vue.h("div", {
              class: "vxe-ico-picker--item-title"
            }, `${item.title || ""}`) : index_esm.renderEmptyElement()
          ]);
        }));
      }));
    };
    const renderIconView = () => {
      const { selectIcon } = reactData;
      const selectIconItem = computeSelectIconItem.value;
      if (selectIconItem) {
        const { iconRender } = selectIconItem;
        const compConf = iconRender ? renderer.renderer.get(iconRender.name) : null;
        const oIconMethod = compConf ? compConf.renderIconPickerOptionIcon : null;
        if (oIconMethod && iconRender) {
          return vue.h("div", {
            key: "inc",
            class: "vxe-ico-picker--icon"
          }, vn.getSlotVNs(oIconMethod(iconRender, { $iconPicker: $xeIconPicker, option: selectIconItem })));
        }
      }
      return vue.h("div", {
        key: "ind",
        class: "vxe-ico-picker--icon"
      }, [
        vue.h("i", {
          class: selectIcon
        })
      ]);
    };
    const renderVN = () => {
      const { className, clearable } = props;
      const { initialized, isActivated, isAniVisible, visiblePanel, selectIcon } = reactData;
      const vSize = computeSize.value;
      const isDisabled = computeIsDisabled.value;
      const btnTransfer = computeBtnTransfer.value;
      const formReadonly = computeFormReadonly.value;
      const inpPlaceholder = computeInpPlaceholder.value;
      const popupOpts = computePopupOpts.value;
      const ppClassName = popupOpts.className || props.popupClassName;
      if (formReadonly) {
        return vue.h("div", {
          ref: refElem,
          class: ["vxe-ico-picker--readonly", className]
        }, [
          vue.h("i", {
            class: selectIcon
          })
        ]);
      }
      return vue.h("div", {
        ref: refElem,
        class: ["vxe-ico-picker", className ? XEUtils.isFunction(className) ? className({ $iconPicker: $xeIconPicker }) : className : "", {
          [`size--${vSize}`]: vSize,
          "show--clear": clearable && !isDisabled && !!selectIcon,
          "is--visible": visiblePanel,
          "is--disabled": isDisabled,
          "is--active": isActivated
        }]
      }, [
        vue.h("div", {
          class: "vxe-ico-picker--inner",
          onClick: clickEvent
        }, [
          vue.h("input", {
            ref: refInput,
            class: "vxe-ico-picker--input",
            onFocus: focusEvent,
            onBlur: blurEvent
          }),
          selectIcon ? renderIconView() : vue.h("div", {
            class: "vxe-ico-picker--placeholder"
          }, inpPlaceholder),
          vue.h("div", {
            class: "vxe-ico-picker--suffix"
          }, [
            vue.h("div", {
              class: "vxe-ico-picker--clear-icon",
              onClick: clearEvent
            }, [
              vue.h("i", {
                class: icon.getIcon().INPUT_CLEAR
              })
            ]),
            vue.h("div", {
              class: "vxe-ico-picker--suffix-icon"
            }, [
              vue.h("i", {
                class: visiblePanel ? icon.getIcon().ICON_PICKER_OPEN : icon.getIcon().ICON_PICKER_CLOSE
              })
            ])
          ])
        ]),
        vue.h(vue.Teleport, {
          to: "body",
          disabled: btnTransfer ? !initialized : true
        }, [
          vue.h("div", {
            ref: refOptionPanel,
            class: ["vxe-table--ignore-clear vxe-ico-picker--panel", ppClassName ? XEUtils.isFunction(ppClassName) ? ppClassName({ $iconPicker: $xeIconPicker }) : ppClassName : "", {
              [`size--${vSize}`]: vSize,
              "is--transfer": btnTransfer,
              "ani--leave": isAniVisible,
              "ani--enter": visiblePanel
            }],
            placement: reactData.panelPlacement,
            style: reactData.panelStyle
          }, [
            initialized && (visiblePanel || isAniVisible) ? vue.h("div", {
              class: "vxe-ico-picker--panel-wrapper"
            }, [
              renderIconWrapper()
            ]) : index_esm.renderEmptyElement()
          ])
        ])
      ]);
    };
    vue.watch(() => props.modelValue, (val) => {
      reactData.selectIcon = `${val || ""}`;
    });
    vue.onMounted(() => {
      event.globalEvents.on($xeIconPicker, "mousewheel", handleGlobalMousewheelEvent);
      event.globalEvents.on($xeIconPicker, "mousedown", handleGlobalMousedownEvent);
      event.globalEvents.on($xeIconPicker, "keydown", handleGlobalKeydownEvent);
      event.globalEvents.on($xeIconPicker, "blur", handleGlobalBlurEvent);
    });
    vue.onUnmounted(() => {
      event.globalEvents.off($xeIconPicker, "mousewheel");
      event.globalEvents.off($xeIconPicker, "mousedown");
      event.globalEvents.off($xeIconPicker, "keydown");
      event.globalEvents.off($xeIconPicker, "blur");
    });
    vue.provide("$xeIconPicker", $xeIconPicker);
    $xeIconPicker.renderVN = renderVN;
    return $xeIconPicker;
  },
  render() {
    return this.renderVN();
  }
});
exports.default = VxeIconPickerComponent;
