/**
 * ldesign v0.2.22
 * (c) 2022/12/7 16:21 built by swimly
 * @license MIT
 */

import isNumber from 'lodash/isNumber';
import throttle from 'lodash/throttle';
import { InfoCircleFilledIcon, CheckCircleFilledIcon, ErrorCircleFilledIcon, CloseIcon } from '@ldesign/icons-vue';
import { Button } from '../button/index.js';
import { renderContent, renderLNodeJSX } from '../../utils/render-node.js';
import mixins from '../../utils/mixins.js';
import getConfigReceiverMixins, { getGlobalIconMixins } from '../config-provider/config-receiver.js';
import TransferDom from '../../utils/transfer-dom.js';
import { emitEvent } from '../../utils/event.js';
import { updateElement } from '../../hooks/useDestroyOnClose.js';
import props from './props.js';
import ActionMixin from './actions.js';
import stack from './stack.js';
import '../../utils/withInstall.js';
import 'vue';
import 'lodash/capitalize';
import '../../config.js';
import '../button/button.js';
import '../loading/index.js';
import '../loading/loading.js';
import '../../utils/dom.js';
import 'raf';
import 'lodash/isString';
import '../../_chunks/dep-eaa95999.js';
import '../../_chunks/dep-102361be.js';
import '../../utils/easing.js';
import '../loading/props.js';
import '../loading/icon/gradient.js';
import '../../_chunks/dep-aacc31a3.js';
import '../../_chunks/dep-c68dc4b6.js';
import '../../_chunks/dep-1a6bca30.js';
import 'lodash';
import 'lodash/mergeWith';
import '../config-provider/context.js';
import 'lodash/merge';
import '../../_chunks/dep-b4fd1955.js';
import '../loading/plugin.js';
import '../../utils/ripple.js';
import '../button/props.js';
import '../../utils/helper.js';
import 'lodash/camelCase';
import '../../_chunks/dep-b0f1ed22.js';
import 'lodash/isObject';

