/**
 * tdesign v0.39.1-alpha.1
 * (c) 2022 tdesign
 * @license MIT
 */

import _typeof from '@babel/runtime/helpers/typeof';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import Vue from 'vue';
import { createPopper } from '@popperjs/core';
import { prefix } from '../config.js';
import ClASSNAMES from '../utils/classnames.js';
import { on, once, off } from '../utils/dom.js';
import { renderContent, renderTNodeJSX } from '../utils/render-tnode.js';
import { getIEVersion } from '../utils/helper.js';
import setStyle from '../_common/js/utils/set-style.js';
import popupProps from './props.js';
import Container from './container.js';
import 'raf';
import 'lodash/isString';
import '../utils/easing.js';
import 'lodash/isObject';
import '@babel/runtime/helpers/objectWithoutProperties';
import '@babel/runtime/helpers/slicedToArray';
import 'lodash/camelCase';

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(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; }
var name = "".concat(prefix, "-popup");
var showTimeout = 250;
var hideTimeout = 150;
var triggers = ["click", "hover", "focus", "context-menu"];

function getPopperPlacement(placement) {
  return placement.replace(/-(left|top)$/, "-start").replace(/-(right|bottom)$/, "-end");
}

var Popup = Vue.extend({
  name: "TPopup",
  provide: function provide() {
    return {
      popup: this
    };
  },
  inject: {
    popup: {
      "default": void 0
    }
  },
  props: _objectSpread(_objectSpread({}, popupProps), {}, {
    expandAnimation: {
      type: Boolean
    }
  }),
  data: function data() {
    return {
      name: name,
      popper: null,
      timeout: null,
      hasDocumentEvent: false,
      visibleState: 0,
      mouseInRange: false,
      contentClicked: false,
      refClicked: false
    };
  },
  computed: {
    overlayClasses: function overlayClasses() {
      var _ref;

      var base = ["".concat(name, "__content"), (_ref = {}, _defineProperty(_ref, "".concat(name, "__content--text"), this.content === "string"), _defineProperty(_ref, "".concat(name, "__content--arrow"), this.showArrow), _defineProperty(_ref, ClASSNAMES.STATUS.disabled, this.disabled), _ref)];
      return base.concat(this.overlayClassName);
    },
    hasTrigger: function hasTrigger() {
      var _this = this;

      return triggers.reduce(function (map, trigger) {
        return _objectSpread(_objectSpread({}, map), {}, _defineProperty({}, trigger, _this.trigger.includes(trigger)));
      }, {});
    }
  },
  watch: {
    visible: function visible(val) {
      var _this2 = this;

      var reference = this.$el;
      var hasTrigger = this.hasTrigger;

      if (val) {
        this.preventClosing(true);

        if (!this.hasDocumentEvent) {
          on(document, "click", this.handleDocumentClick);
          this.hasDocumentEvent = true;
        }

        if (reference && hasTrigger.focus) {
          once(reference, "keydown", function (ev) {
            if (ev.code === "Escape") {
              _this2.handleClose({
                trigger: "keydown-esc"
              });
            }
          });
        }
      } else {
        this.preventClosing(false);
        off(document, "click", this.handleDocumentClick);
        this.hasDocumentEvent = false;
        this.mouseInRange = false;
      }
    },
    overlayStyle: function overlayStyle() {
      if (this.popper) {
        this.popper.update();
        this.updateOverlayStyle();
      }
    },
    contentClicked: function contentClicked(clicked) {
      if (this.popup) {
        this.popup.contentClicked = clicked;
      }
    }
  },
  mounted: function mounted() {
    var _this3 = this;

    var reference = this.$el;
    var hasTrigger = this.hasTrigger;

    if (hasTrigger.hover) {
      on(reference, "mouseenter", function () {
        return _this3.handleOpen({
          trigger: "trigger-element-hover"
        });
      });
      on(reference, "mouseleave", function () {
        return _this3.handleClose({
          trigger: "trigger-element-hover"
        });
      });
      on(reference, "click", function () {
        _this3.refClicked = true;
      });
    } else if (hasTrigger.focus) {
      on(reference, "focusin", function () {
        return _this3.handleOpen({
          trigger: "trigger-element-focus"
        });
      });
      on(reference, "focusout", function () {
        return _this3.handleClose({
          trigger: "trigger-element-blur"
        });
      });
    } else if (hasTrigger.click) {
      on(reference, "click", function (e) {
        _this3.refClicked = true;
        _this3.visibleState = 0;

        _this3.handleToggle({
          e: e,
          trigger: "trigger-element-click"
        });

        if (getIEVersion() < 11) {
          _this3.handleDocumentClick();
        }
      });
    } else if (hasTrigger["context-menu"]) {
      on(reference, "contextmenu", function (e) {
        e.preventDefault();
        e.button === 2 && _this3.handleToggle({
          trigger: "context-menu"
        });
      });
    }
  },
  updated: function updated() {
    var _this$$refs$container;

    (_this$$refs$container = this.$refs.container) === null || _this$$refs$container === void 0 ? void 0 : _this$$refs$container.updateContent();
  },
  destroyed: function destroyed() {
    this.destroyPopper();
  },
  methods: {
    createPopper: function createPopper$1() {
      var _this$popper,
          _this4 = this;

      var reference = this.$el;
      var currentPlacement = this.placement;
      var popperElm = this.$refs.popper;
      if (!popperElm) return;
      (_this$popper = this.popper) === null || _this$popper === void 0 ? void 0 : _this$popper.destroy();
      this.popper = createPopper(reference, popperElm, {
        modifiers: getIEVersion() > 9 ? [] : [{
          name: "computeStyles",
          options: {
            gpuAcceleration: false
          }
        }],
        placement: getPopperPlacement(currentPlacement),
        onFirstUpdate: function onFirstUpdate() {
          _this4.$nextTick(_this4.updatePopper);
        }
      });
    },
    updatePopper: function updatePopper() {
      if (this.popper) {
        this.popper.update();
        return;
      }

      this.createPopper();
    },
    updateOverlayStyle: function updateOverlayStyle() {
      var overlayStyle = this.overlayStyle;
      var referenceElm = this.$el;
      if (!this.$refs) return;
      var refOverlayElm = this.$refs.overlay;

      if (typeof overlayStyle === "function" && referenceElm && refOverlayElm) {
        var userOverlayStyle = overlayStyle(referenceElm, refOverlayElm);
        this.setOverlayStyle(userOverlayStyle);
      } else if (_typeof(overlayStyle) === "object" && refOverlayElm) {
        this.setOverlayStyle(overlayStyle);
      }
    },
    setOverlayStyle: function setOverlayStyle(styles) {
      if (!this.$refs) return;
      var refOverlayElm = this.$refs.overlay;

      if (_typeof(styles) === "object" && refOverlayElm) {
        setStyle(refOverlayElm, styles);
      }
    },
    destroyPopper: function destroyPopper() {
      var _this$popper2;

      (_this$popper2 = this.popper) === null || _this$popper2 === void 0 ? void 0 : _this$popper2.destroy();
      this.popper = null;

      if (this.destroyOnClose) {
        var _this$$refs$container2;

        (_this$$refs$container2 = this.$refs.container) === null || _this$$refs$container2 === void 0 ? void 0 : _this$$refs$container2.unmountContent();
      }
    },
    handleToggle: function handleToggle(context) {
      this.emitPopVisible(!this.visible, context);
    },
    handleOpen: function handleOpen(context) {
      var _this5 = this;

      clearTimeout(this.timeout);
      this.timeout = setTimeout(function () {
        _this5.emitPopVisible(true, context);
      }, this.hasTrigger.click ? 0 : showTimeout);
    },
    handleClose: function handleClose(context) {
      var _this6 = this;

      clearTimeout(this.timeout);
      this.timeout = setTimeout(function () {
        _this6.emitPopVisible(false, context);
      }, this.hasTrigger.click ? 0 : hideTimeout);
    },
    handleDocumentClick: function handleDocumentClick() {
      var _this7 = this;

      if (this.contentClicked || this.refClicked) {
        this.refClicked = false;
        setTimeout(function () {
          _this7.contentClicked = false;
        });
        return;
      }

      this.visibleState = 0;
      this.emitPopVisible(false, {
        trigger: "document"
      });
    },
    emitPopVisible: function emitPopVisible(val, context) {
      if (this.disabled || val === this.visible) return;
      if (!val && this.visibleState > 1) return;
      if (val && this.mouseInRange) return;
      this.$emit("visible-change", val, context);

      if (typeof this.onVisibleChange === "function") {
        this.onVisibleChange(val, context);
      }
    },
    onMouseEnter: function onMouseEnter() {
      this.mouseInRange = true;
      this.handleOpen({});
    },
    onMouseLeave: function onMouseLeave(ev) {
      if (this.visibleState > 1) {
        var rect = this.$refs.popper.getBoundingClientRect();
        if (ev.x > rect.x && ev.x < rect.x + rect.width && ev.y > rect.y && ev.y < rect.y + rect.height) return;
      }

      this.mouseInRange = false;
      this.handleClose({});
      var parent = this.popup;

      if (parent !== null && parent !== void 0 && parent.mouseInRange) {
        parent.onMouseLeave(ev);
      }
    },
    onBeforeEnter: function onBeforeEnter() {
      if (this.visible) {
        this.updatePopper();
      }
    },
    onAfterEnter: function onAfterEnter() {
      if (this.visible) {
        this.updatePopper();
      }
    },
    preventClosing: function preventClosing(preventing) {
      var parent = this.popup;
      parent === null || parent === void 0 ? void 0 : parent.preventClosing(preventing);

      if (preventing) {
        this.visibleState += 1;
      } else if (this.visibleState) {
        this.visibleState -= 1;

        if (!this.visibleState) {
          this.emitPopVisible(false, {});

          if (parent !== null && parent !== void 0 && parent.hasTrigger.hover && !(parent !== null && parent !== void 0 && parent.mouseInRange)) {
            parent.emitPopVisible(false, {});
          }
        }
      }
    }
  },
  render: function render(h) {
    var _this8 = this;

    var visible = this.visible,
        destroyOnClose = this.destroyOnClose,
        hasTrigger = this.hasTrigger,
        onScroll = this.onScroll;
    var ref = renderContent(this, "default", "triggerElement");
    var content = renderTNodeJSX(this, "content");

    if (this.hideEmptyPopup && ["", void 0, null].includes(content)) {
      return ref;
    }

    var overlay = visible || !destroyOnClose ? h("div", {
      "class": name,
      ref: "popper",
      directives: destroyOnClose ? void 0 : [{
        name: "show",
        rawName: "v-show",
        value: visible,
        expression: "visible"
      }],
      on: _objectSpread({
        mousedown: function mousedown() {
          _this8.contentClicked = true;
        },
        mouseup: function mouseup() {
          setTimeout(function () {
            _this8.contentClicked = false;
          });
        }
      }, hasTrigger.hover && {
        mouseenter: this.onMouseEnter,
        mouseleave: this.onMouseLeave
      })
    }, [h("div", {
      "class": this.overlayClasses,
      ref: "overlay",
      on: onScroll ? {
        scroll: function scroll(e) {
          onScroll({
            e: e
          });
        }
      } : void 0
    }, [content, this.showArrow && h("div", {
      "class": "".concat(name, "__arrow")
    })])]) : null;
    return h(Container, {
      "ref": "container",
      "on": {
        "mounted": function mounted() {
          if (visible) {
            _this8.updatePopper();

            _this8.updateOverlayStyle();
          }
        },
        "refResize": function refResize() {
          if (visible) {
            _this8.updatePopper();
          }
        }
      },
      "attrs": {
        "parent": this,
        "visible": visible,
        "attach": this.attach
      }
    }, [h("transition", {
      "slot": "content",
      "attrs": {
        "name": this.expandAnimation ? "".concat(name, "--animation-expand") : "".concat(name, "--animation"),
        "appear": true
      },
      "on": {
        "beforeEnter": this.onBeforeEnter,
        "afterEnter": this.onAfterEnter,
        "afterLeave": this.destroyPopper
      }
    }, [(visible || !destroyOnClose) && overlay]), ref]);
  }
});

export { Popup as default };
//# sourceMappingURL=popup.js.map
