@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
300 lines (299 loc) • 7.86 kB
JavaScript
import { EVENT_KEYNAMES as e } from "../../common/constants/index.js";
import { disableRootScrolling as t, enableRootScrolling as n, getUniqueString as r, hasSlotContent as i, returnFirstEl as a } from "../../common/utils/index.js";
import { t as o } from "../../_plugin-vue_export-helper-BTgDAbhb.js";
import s from "../../common/mixins/modal.js";
import { NOTICE_KINDS as c } from "../notice/notice-constants.js";
import { DialtoneLocalization as l } from "../../localization/index.js";
import u from "../button/button.js";
import d from "../../shared/sr_only_close_button.js";
import f from "../lazy-show/lazy-show.js";
import { MODAL_BANNER_KINDS as p, MODAL_KIND_MODIFIERS as m, MODAL_SIZE_MODIFIERS as h } from "./modal-constants.js";
import { Teleport as g, Transition as _, createBlock as v, createCommentVNode as y, createElementBlock as b, createElementVNode as x, createTextVNode as S, createVNode as C, mergeProps as w, normalizeClass as T, openBlock as E, renderSlot as D, resolveComponent as O, toDisplayString as k, toHandlers as A, vShow as j, withCtx as M, withDirectives as N } from "vue";
import { DtIconClose as P } from "@dialpad/dialtone-icons/vue3";
//#region components/modal/modal.vue
var F = {
compatConfig: { MODE: 3 },
name: "DtModal",
components: {
DtLazyShow: f,
DtButton: u,
DtIconClose: P,
SrOnlyCloseButton: d
},
mixins: [s],
props: {
copy: {
type: String,
default: ""
},
describedById: {
type: String,
default: ""
},
labelledById: {
type: String,
default: function() {
return r();
}
},
show: {
type: Boolean,
default: !1
},
title: {
type: String,
default: ""
},
bannerTitle: {
type: String,
default: ""
},
kind: {
type: String,
default: "default",
validator: (e) => Object.keys(m).includes(e)
},
size: {
type: String,
default: "default",
validator: (e) => Object.keys(h).includes(e)
},
modalClass: {
type: [
String,
Object,
Array
],
default: ""
},
dialogClass: {
type: [
String,
Object,
Array
],
default: ""
},
contentClass: {
type: [
String,
Object,
Array
],
default: ""
},
bannerKind: {
type: String,
default: "warning",
validate(e) {
return c.includes(e);
}
},
bannerClass: {
type: [
String,
Object,
Array
],
default: ""
},
hideClose: {
type: Boolean,
default: !1
},
closeOnClick: {
type: Boolean,
default: !0
},
fixedHeaderFooter: {
type: Boolean,
default: !0
},
initialFocusElement: {
type: [String, HTMLElement],
default: "first",
validator: (e) => e === "first" || e instanceof HTMLElement || e.startsWith("#")
},
appendTo: {
type: String,
default: void 0
}
},
emits: [
"click",
"keydown",
"update:show"
],
data() {
return {
MODAL_KIND_MODIFIERS: m,
MODAL_SIZE_MODIFIERS: h,
MODAL_BANNER_KINDS: p,
EVENT_KEYNAMES: e,
hasSlotContent: i,
i18n: new l()
};
},
computed: {
modalListeners() {
return {
click: (e) => {
this.closeOnClick && e.target === e.currentTarget ? this.close() : this.show && e.target !== e.currentTarget && this.handleModalClick(e), this.$emit("click", e);
},
keydown: (t) => {
switch (t.code) {
case e.esc:
case e.escape:
this.close();
break;
case e.tab:
this.trapFocus(t);
break;
}
this.$emit("keydown", t);
},
"after-enter": async () => {
this.$emit("update:show", !0), await this.setFocusAfterTransition();
},
focusin: (e) => {
let t = this.$refs.modalRoot?.$el || this.$el;
this.show && t && !t.contains(e.target) && (e.preventDefault(), this.focusFirstElement(t));
}
};
},
open() {
return `${!this.show}`;
},
hasFooterSlot() {
return !!this.$slots.footer;
},
bannerKindClass() {
return p[this.bannerKind];
},
closeButtonTitle() {
return this.i18n.$t("DIALTONE_CLOSE_BUTTON");
}
},
watch: { show: { handler(e) {
e ? (this.previousActiveElement = document.activeElement, t(a(this.$refs.modalRoot?.$el || this.$el).getRootNode().host)) : (n(a(this.$refs.modalRoot?.$el || this.$el).getRootNode().host), this.previousActiveElement?.focus(), this.previousActiveElement = null);
} } },
methods: {
close() {
this.$emit("update:show", !1);
},
async setFocusAfterTransition() {
let e = this.$refs.modalRoot?.$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) {
if (this.show) {
let t = this.$refs.modalRoot?.$el || this.$el;
this.focusTrappedTabPress(e, t);
}
},
handleModalClick(e) {
let t = e.target, n = this.$refs.modalRoot?.$el || this.$el, r = this._getFocusableElements(n);
r.length && !r.includes(t) && (r.includes(document.activeElement) || this.focusFirstElement(n));
}
}
}, I = ["aria-describedby", "aria-labelledby"], L = ["id"], R = ["id"], z = {
key: 4,
class: "d-modal__footer"
};
function B(e, t, n, r, i, a) {
let o = O("sr-only-close-button"), s = O("dt-icon-close"), c = O("dt-button"), l = O("dt-lazy-show");
return E(), v(g, {
disabled: !n.appendTo,
to: n.appendTo
}, [C(l, w({
ref: "modalRoot",
transition: "d-zoom",
show: n.show,
class: [
"d-modal",
i.MODAL_KIND_MODIFIERS[n.kind],
i.MODAL_SIZE_MODIFIERS[n.size],
n.modalClass
],
"data-qa": "dt-modal",
"aria-hidden": a.open
}, A(a.modalListeners)), {
default: M(() => [n.show && (i.hasSlotContent(e.$slots.banner) || n.bannerTitle) ? (E(), b("div", {
key: 0,
"data-qa": "dt-modal-banner",
class: T([
"d-modal__banner",
n.bannerClass,
a.bannerKindClass
])
}, [D(e.$slots, "banner", {}, () => [S(k(n.bannerTitle), 1)])], 2)) : y("", !0), C(_, {
appear: "",
name: "d-modal__dialog"
}, {
default: M(() => [N(x("div", {
class: T([
"d-modal__dialog",
{ "d-modal__dialog--scrollable": n.fixedHeaderFooter },
n.dialogClass
]),
role: "dialog",
"aria-modal": "true",
"aria-describedby": n.describedById,
"aria-labelledby": n.labelledById
}, [
i.hasSlotContent(e.$slots.header) ? (E(), b("div", {
key: 0,
id: n.labelledById,
class: "d-modal__header",
"data-qa": "dt-modal-title"
}, [D(e.$slots, "header")], 8, L)) : (E(), b("h2", {
key: 1,
id: n.labelledById,
class: "d-modal__header",
"data-qa": "dt-modal-title"
}, k(n.title), 9, R)),
i.hasSlotContent(e.$slots.default) ? (E(), b("div", {
key: 2,
class: T(["d-modal__content", n.contentClass]),
"data-qa": "dt-modal-copy"
}, [D(e.$slots, "default")], 2)) : (E(), b("p", {
key: 3,
class: T(["d-modal__content", n.contentClass]),
"data-qa": "dt-modal-copy"
}, k(n.copy), 3)),
a.hasFooterSlot ? (E(), b("footer", z, [D(e.$slots, "footer")])) : y("", !0),
n.hideClose ? (E(), v(o, {
key: 5,
onClose: a.close
}, null, 8, ["onClose"])) : (E(), v(c, {
key: 6,
class: "d-modal__close",
"data-qa": "dt-modal-close-button",
size: "md",
kind: "muted",
importance: "clear",
"aria-label": a.closeButtonTitle,
title: a.closeButtonTitle,
onClick: a.close
}, {
icon: M(({ iconSize: e }) => [C(s, { size: e }, null, 8, ["size"])]),
_: 1
}, 8, [
"aria-label",
"title",
"onClick"
]))
], 10, I), [[j, n.show]])]),
_: 3
})]),
_: 3
}, 16, [
"show",
"class",
"aria-hidden"
])], 8, ["disabled", "to"]);
}
var V = /* @__PURE__ */ o(F, [["render", B]]);
//#endregion
export { V as default };
//# sourceMappingURL=modal.js.map