/**
 * ldesign v0.3.13
 * (c) 2023 ldesign
 * @license MIT
 */

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var vue = require('vue');
var core = require('@popperjs/core');
var isString = require('lodash/isString');
var isFunction = require('lodash/isFunction');
var isObject = require('lodash/isObject');
var hooks_useConfig = require('../hooks/useConfig.js');
var utils_dom = require('../utils/dom.js');
var utils_renderTnode = require('../utils/render-tnode.js');
var _common_js_utils_setStyle = require('../_common/js/utils/set-style.js');
var hooks_useVModel = require('../hooks/useVModel.js');
var popup_props = require('./props.js');
var popup_container = require('./container.js');
require('../config-provider/useConfig.js');
require('lodash/cloneDeep');
require('../config-provider/context.js');
require('lodash/mergeWith');
require('lodash/merge');
require('lodash/isArray');
require('../_common/js/global-config/default-config.js');
require('../_common/js/global-config/locale/zh_CN.js');
require('@babel/runtime/helpers/typeof');
require('../_chunks/dep-f4db2590.js');
require('dayjs');
require('../utils/easing.js');
require('lodash/isEmpty');
require('lodash/camelCase');
require('lodash/kebabCase');
require('@babel/runtime/helpers/toConsumableArray');
require('lodash/isUndefined');
require('../hooks/useResizeObserver.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray);
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
var isString__default = /*#__PURE__*/_interopDefaultLegacy(isString);
var isFunction__default = /*#__PURE__*/_interopDefaultLegacy(isFunction);
var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _isSlot(s) {
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
}
var triggers = ["click", "hover", "focus", "context-menu"];
var injectionKey = Symbol("popup");
function getPopperPlacement(placement) {
  return placement.replace(/-(left|top)$/, "-start").replace(/-(right|bottom)$/, "-end");
}
function attachListeners(elm) {
  var offs = [];
  return {
    add: function add(type, listener) {
      utils_dom.on(elm.value, type, listener);
      offs.push(function () {
        utils_dom.off(elm.value, type, listener);
      });
    },
    clean: function clean() {
      offs.forEach(function (handler) {
        return handler === null || handler === void 0 ? void 0 : handler();
      });
      offs.length = 0;
    }
  };
}
var _Popup = vue.defineComponent({
  name: "TPopup",
  props: _objectSpread(_objectSpread({}, popup_props["default"]), {}, {
    expandAnimation: {
      type: Boolean
    }
  }),
  setup: function setup(props2, _ref) {
    var expose = _ref.expose;
    var _toRefs = vue.toRefs(props2),
      visible = _toRefs.visible,
      modelValue = _toRefs.modelValue;
    var _useVModel = hooks_useVModel["default"](visible, modelValue, props2.defaultVisible, props2.onVisibleChange, "visible"),
      _useVModel2 = _slicedToArray__default["default"](_useVModel, 2),
      innerVisible = _useVModel2[0],
      setInnerVisible = _useVModel2[1];
    var popper;
    var timeoutId;
    var hasDocumentEvent = false;
    var visibleState = vue.ref(0);
    var mouseInRange = vue.ref(false);
    var contentClicked = vue.ref(false);
    var triggerEl = vue.ref(null);
    var overlayEl = vue.ref(null);
    var popperEl = vue.ref(null);
    var containerRef = vue.ref(null);
    var parent = vue.inject(injectionKey, void 0);
    var prefixCls = hooks_useConfig.usePrefixClass("popup");
    var _useCommonClassName = hooks_useConfig.useCommonClassName(),
      commonCls = _useCommonClassName.STATUS;
    var overlayCls = vue.computed(function () {
      var _ref2;
      return ["".concat(prefixCls.value, "__content"), (_ref2 = {}, _defineProperty__default["default"](_ref2, "".concat(prefixCls.value, "__content--text"), isString__default["default"](props2.content)), _defineProperty__default["default"](_ref2, "".concat(prefixCls.value, "__content--arrow"), props2.showArrow), _defineProperty__default["default"](_ref2, commonCls.value.disabled, props2.disabled), _ref2), props2.overlayInnerClassName];
    });
    var hasTrigger = vue.computed(function () {
      return triggers.reduce(function (map, trigger2) {
        return _objectSpread(_objectSpread({}, map), {}, _defineProperty__default["default"]({}, trigger2, props2.trigger.includes(trigger2)));
      }, {});
    });
    var delay = vue.computed(function () {
      var _props2$delay, _delay2$;
      var delay2 = [].concat((_props2$delay = props2.delay) !== null && _props2$delay !== void 0 ? _props2$delay : [250, 150]);
      return {
        open: delay2[0],
        close: (_delay2$ = delay2[1]) !== null && _delay2$ !== void 0 ? _delay2$ : delay2[0]
      };
    });
    function getOverlayStyle() {
      var overlayStyle = props2.overlayStyle;
      if (!triggerEl.value || !overlayEl.value) return;
      if (isFunction__default["default"](overlayStyle)) return overlayStyle(triggerEl.value, overlayEl.value);
      if (isObject__default["default"](overlayStyle)) return overlayStyle;
    }
    function updateOverlayInnerStyle() {
      var overlayInnerStyle = props2.overlayInnerStyle;
      if (!triggerEl.value || !overlayEl.value) return;
      if (isFunction__default["default"](overlayInnerStyle)) _common_js_utils_setStyle["default"](overlayEl.value, overlayInnerStyle(triggerEl.value, overlayEl.value));else if (isObject__default["default"](overlayInnerStyle)) _common_js_utils_setStyle["default"](overlayEl.value, overlayInnerStyle);
    }
    function updatePopper() {
      if (!popperEl.value || !innerVisible.value) return;
      if (popper) {
        popper.state.elements.reference = triggerEl.value;
        popper.update();
        return;
      }
      popper = core.createPopper(triggerEl.value, popperEl.value, _objectSpread({
        placement: getPopperPlacement(props2.placement),
        onFirstUpdate: function onFirstUpdate() {
          vue.nextTick(updatePopper);
        }
      }, props2.popperOptions));
    }
    function destroyPopper() {
      var _containerRef$value;
      if (popper) {
        var _popper;
        (_popper = popper) === null || _popper === void 0 ? void 0 : _popper.destroy();
        popper = null;
      }
      if (props2.destroyOnClose) (_containerRef$value = containerRef.value) === null || _containerRef$value === void 0 ? void 0 : _containerRef$value.unmountContent();
    }
    function emitVisible(visible2, context) {
      if (props2.disabled || visible2 === innerVisible.value) return;
      if (!visible2 && visibleState.value > 1) return;
      setInnerVisible(visible2, context);
    }
    function preventClosing(preventing) {
      parent === null || parent === void 0 ? void 0 : parent.preventClosing(preventing);
      if (preventing) {
        visibleState.value += 1;
      } else if (visibleState.value) {
        visibleState.value -= 1;
        if (!visibleState.value) {
          emitVisible(false, {});
          if (parent !== null && parent !== void 0 && parent.hasTrigger.value.hover && !(parent !== null && parent !== void 0 && parent.mouseInRange)) parent.emitVisible(false, {});
        }
      }
    }
    function handleToggle(context) {
      emitVisible(!innerVisible.value, context);
    }
    function handleOpen(context) {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(function () {
        emitVisible(true, context);
      }, hasTrigger.value.click ? 0 : delay.value.open);
    }
    function handleClose(context) {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(function () {
        emitVisible(false, context);
      }, hasTrigger.value.click ? 0 : delay.value.close);
    }
    function handleDocumentClick(ev) {
      if (contentClicked.value) {
        setTimeout(function () {
          contentClicked.value = false;
        });
        return;
      }
      if (triggerEl.value.contains(ev.target)) return;
      visibleState.value = 0;
      emitVisible(false, {
        trigger: "document"
      });
    }
    function onMouseEnter() {
      mouseInRange.value = true;
      handleOpen({});
    }
    function onMouseLeave(ev) {
      if (visibleState.value > 1) {
        var rect = popperEl.value.getBoundingClientRect();
        if (ev.x > rect.x && ev.x < rect.x + rect.width && ev.y > rect.y && ev.y < rect.y + rect.height) return;
      }
      mouseInRange.value = false;
      handleClose({});
      if (parent !== null && parent !== void 0 && parent.mouseInRange) parent.onMouseLeave(ev);
    }
    function handleOnScroll(e) {
      var _props2$onScroll;
      var _e$target = e.target,
        scrollTop = _e$target.scrollTop,
        clientHeight = _e$target.clientHeight,
        scrollHeight = _e$target.scrollHeight;
      if (scrollHeight - scrollTop === clientHeight) {
        var _props2$onScrollToBot;
        (_props2$onScrollToBot = props2.onScrollToBottom) === null || _props2$onScrollToBot === void 0 ? void 0 : _props2$onScrollToBot.call(props2, {
          e: e
        });
      }
      (_props2$onScroll = props2.onScroll) === null || _props2$onScroll === void 0 ? void 0 : _props2$onScroll.call(props2, {
        e: e
      });
    }
    var trigger = attachListeners(triggerEl);
    vue.watch(function () {
      return [props2.trigger, triggerEl.value];
    }, function () {
      if (!triggerEl.value) return;
      trigger.clean();
      if (hasTrigger.value.hover) {
        trigger.add("mouseenter", function () {
          return handleOpen({
            trigger: "trigger-element-hover"
          });
        });
        trigger.add("mouseleave", function () {
          return handleClose({
            trigger: "trigger-element-hover"
          });
        });
      } else if (hasTrigger.value.focus) {
        trigger.add("focusin", function () {
          return handleOpen({
            trigger: "trigger-element-focus"
          });
        });
        trigger.add("focusout", function () {
          return handleClose({
            trigger: "trigger-element-blur"
          });
        });
      } else if (hasTrigger.value.click) {
        trigger.add("click", function (e) {
          handleToggle({
            e: e,
            trigger: "trigger-element-click"
          });
        });
      } else if (hasTrigger.value["context-menu"]) {
        trigger.add("contextmenu", function (e) {
          e.preventDefault();
          e.button === 2 && handleToggle({
            trigger: "context-menu"
          });
        });
      }
    });
    vue.watch(function () {
      return [props2.overlayStyle, props2.overlayInnerStyle, overlayEl.value];
    }, function () {
      updateOverlayInnerStyle();
      updatePopper();
    });
    var updateScrollTop = vue.inject("updateScrollTop", function () {});
    vue.watch(function () {
      return [innerVisible.value, overlayEl.value];
    }, function () {
      if (innerVisible.value && overlayEl.value && updateScrollTop) updateScrollTop === null || updateScrollTop === void 0 ? void 0 : updateScrollTop(overlayEl.value);
    });
    vue.watch(function () {
      return props2.placement;
    }, function () {
      destroyPopper();
      updatePopper();
    });
    vue.watch(contentClicked, function (clicked) {
      if (parent) parent.contentClicked.value = clicked;
    });
    vue.watch(function () {
      return innerVisible.value;
    }, function (visible2) {
      if (visible2) {
        preventClosing(true);
        if (!hasDocumentEvent) {
          utils_dom.on(document, "click", handleDocumentClick, true);
          hasDocumentEvent = true;
        }
        if (triggerEl.value && hasTrigger.value.focus) {
          utils_dom.once(triggerEl.value, "keydown", function (ev) {
            if (ev.code === "Escape") handleClose({
              trigger: "keydown-esc"
            });
          });
        }
      } else {
        preventClosing(false);
        utils_dom.off(document, "click", handleDocumentClick, true);
        hasDocumentEvent = false;
        mouseInRange.value = false;
      }
    });
    vue.onUnmounted(function () {
      if (innerVisible.value) parent === null || parent === void 0 ? void 0 : parent.preventClosing(false);
      destroyPopper();
      utils_dom.off(document, "click", handleDocumentClick, true);
      clearTimeout(timeoutId);
    });
    vue.provide(injectionKey, {
      preventClosing: preventClosing,
      emitVisible: emitVisible,
      contentClicked: contentClicked,
      mouseInRange: mouseInRange,
      onMouseLeave: onMouseLeave,
      hasTrigger: hasTrigger
    });
    expose({
      handleClose: handleClose,
      updatePopper: updatePopper,
      getOverlay: function getOverlay() {
        return overlayEl.value;
      }
    });
    return {
      containerRef: containerRef,
      innerVisible: innerVisible,
      triggerEl: triggerEl,
      overlayEl: overlayEl,
      popperEl: popperEl,
      prefixCls: prefixCls,
      overlayCls: overlayCls,
      hasTrigger: hasTrigger,
      contentClicked: contentClicked,
      updatePopper: updatePopper,
      destroyPopper: destroyPopper,
      getOverlayStyle: getOverlayStyle,
      updateOverlayInnerStyle: updateOverlayInnerStyle,
      emitVisible: emitVisible,
      onMouseEnter: onMouseEnter,
      onMouseLeave: onMouseLeave,
      handleOnScroll: handleOnScroll
    };
  },
  render: function render() {
    var _this = this;
    var prefixCls = this.prefixCls,
      innerVisible = this.innerVisible,
      destroyOnClose = this.destroyOnClose,
      hasTrigger = this.hasTrigger,
      getOverlayStyle = this.getOverlayStyle,
      handleOnScroll = this.handleOnScroll;
    var content = utils_renderTnode.renderTNodeJSX(this, "content");
    var hidePopup = this.hideEmptyPopup && ["", void 0, null].includes(content);
    var overlay = innerVisible || !destroyOnClose ? vue.withDirectives(vue.createVNode("div", vue.mergeProps({
      "class": [prefixCls, this.overlayClassName],
      "ref": "popperEl",
      "style": [hidePopup && {
        visibility: "hidden",
        pointerEvents: "none"
      }, {
        zIndex: this.zIndex
      }, getOverlayStyle()],
      "onMousedown": function onMousedown() {
        _this.contentClicked = true;
      }
    }, hasTrigger.hover && {
      onMouseenter: this.onMouseEnter,
      onMouseleave: this.onMouseLeave
    }), [vue.createVNode("div", {
      "class": this.overlayCls,
      "ref": "overlayEl",
      "onScroll": handleOnScroll
    }, [content, this.showArrow && vue.createVNode("div", {
      "class": "".concat(prefixCls, "__arrow")
    }, null)])]), [[vue.vShow, innerVisible]]) : null;
    return vue.createVNode(popup_container["default"], {
      "ref": "containerRef",
      "forwardRef": function forwardRef(ref2) {
        return _this.triggerEl = ref2;
      },
      "onContentMounted": function onContentMounted() {
        if (innerVisible) {
          _this.updatePopper();
          _this.updateOverlayInnerStyle();
        }
      },
      "onResize": function onResize() {
        if (innerVisible) _this.updatePopper();
      },
      "visible": innerVisible,
      "attach": this.attach
    }, {
      content: function content() {
        return vue.createVNode(vue.Transition, {
          "name": _this.expandAnimation ? "".concat(prefixCls, "--animation-expand") : "".concat(prefixCls, "--animation"),
          "appear": true,
          "onEnter": _this.updatePopper,
          "onAfterLeave": _this.destroyPopper
        }, _isSlot(overlay) ? overlay : {
          "default": function _default() {
            return [overlay];
          }
        });
      },
      "default": function _default() {
        return utils_renderTnode.renderContent(_this, "default", "triggerElement");
      }
    });
  }
});

exports["default"] = _Popup;
//# sourceMappingURL=popup.js.map