function getCSSValue(v) {
  return isNaN(Number(v)) ? v : `${Number(v)}px`;
}
let mousePosition;
const getClickPosition = e => {
  mousePosition = {
    x: e.clientX,
    y: e.clientY
  };
  setTimeout(() => {
    mousePosition = null;
  }, 100);
};
if (typeof window !== "undefined" && window.document && window.document.documentElement) document.documentElement.addEventListener("click", getClickPosition, true);
let key = 1;
var _Dialog = mixins(ActionMixin, getConfigReceiverMixins("dialog"), getGlobalIconMixins()).extend({
  name: "LDialog",
  components: {
    TButton: Button
  },
  data() {
    return {
      uid: 0,
      scrollWidth: 0,
      disX: 0,
      disY: 0,
      windowInnerWidth: 0,
      windowInnerHeight: 0,
      dialogW: 0,
      dialogH: 0,
      dLeft: 0,
      dTop: 0,
      styleEl: null,
      timer: null,
      animationEnd: false
    };
  },
  props: {
    ...props
  },
  computed: {
    isModal() {
      return this.mode === "modal";
    },
    isModeLess() {
      return this.mode === "modeless";
    },
    isNormal() {
      return this.mode === "normal";
    },
    maskClass() {
      return [`${this.componentName}__mask`, !this.showOverlay && `${this.classPrefix}-is-hidden`];
    },
    dialogClass() {
      const dialogClass = [`${this.componentName}`, `${this.componentName}--default`, `${this.componentName}__modal-${this.theme}`, this.isModeLess && this.draggable && `${this.componentName}--draggable`];
      return dialogClass;
    },
    positionClass() {
      if (this.isNormal) return [];
      const dialogClass = [`${this.componentName}__position`, !!this.top && `${this.componentName}--top`, `${this.placement && !this.top ? `${this.componentName}--${this.placement}` : ""}`];
      return dialogClass;
    },
    wrapClass() {
      return [!this.isNormal && `${this.componentName}__wrap`];
    },
    bodyClass() {
      return [`${this.componentName}__body`, {
        [`${this.componentName}__body--icon`]: this.theme !== "default"
      }];
    },
    ctxClass() {
      return [`${this.componentName}__ctx`, {
        [`${this.classPrefix}-dialog__ctx--fixed`]: this.mode === "modal",
        [`${this.classPrefix}-dialog__ctx--absolute`]: this.isModal && this.showInAttachedElement,
        [`${this.componentName}__ctx--modeless`]: this.isModeLess
      }];
    },
    positionStyle() {
      const topStyle = {};
      if (this.top !== void 0) {
        if (isNumber(this.top) && this.top < 0) topStyle.paddingTop = `${this.top}px`;else topStyle.paddingTop = this.top;
      }
      return topStyle;
    },
    dialogStyle() {
      return {
        width: getCSSValue(this.width)
      };
    }
  },
  watch: {
    visible(value) {
      if (value) {
        this.animationEnd = false;
        if (this.isModal && !this.showInAttachedElement && this.preventScrollThrough) {
          document.head.appendChild(this.styleEl);
          this.$nextTick(() => {
            const target = this.$refs.dialog;
            if (mousePosition && target) {
              target.style.transformOrigin = `${mousePosition.x - target.offsetLeft}px ${mousePosition.y - target.offsetTop}px`;
            }
          });
        }
        document.activeElement.blur();
      } else {
        this.clearStyleFunc();
      }
      this.storeUid(value);
      this.addKeyboardEvent(value);
      if (this.isModeLess && this.draggable) this.initDragEvent(value);
      if (value && !this.destroyOnClose && requestAnimationFrame) {
        requestAnimationFrame(() => {
          updateElement(this);
        });
      }
    }
  },
  mounted() {
    this.scrollWidth = window.innerWidth - document.body.offsetWidth;
    if (this.draggable) window.addEventListener("resize", throttle(this.resizeAdjustPosition, 1e3));
    this.uid = this._uid;
    this.styleEl = document.createElement("style");
    this.styleEl.dataset.id = `td_dialog_${+new Date()}_${key += 1}`;
    this.styleEl.innerHTML = `
      html body {
        overflow-y: hidden;
        width: calc(100% - ${this.scrollWidth}px);
      }
    `;
    if (this.visible && this.isModal && this.preventScrollThrough && !this.showInAttachedElement) document.head.appendChild(this.styleEl);
  },
  beforeDestroy() {
    this.addKeyboardEvent(false);
    this.clearStyleFunc();
  },
  directives: {
    TransferDom
  },
  methods: {
    clearStyleFunc() {
      clearTimeout(this.timer);
      this.timer = setTimeout(() => {
        this.styleEl.parentNode?.removeChild?.(this.styleEl);
      }, 150);
    },
    storeUid(flag) {
      if (flag) stack.push(this.uid);else stack.pop();
    },
    addKeyboardEvent(status) {
      if (status) {
        document.addEventListener("keydown", this.keyboardEvent);
        this.confirmOnEnter && document.addEventListener("keydown", this.keyboardEnterEvent);
      } else {
        document.removeEventListener("keydown", this.keyboardEvent);
        this.confirmOnEnter && document.removeEventListener("keydown", this.keyboardEnterEvent);
      }
    },
    keyboardEvent(e) {
      if (e.code === "Escape" && stack.top === this.uid) {
        emitEvent(this, "esc-keydown", {
          e
        });
        if (this.closeOnEscKeydown ?? this.global.closeOnEscKeydown) this.emitCloseEvent({
          e,
          trigger: "esc"
        });
      }
    },
    keyboardEnterEvent(e) {
      const {
        code
      } = e;
      if ((code === "Enter" || code === "NumpadEnter") && stack.top === this.uid) emitEvent(this, "confirm", {
        e
      });
    },
    overlayAction(e) {
      if (this.showOverlay && (this.closeOnOverlayClick ?? this.global.closeOnOverlayClick)) {
        if (e.target === this.$refs.dialogPosition) {
          emitEvent(this, "overlay-click", {
            e
          });
          this.emitCloseEvent({
            e,
            trigger: "overlay"
          });
        }
      }
    },
    closeBtnAction(e) {
      emitEvent(this, "close-btn-click", {
        e
      });
      this.emitCloseEvent({
        trigger: "close-btn",
        e
      });
    },
    cancelBtnAction(e) {
      emitEvent(this, "cancel", {
        e
      });
      this.emitCloseEvent({
        trigger: "cancel",
        e
      });
    },
    confirmBtnAction(e) {
      emitEvent(this, "confirm", {
        e
      });
    },
    afterEnter() {
      emitEvent(this, "opened");
    },
    afterLeave() {
      if (this.isModeLess && this.draggable) {
        const target = this.$refs.dialog;
        if (!target) return;
        target.style.position = "relative";
        target.style.left = "unset";
        target.style.top = "unset";
      }
      emitEvent(this, "closed");
      this.animationEnd = true;
    },
    emitCloseEvent(context) {
      emitEvent(this, "close", context);
      this.$emit("update:visible", false);
    },
    hasEventOn(name) {
      const eventFuncs = this["_events"]?.[name];
      return !!eventFuncs?.length;
    },
    getIcon() {
      const h = this.$createElement;
      const {
        InfoCircleFilledIcon: InfoCircleFilledIcon$1,
        CheckCircleFilledIcon: CheckCircleFilledIcon$1,
        ErrorCircleFilledIcon: ErrorCircleFilledIcon$1
      } = this.useGlobalIcon({
        InfoCircleFilledIcon: InfoCircleFilledIcon,
        CheckCircleFilledIcon: CheckCircleFilledIcon,
        ErrorCircleFilledIcon: ErrorCircleFilledIcon
      });
      const icon = {
        info: h(InfoCircleFilledIcon$1, {
          "class": `${this.classPrefix}-is-info`
        }),
        warning: h(ErrorCircleFilledIcon$1, {
          "class": `${this.classPrefix}-is-warning`
        }),
        danger: h(ErrorCircleFilledIcon$1, {
          "class": `${this.classPrefix}-is-error`
        }),
        success: h(CheckCircleFilledIcon$1, {
          "class": `${this.classPrefix}-is-success`
        })
      };
      return icon[this.theme];
    },
    mousedownHandler(targetEvent) {
      const target = this.$refs.dialog;
      this.disX = targetEvent.clientX - target.offsetLeft;
      this.disY = targetEvent.clientY - target.offsetTop;
      this.dialogW = target.offsetWidth;
      this.dialogH = target.offsetHeight;
      this.windowInnerWidth = window.innerWidth || document.documentElement.clientWidth;
      this.windowInnerHeight = window.innerHeight || document.documentElement.clientHeight;
      if (this.dialogW > this.windowInnerWidth || this.dialogH > this.windowInnerHeight) return;
      document.addEventListener("mousemove", this.mouseMoverHandler);
      document.addEventListener("mouseup", this.mouseUpHandler);
      document.addEventListener("dragend", this.mouseUpHandler);
    },
    mouseMoverHandler(documentEvent) {
      const target = this.$refs.dialog;
      let left = documentEvent.clientX - this.disX;
      let top = documentEvent.clientY - this.disY;
      if (left < 0) left = 0;
      if (top < 0) top = 0;
      if (this.windowInnerWidth - target.offsetWidth - left < 0) left = this.windowInnerWidth - target.offsetWidth;
      if (this.windowInnerHeight - target.offsetHeight - top < 0) top = this.windowInnerHeight - target.offsetHeight;
      target.style.position = "absolute";
      target.style.left = `${left}px`;
      target.style.top = `${top}px`;
    },
    mouseUpHandler() {
      document.removeEventListener("mousemove", this.mouseMoverHandler);
      document.removeEventListener("mouseup", this.mouseUpHandler);
      document.removeEventListener("dragend", this.mouseUpHandler);
    },
    initDragEvent(status) {
      const target = this.$refs.dialog;
      if (status) target.addEventListener("mousedown", this.mousedownHandler);else target.removeEventListener("mousedown", this.mousedownHandler);
    },
    resizeAdjustPosition() {
      if (this.visible) {
        const target = this.$refs.dialog;
        target.style.left = `${this.dLeft * (window.innerWidth / this.windowInnerWidth)}px`;
        target.style.top = `${this.dTop * (window.innerHeight / this.windowInnerHeight)}px`;
      }
    },
    onStopDown(e) {
      if (this.isModeLess && this.draggable) e.stopPropagation();
    },
    renderDialog() {
      const h = this.$createElement;
      const {
        CloseIcon: CloseIcon$1
      } = this.useGlobalIcon({
        CloseIcon: CloseIcon
      });
      const defaultHeader = h("h5", {
        "class": "title"
      });
      const defaultCloseBtn = h(CloseIcon$1);
      const body = renderContent(this, "default", "body");
      const defaultFooter = h("div", [this.getCancelBtn({
        cancelBtn: this.cancelBtn,
        globalCancel: this.global.cancel,
        className: `${this.componentName}__cancel`
      }), this.getConfirmBtn({
        theme: this.theme,
        confirmBtn: this.confirmBtn,
        globalConfirm: this.global.confirm,
        globalConfirmBtnTheme: this.global.confirmBtnTheme,
        className: `${this.componentName}__confirm`
      })]);
      const footer = this.footer ? h("div", {
        "class": `${this.componentName}__footer`,
        "on": {
          "mousedown": this.onStopDown
        }
      }, [renderLNodeJSX(this, "footer", defaultFooter)]) : null;
      return h("div", {
        "class": this.wrapClass
      }, [h("div", {
        "class": this.positionClass,
        "style": this.positionStyle,
        "on": {
          "click": this.overlayAction
        },
        "ref": "dialogPosition"
      }, [h("div", {
        "key": "dialog",
        "ref": "dialog",
        "class": this.dialogClass,
        "style": this.dialogStyle
      }, [h("div", {
        "class": `${this.componentName}__header`,
        "on": {
          "mousedown": this.onStopDown
        }
      }, [h("div", {
        "class": `${this.componentName}__header-content`
      }, [this.getIcon(), renderLNodeJSX(this, "header", defaultHeader)]), this.closeBtn ? h("span", {
        "class": `${this.componentName}__close`,
        "on": {
          "click": this.closeBtnAction
        }
      }, [renderLNodeJSX(this, "closeBtn", defaultCloseBtn)]) : null]), h("div", {
        "class": this.bodyClass,
        "on": {
          "mousedown": this.onStopDown
        }
      }, [body]), footer])])]);
    }
  },
  render() {
    const h = arguments[0];
    const maskView = this.isModal && h("div", {
      "key": "mask",
      "class": this.maskClass
    });
    const dialogView = this.renderDialog();
    const view = [maskView, dialogView];
    const ctxStyle = {
      zIndex: this.zIndex
    };
    if (this.destroyOnClose && !this.visible && this.animationEnd) return null;
    return h("transition", {
      "attrs": {
        "duration": 300,
        "name": `${this.componentName}-zoom__vue`
      },
      "on": {
        "afterEnter": this.afterEnter,
        "afterLeave": this.afterLeave
      }
    }, [h("div", {
      "directives": [{
        name: "show",
        value: this.visible
      }, {
        name: "transfer-dom",
        value: this.attach
      }],
      "class": this.ctxClass,
      "style": ctxStyle
    }, [view])]);
  }
});

export { _Dialog as default };
//# sourceMappingURL=dialog.js.map
