"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 config = require("../../../../@vxe-ui/core/es/src/config.js");
const useFns = require("../../../../@vxe-ui/core/es/src/useFns.js");
const event = require("../../../../@vxe-ui/core/es/src/event.js");
const index_esm = require("../../../../@vxe-ui/core/es/index.esm.js");
const VxePulldownComponent = comp.defineVxeComponent({
  name: "VxePulldown",
  props: {
    modelValue: Boolean,
    disabled: Boolean,
    placement: String,
    trigger: {
      type: String,
      default: config.getConfig().pulldown.trigger
    },
    /**
     * 已废弃，请使用 popupConfig.zIndex
     * @deprecated
     */
    zIndex: Number,
    size: {
      type: String,
      default: () => config.getConfig().pulldown.size || config.getConfig().size
    },
    options: Array,
    className: {
      type: [String, Function],
      default: config.getConfig().pulldown.className
    },
    /**
     * 已废弃，请使用 popupConfig.className
     * @deprecated
     */
    popupClassName: [String, Function],
    showPopupShadow: Boolean,
    popupConfig: Object,
    destroyOnClose: {
      type: Boolean,
      default: config.getConfig().pulldown.destroyOnClose
    },
    transfer: {
      type: Boolean,
      default: null
    }
  },
  emits: [
    "update:modelValue",
    "click",
    "option-click",
    "show-panel",
    "hide-panel",
    "visible-change"
  ],
  setup(props, context) {
    const { slots, 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 xID = XEUtils.uniqueId();
    const { computeSize } = useFns.useSize(props);
    const reactData = vue.reactive({
      initialized: false,
      panelIndex: 0,
      panelStyle: {},
      panelPlacement: null,
      visiblePanel: false,
      isAniVisible: false,
      isActivated: false
    });
    const internalData = {
      hpTimeout: void 0
    };
    const refElem = vue.ref();
    const refPulldownContent = vue.ref();
    const refPulldownPanel = vue.ref();
    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().pulldown.transfer;
        if (XEUtils.isBoolean(globalTransfer)) {
          return globalTransfer;
        }
        if ($xeTable || $xeModal || $xeDrawer || $xeForm) {
          return true;
        }
      }
      return transfer;
    });
    const computePopupOpts = vue.computed(() => {
      return Object.assign({}, config.getConfig().pulldown.popupConfig, props.popupConfig);
    });
    const refMaps = {
      refElem
    };
    const $xePulldown = {
      xID,
      props,
      context,
      reactData,
      internalData,
      getRefMaps: () => refMaps
    };
    let pulldownMethods = {};
    const updateZindex = () => {
      const popupOpts = computePopupOpts.value;
      const customZIndex = popupOpts.zIndex || props.zIndex;
      if (customZIndex) {
        reactData.panelIndex = XEUtils.toNumber(customZIndex);
      } else if (reactData.panelIndex < utils.getLastZIndex()) {
        reactData.panelIndex = utils.nextZIndex();
      }
    };
    const isPanelVisible = () => {
      return reactData.visiblePanel;
    };
    const updatePlacement = () => {
      const { placement } = props;
      const { panelIndex } = reactData;
      const targetElem = refPulldownContent.value;
      const panelElem = refPulldownPanel.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 showPanel = () => {
      if (!reactData.initialized) {
        reactData.initialized = true;
      }
      return new Promise((resolve) => {
        if (!props.disabled) {
          if (internalData.hpTimeout) {
            clearTimeout(internalData.hpTimeout);
          }
          reactData.isActivated = true;
          reactData.isAniVisible = true;
          setTimeout(() => {
            reactData.visiblePanel = true;
            emit("update:modelValue", true);
            updatePlacement();
            setTimeout(() => {
              resolve(updatePlacement());
            }, 40);
          }, 10);
          updateZindex();
          dispatchEvent("visible-change", { visible: true }, null);
        } else {
          vue.nextTick(() => {
            resolve();
          });
        }
      });
    };
    const hideOptionPanel = () => {
      reactData.visiblePanel = false;
      dispatchEvent("visible-change", { visible: false }, null);
      emit("update:modelValue", false);
      return new Promise((resolve) => {
        if (reactData.isAniVisible) {
          internalData.hpTimeout = setTimeout(() => {
            reactData.isAniVisible = false;
            vue.nextTick(() => {
              resolve();
            });
          }, 350);
        } else {
          vue.nextTick(() => {
            resolve();
          });
        }
      });
    };
    const togglePanel = () => {
      if (reactData.visiblePanel) {
        return hideOptionPanel();
      }
      return showPanel();
    };
    const handleOptionEvent = (evnt, option) => {
      if (!option.disabled) {
        if (reactData.visiblePanel) {
          hideOptionPanel();
          dispatchEvent("hide-panel", {}, evnt);
        }
        dispatchEvent("option-click", { option }, evnt);
      }
    };
    const clickTargetEvent = (evnt) => {
      const { trigger } = props;
      if (trigger === "click") {
        if (reactData.visiblePanel) {
          hideOptionPanel();
          dispatchEvent("hide-panel", {}, evnt);
        } else {
          showPanel();
          dispatchEvent("show-panel", {}, evnt);
        }
      }
      dispatchEvent("click", { $pulldown: $xePulldown }, evnt);
    };
    const handleGlobalMousewheelEvent = (evnt) => {
      const { disabled } = props;
      const { visiblePanel } = reactData;
      const panelElem = refPulldownPanel.value;
      if (!disabled) {
        if (visiblePanel) {
          if (dom.getEventTargetNode(evnt, panelElem).flag) {
            updatePlacement();
          } else {
            hideOptionPanel();
            dispatchEvent("hide-panel", {}, evnt);
          }
        }
      }
    };
    const handleGlobalMousedownEvent = (evnt) => {
      const { disabled } = props;
      const { visiblePanel } = reactData;
      const el = refElem.value;
      const panelElem = refPulldownPanel.value;
      if (!disabled) {
        reactData.isActivated = dom.getEventTargetNode(evnt, el).flag || dom.getEventTargetNode(evnt, panelElem).flag;
        if (visiblePanel && !reactData.isActivated) {
          hideOptionPanel();
          dispatchEvent("hide-panel", {}, evnt);
        }
      }
    };
    const handleGlobalBlurEvent = (evnt) => {
      const { visiblePanel, isActivated } = reactData;
      if (visiblePanel) {
        hideOptionPanel();
        dispatchEvent("hide-panel", {}, evnt);
      }
      if (isActivated) {
        reactData.isActivated = false;
      }
    };
    const handleGlobalResizeEvent = () => {
      const { visiblePanel } = reactData;
      if (visiblePanel) {
        updatePlacement();
      }
    };
    const dispatchEvent = (type, params, evnt) => {
      emit(type, event.createEvent(evnt, { $pulldown: $xePulldown }, params));
    };
    pulldownMethods = {
      dispatchEvent,
      isPanelVisible,
      togglePanel,
      showPanel,
      hidePanel: hideOptionPanel
    };
    Object.assign($xePulldown, pulldownMethods);
    vue.watch(() => props.modelValue, (value) => {
      reactData.isActivated = !!value;
      if (value) {
        showPanel();
      } else {
        hideOptionPanel();
      }
    });
    vue.nextTick(() => {
      if (props.modelValue) {
        showPanel();
      }
      event.globalEvents.on($xePulldown, "mousewheel", handleGlobalMousewheelEvent);
      event.globalEvents.on($xePulldown, "mousedown", handleGlobalMousedownEvent);
      event.globalEvents.on($xePulldown, "blur", handleGlobalBlurEvent);
      event.globalEvents.on($xePulldown, "resize", handleGlobalResizeEvent);
    });
    vue.onUnmounted(() => {
      event.globalEvents.off($xePulldown, "mousewheel");
      event.globalEvents.off($xePulldown, "mousedown");
      event.globalEvents.off($xePulldown, "blur");
      event.globalEvents.off($xePulldown, "resize");
    });
    const renderDefaultPanel = (options) => {
      const optionSlot = slots.option;
      return vue.h("div", {
        class: "vxe-pulldown--panel-list"
      }, options ? options.map((item) => {
        return vue.h("div", {
          class: "vxe-pulldown--panel-item",
          onClick(evnt) {
            handleOptionEvent(evnt, item);
          }
        }, optionSlot ? optionSlot({ $pulldown: $xePulldown, option: item }) : `${item.label || ""}`);
      }) : []);
    };
    const renderVN = () => {
      const { className, options, showPopupShadow, destroyOnClose, disabled } = props;
      const { initialized, isActivated, isAniVisible, visiblePanel, panelStyle, panelPlacement } = reactData;
      const btnTransfer = computeBtnTransfer.value;
      const vSize = computeSize.value;
      const popupOpts = computePopupOpts.value;
      const defaultSlot = slots.default;
      const headerSlot = slots.header;
      const footerSlot = slots.footer;
      const dropdownSlot = slots.dropdown;
      const ppClassName = popupOpts.className || props.popupClassName;
      return vue.h("div", {
        ref: refElem,
        class: ["vxe-pulldown", className ? XEUtils.isFunction(className) ? className({ $pulldown: $xePulldown }) : className : "", {
          [`size--${vSize}`]: vSize,
          "is--visible": visiblePanel,
          "is--disabled": disabled,
          "is--active": isActivated
        }]
      }, [
        vue.h("div", {
          ref: refPulldownContent,
          class: "vxe-pulldown--content",
          onClick: clickTargetEvent
        }, defaultSlot ? defaultSlot({ $pulldown: $xePulldown }) : []),
        vue.h(vue.Teleport, {
          to: "body",
          disabled: btnTransfer ? !initialized : true
        }, [
          vue.h("div", {
            ref: refPulldownPanel,
            class: ["vxe-table--ignore-clear vxe-pulldown--panel", ppClassName ? XEUtils.isFunction(ppClassName) ? ppClassName({ $pulldown: $xePulldown }) : ppClassName : "", {
              [`size--${vSize}`]: vSize,
              "is--transfer": btnTransfer,
              "ani--leave": isAniVisible,
              "ani--enter": visiblePanel
            }],
            placement: panelPlacement,
            style: panelStyle
          }, [
            vue.h("div", {
              class: ["vxe-pulldown--panel-wrapper", {
                "is--shadow": showPopupShadow
              }]
            }, initialized && (destroyOnClose ? visiblePanel || isAniVisible : true) ? [
              headerSlot ? vue.h("div", {
                class: "vxe-pulldown--panel-header"
              }, headerSlot({ $pulldown: $xePulldown })) : index_esm.renderEmptyElement(),
              vue.h("div", {
                class: "vxe-pulldown--panel-body"
              }, dropdownSlot ? dropdownSlot({ $pulldown: $xePulldown }) : [
                renderDefaultPanel(options)
              ]),
              footerSlot ? vue.h("div", {
                class: "vxe-pulldown--panel-footer"
              }, footerSlot({ $pulldown: $xePulldown })) : index_esm.renderEmptyElement()
            ] : [])
          ])
        ])
      ]);
    };
    $xePulldown.renderVN = renderVN;
    return $xePulldown;
  },
  render() {
    return this.renderVN();
  }
});
exports.default = VxePulldownComponent;
