import { DtIconClose as d } from "@dialpad/dialtone-icons/vue2";
import c from "../../common/mixins/modal.js";
import { MODAL_BANNER_KINDS as i, MODAL_SIZE_MODIFIERS as n, MODAL_KIND_MODIFIERS as r } from "./modal-constants.js";
import { disableRootScrolling as m, enableRootScrolling as u, getUniqueString as f } from "../../common/utils/index.js";
import { EVENT_KEYNAMES as l } from "../../common/constants/index.js";
import h from "../../shared/sr_only_close_button.js";
import { DialtoneLocalization as p } from "../../localization/index.js";
import { Portal as _ } from "../../node_modules/@linusborg/vue-simple-portal.js";
import { n as y } from "../../_plugin-vue2_normalizer-DSLOjnn3.js";
import b from "../button/button.js";
import E from "../lazy-show/lazy-show.js";
import { NOTICE_KINDS as g } from "../notice/notice-constants.js";
const S = {
  name: "DtModal",
  components: {
    DtLazyShow: E,
    DtButton: b,
    DtIconClose: d,
    SrOnlyCloseButton: h,
    Portal: _
  },
  mixins: [c],
  props: {
    /**
     * Body text to display as the modal's main content.
     */
    copy: {
      type: String,
      default: ""
    },
    /**
     * Id to use for the dialog's aria-describedby.
     * Recommended only if the dialog content itself isn't enough to give full context,
     * as screen readers should recite the dialog contents by default before any aria-description.
     */
    describedById: {
      type: String,
      default: ""
    },
    /**
     * Id to use for the dialog's aria-labelledby.
     */
    labelledById: {
      type: String,
      default: function() {
        return f();
      }
    },
    /**
     * Whether the modal should be shown.
     * Parent component can sync on this value to control the modal's visibility.
     * @values true, false
     */
    show: {
      type: Boolean,
      default: !1
    },
    /**
     * Title text to display in the modal header.
     */
    title: {
      type: String,
      default: ""
    },
    /**
     * Title text to display in the modal banner.
     */
    bannerTitle: {
      type: String,
      default: ""
    },
    /**
     * The theme of the modal. kind - default or danger,
     * @values default, danger
     */
    kind: {
      type: String,
      default: "default",
      validator: (e) => Object.keys(r).includes(e)
    },
    /**
     * The size of the modal. size - default or full,
     * @values default, full
     */
    size: {
      type: String,
      default: "default",
      validator: (e) => Object.keys(n).includes(e)
    },
    /**
     * Additional class name for the root modal element.
     * Can accept String, Object, and Array, i.e. has the
     * same API as Vue's built-in handling of the class attribute.
     */
    modalClass: {
      type: [String, Object, Array],
      default: ""
    },
    /**
     * Additional class name for the dialog element within the modal.
     * Can accept String, Object, and Array, i.e. has the
     * same API as Vue's built-in handling of the class attribute.
     */
    dialogClass: {
      type: [String, Object, Array],
      default: ""
    },
    /**
     * Additional class name for the content element within the modal.
     * Can accept String, Object, and Array, i.e. has the
     * same API as Vue's built-in handling of the class attribute.
     */
    contentClass: {
      type: [String, Object, Array],
      default: ""
    },
    /**
     * Sets the color of the banner.
     * @values base, error, info, success, warning
     */
    bannerKind: {
      type: String,
      default: "warning",
      validate(e) {
        return g.includes(e);
      }
    },
    /**
     * Additional class name for the banner element within the modal.
     * Can accept String, Object, and Array, i.e. has the
     * same API as Vue's built-in handling of the class attribute.
     */
    bannerClass: {
      type: [String, Object, Array],
      default: ""
    },
    /**
     * Hides the close button on the modal
     * @values true, false
     */
    hideClose: {
      type: Boolean,
      default: !1
    },
    /**
     * Whether the modal will close when you click outside of the dialog on the overlay.
     * @values true, false
     */
    closeOnClick: {
      type: Boolean,
      default: !0
    },
    /**
     * Scrollable modal that allows scroll the modal content keeping the header and footer fixed
     * @values true, false
     */
    fixedHeaderFooter: {
      type: Boolean,
      default: !0
    },
    /**
     * The element that is focused when the modal is opened. This can be an
     * HTMLElement within the modal, a string starting with '#' which will
     * find the element by ID. 'first' which will automatically focus
     * the first element, or 'dialog' which will focus the dialog window itself.
     * If the dialog is modal this prop cannot be 'none'.
     */
    initialFocusElement: {
      type: [String, HTMLElement],
      default: "first",
      validator: (e) => e === "first" || e instanceof HTMLElement || e.startsWith("#")
    },
    /**
     * A CSS selector string for the element to portal the modal to. If not provided, the modal will be rendered in its default location.
     */
    appendTo: {
      type: String,
      default: void 0
    }
  },
  emits: [
    /**
     * The modal will emit a "false" boolean value for this event when the user performs a modal-closing action.
     * Parent components can sync on this value to create a 2-way binding to control modal visibility.
     *
     * @event update:show
     * @type {Boolean}
     */
    "update:show"
  ],
  data() {
    return {
      MODAL_KIND_MODIFIERS: r,
      MODAL_SIZE_MODIFIERS: n,
      MODAL_BANNER_KINDS: i,
      EVENT_KEYNAMES: l,
      i18n: new p()
    };
  },
  computed: {
    modalListeners() {
      return {
        ...this.$listeners,
        click: (e) => {
          this.closeOnClick && e.target === e.currentTarget ? this.close() : this.show && e.target !== e.currentTarget && this.handleModalClick(e), this.$emit("click", e);
        },
        keydown: (e) => {
          switch (e.code) {
            case l.esc:
            case l.escape:
              this.close();
              break;
            case l.tab:
              this.trapFocus(e);
              break;
          }
          this.$emit("keydown", e);
        },
        "after-enter": async () => {
          this.$emit("update:show", !0), await this.setFocusAfterTransition();
        }
      };
    },
    open() {
      return `${!this.show}`;
    },
    hasFooterSlot() {
      return !!this.$slots.footer;
    },
    bannerKindClass() {
      return i[this.bannerKind];
    },
    closeButtonTitle() {
      return this.i18n.$t("DIALTONE_CLOSE_BUTTON");
    }
  },
  watch: {
    show: {
      handler(e) {
        var t, a, o;
        if (e) {
          this.previousActiveElement = document.activeElement;
          const s = ((t = this.$refs.modalRoot) == null ? void 0 : t.$el) || this.$el;
          m(s.getRootNode().host);
        } else {
          const s = ((a = this.$refs.modalRoot) == null ? void 0 : a.$el) || this.$el;
          u(s.getRootNode().host), (o = this.previousActiveElement) == null || o.focus(), this.previousActiveElement = null;
        }
      }
    }
  },
  methods: {
    close() {
      this.$emit("update:show", !1);
    },
    async setFocusAfterTransition() {
      var t;
      const e = ((t = this.$refs.modalRoot) == null ? void 0 : t.$el) || this.$el;
      this.initialFocusElement === "first" ? await this.focusFirstElement(e) : this.initialFocusElement.startsWith("#") ? await this.focusElementById(this.initialFocusElement) : this.initialFocusElement instanceof HTMLElement && this.initialFocusElement.focus();
    },
    trapFocus(e) {
      var t;
      if (this.show) {
        const a = ((t = this.$refs.modalRoot) == null ? void 0 : t.$el) || this.$el;
        this.focusTrappedTabPress(e, a);
      }
    },
    handleModalClick(e) {
      var s;
      const t = e.target, a = ((s = this.$refs.modalRoot) == null ? void 0 : s.$el) || this.$el, o = this._getFocusableElements(a);
      o.length && !o.includes(t) && (o.includes(document.activeElement) || this.focusFirstElement(a));
    }
  }
};
var w = function() {
  var t = this, a = t._self._c;
  return a("portal", { attrs: { disabled: !t.appendTo, selector: t.appendTo } }, [a("dt-lazy-show", t._g({ ref: "modalRoot", class: [
    "d-modal",
    t.MODAL_KIND_MODIFIERS[t.kind],
    t.MODAL_SIZE_MODIFIERS[t.size],
    t.modalClass
  ], attrs: { transition: "d-zoom", show: t.show, "data-qa": "dt-modal", "aria-hidden": t.open } }, t.modalListeners), [t.show && (t.$slots.banner || t.bannerTitle) ? a("div", { class: [
    "d-modal__banner",
    t.bannerClass,
    t.bannerKindClass
  ], attrs: { "data-qa": "dt-modal-banner" } }, [t._t("banner", function() {
    return [t._v(" " + t._s(t.bannerTitle) + " ")];
  })], 2) : t._e(), a("transition", { attrs: { appear: "", name: "d-modal__dialog" } }, [a("div", { directives: [{ name: "show", rawName: "v-show", value: t.show, expression: "show" }], class: [
    "d-modal__dialog",
    { "d-modal__dialog--scrollable": t.fixedHeaderFooter },
    t.dialogClass
  ], attrs: { role: "dialog", "aria-modal": "true", "aria-describedby": t.describedById, "aria-labelledby": t.labelledById } }, [t.$slots.header ? a("div", { staticClass: "d-modal__header", attrs: { id: t.labelledById, "data-qa": "dt-modal-title" } }, [t._t("header")], 2) : a("h2", { staticClass: "d-modal__header", attrs: { id: t.labelledById, "data-qa": "dt-modal-title" } }, [t._v(" " + t._s(t.title) + " ")]), t.$slots.default ? a("div", { class: [
    "d-modal__content",
    t.contentClass
  ], attrs: { "data-qa": "dt-modal-copy" } }, [t._t("default")], 2) : a("p", { class: [
    "d-modal__content",
    t.contentClass
  ], attrs: { "data-qa": "dt-modal-copy" } }, [t._v(" " + t._s(t.copy) + " ")]), t.hasFooterSlot ? a("footer", { staticClass: "d-modal__footer" }, [t._t("footer")], 2) : t._e(), t.hideClose ? a("sr-only-close-button", { on: { close: t.close } }) : a("dt-button", { staticClass: "d-modal__close", attrs: { "data-qa": "dt-modal-close-button", size: "md", kind: "muted", importance: "clear", "aria-label": t.closeButtonTitle, title: t.closeButtonTitle }, on: { click: t.close }, scopedSlots: t._u([{ key: "icon", fn: function({ iconSize: o }) {
    return [a("dt-icon-close", { attrs: { size: o } })];
  } }]) })], 1)])], 1)], 1);
}, C = [], $ = /* @__PURE__ */ y(
  S,
  w,
  C
);
const N = $.exports;
export {
  N as default
};
//# sourceMappingURL=modal.js.map
