@dialpad/dialtone 9.126.4 → 9.126.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tokens/doc.json +26079 -26079
- package/dist/vue2/lib/emoji-row/emoji-row-constants.cjs +1 -1
- package/dist/vue2/lib/emoji-row/emoji-row-constants.cjs.map +1 -1
- package/dist/vue2/lib/emoji-row/emoji-row-constants.js +1 -0
- package/dist/vue2/lib/emoji-row/emoji-row-constants.js.map +1 -1
- package/dist/vue2/lib/emoji-row/emoji-row.cjs +1 -1
- package/dist/vue2/lib/emoji-row/emoji-row.cjs.map +1 -1
- package/dist/vue2/lib/emoji-row/emoji-row.js +28 -30
- package/dist/vue2/lib/emoji-row/emoji-row.js.map +1 -1
- package/dist/vue2/lib/modal/modal.cjs +1 -1
- package/dist/vue2/lib/modal/modal.cjs.map +1 -1
- package/dist/vue2/lib/modal/modal.js +13 -9
- package/dist/vue2/lib/modal/modal.js.map +1 -1
- package/dist/vue2/lib/rich-text-editor/rich-text-editor.cjs +3 -3
- package/dist/vue2/lib/rich-text-editor/rich-text-editor.cjs.map +1 -1
- package/dist/vue2/lib/rich-text-editor/rich-text-editor.js +34 -38
- package/dist/vue2/lib/rich-text-editor/rich-text-editor.js.map +1 -1
- package/dist/vue2/localization/en-US.cjs +1 -11
- package/dist/vue2/localization/en-US.cjs.map +1 -1
- package/dist/vue2/localization/en-US.js +1 -11
- package/dist/vue2/localization/en-US.js.map +1 -1
- package/dist/vue2/types/components/modal/modal.vue.d.ts +3 -2
- package/dist/vue2/types/components/rich_text_editor/rich_text_editor.vue.d.ts.map +1 -1
- package/dist/vue2/types/recipes/conversation_view/emoji_row/emoji_row_constants.d.ts.map +1 -1
- package/dist/vue3/lib/modal/modal.cjs +2 -2
- package/dist/vue3/lib/modal/modal.cjs.map +1 -1
- package/dist/vue3/lib/modal/modal.js +55 -48
- package/dist/vue3/lib/modal/modal.js.map +1 -1
- package/dist/vue3/lib/rich-text-editor/rich-text-editor.cjs +2 -2
- package/dist/vue3/lib/rich-text-editor/rich-text-editor.cjs.map +1 -1
- package/dist/vue3/lib/rich-text-editor/rich-text-editor.js +18 -22
- package/dist/vue3/lib/rich-text-editor/rich-text-editor.js.map +1 -1
- package/dist/vue3/types/components/modal/modal.vue.d.ts +4 -2
- package/dist/vue3/types/components/modal/modal.vue.d.ts.map +1 -1
- package/dist/vue3/types/components/rich_text_editor/rich_text_editor.vue.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=["emojiUnicodeOrShortname","isSelected","num"],t={REACTIONS_ATTRIBUTES:e};exports.REACTIONS_ATTRIBUTES=e;exports.default=t;
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=["emojiUnicodeOrShortname","isSelected","names","num"],t={REACTIONS_ATTRIBUTES:e};exports.REACTIONS_ATTRIBUTES=e;exports.default=t;
|
|
2
2
|
//# sourceMappingURL=emoji-row-constants.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emoji-row-constants.cjs","sources":["../../../recipes/conversation_view/emoji_row/emoji_row_constants.js"],"sourcesContent":["export const REACTIONS_ATTRIBUTES = [\n 'emojiUnicodeOrShortname',\n 'isSelected',\n 'num',\n];\n\nexport default {\n REACTIONS_ATTRIBUTES,\n};\n"],"names":["REACTIONS_ATTRIBUTES","emoji_row_constants"],"mappings":"4GAAY,MAACA,EAAuB,CAClC,0BACA,aACA,KACF,EAEeC,EAAA,CACb,qBAAAD,CACF"}
|
|
1
|
+
{"version":3,"file":"emoji-row-constants.cjs","sources":["../../../recipes/conversation_view/emoji_row/emoji_row_constants.js"],"sourcesContent":["export const REACTIONS_ATTRIBUTES = [\n 'emojiUnicodeOrShortname',\n 'isSelected',\n 'names',\n 'num',\n];\n\nexport default {\n REACTIONS_ATTRIBUTES,\n};\n"],"names":["REACTIONS_ATTRIBUTES","emoji_row_constants"],"mappings":"4GAAY,MAACA,EAAuB,CAClC,0BACA,aACA,QACA,KACF,EAEeC,EAAA,CACb,qBAAAD,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emoji-row-constants.js","sources":["../../../recipes/conversation_view/emoji_row/emoji_row_constants.js"],"sourcesContent":["export const REACTIONS_ATTRIBUTES = [\n 'emojiUnicodeOrShortname',\n 'isSelected',\n 'num',\n];\n\nexport default {\n REACTIONS_ATTRIBUTES,\n};\n"],"names":["REACTIONS_ATTRIBUTES","emoji_row_constants"],"mappings":"AAAY,MAACA,IAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,GAEeC,IAAA;AAAA,EACb,sBAAAD;AACF;"}
|
|
1
|
+
{"version":3,"file":"emoji-row-constants.js","sources":["../../../recipes/conversation_view/emoji_row/emoji_row_constants.js"],"sourcesContent":["export const REACTIONS_ATTRIBUTES = [\n 'emojiUnicodeOrShortname',\n 'isSelected',\n 'names',\n 'num',\n];\n\nexport default {\n REACTIONS_ATTRIBUTES,\n};\n"],"names":["REACTIONS_ATTRIBUTES","emoji_row_constants"],"mappings":"AAAY,MAACA,IAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEeC,IAAA;AAAA,EACb,sBAAAD;AACF;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const n=require("./emoji-row-constants.cjs"),s=require("../../_plugin-vue2_normalizer-e_CkxkSV.cjs"),a=require("../tooltip/tooltip.cjs"),c=require("../button/button.cjs"),m=require("../emoji/emoji.cjs"),l=require("../emoji-text-wrapper/emoji-text-wrapper.cjs"),_=require("../../common/mixins/localization.cjs"),d={name:"DtRecipeEmojiRow",components:{DtTooltip:a.default,DtButton:c.default,DtEmoji:m.default,DtEmojiTextWrapper:l.default},mixins:[_.default],props:{reactions:{type:Array,default:()=>[],validator:
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const n=require("./emoji-row-constants.cjs"),s=require("../../_plugin-vue2_normalizer-e_CkxkSV.cjs"),a=require("../tooltip/tooltip.cjs"),c=require("../button/button.cjs"),m=require("../emoji/emoji.cjs"),l=require("../emoji-text-wrapper/emoji-text-wrapper.cjs"),_=require("../../common/mixins/localization.cjs"),d={name:"DtRecipeEmojiRow",components:{DtTooltip:a.default,DtButton:c.default,DtEmoji:m.default,DtEmojiTextWrapper:l.default},mixins:[_.default],props:{reactions:{type:Array,default:()=>[],validator:i=>{for(const e of i)if(!n.REACTIONS_ATTRIBUTES.every(o=>e[o]!==void 0))return!1;return!0}}},emits:["emoji-clicked","emoji-hovered"],methods:{emojiClicked(i){this.$emit("emoji-clicked",i.emojiUnicodeOrShortname)},emojiHovered(i,e){this.$emit("emoji-hovered",{reaction:i.emojiUnicodeOrShortname,state:e})},reactionLabel(i){return this.i18n.$t("DIALTONE_EMOJI_ROW_REACTION_LABEL",{names:i.names,reaction:i.emojiUnicodeOrShortname})}}};var u=function(){var e=this,t=e._self._c;return t("span",{staticClass:"d-recipe-emoji-row"},[e._l(e.reactions,function(o){return t("span",{key:o.unicodeOutput},[t("dt-tooltip",{staticClass:"d-recipe-emoji-row__tooltip",attrs:{"content-class":"d-recipe-emoji-row__tooltip-content",sticky:"popper"},on:{shown:r=>e.emojiHovered(o,r)},scopedSlots:e._u([{key:"anchor",fn:function({attrs:r}){return[t("dt-button",{class:["d-recipe-emoji-row__reaction",o.isSelected?"d-recipe-emoji-row__reaction--selected":""],attrs:{importance:"clear",size:"sm","data-qa":"feed-item-reaction-button","aria-label":e.reactionLabel(o),attrs:r},on:{click:function(v){return e.emojiClicked(o)}}},[t("span",{staticClass:"d-recipe-emoji-row__emoji"},[t("dt-emoji",{attrs:{size:"200",code:o.emojiUnicodeOrShortname}})],1),t("span",{staticClass:"d-recipe-emoji-row__reaction-number"},[e._v(" "+e._s(o.num)+" ")])])]}}],null,!0)},[t("span",{attrs:{"aria-hidden":"true"}},[t("dt-emoji-text-wrapper",{attrs:{size:"200"}},[e._v(" "+e._s(e.reactionLabel(o))+" ")])],1)])],1)}),e._t("picker")],2)},p=[],j=s.n(d,u,p);const f=j.exports;exports.default=f;
|
|
2
2
|
//# sourceMappingURL=emoji-row.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emoji-row.cjs","sources":["../../../recipes/conversation_view/emoji_row/emoji_row.vue"],"sourcesContent":["<template>\n <span class=\"d-recipe-emoji-row\">\n <span\n v-for=\"reaction in reactions\"\n :key=\"reaction.unicodeOutput\"\n >\n <dt-tooltip\n class=\"d-recipe-emoji-row__tooltip\"\n content-class=\"d-recipe-emoji-row__tooltip-content\"\n sticky=\"popper\"\n @shown=\"(shown) => emojiHovered(reaction, shown)\"\n >\n <span aria-hidden=\"true\">\n <dt-emoji-text-wrapper size=\"200\">\n {{ reactionLabel(reaction) }}\n </dt-emoji-text-wrapper>\n </span>\n <template #anchor=\"{ attrs }\">\n <dt-button\n importance=\"clear\"\n size=\"sm\"\n data-qa=\"feed-item-reaction-button\"\n :class=\"[\n 'd-recipe-emoji-row__reaction',\n reaction.isSelected ? 'd-recipe-emoji-row__reaction--selected' : '',\n ]\"\n :aria-label=\"reactionLabel(reaction)\"\n :attrs=\"attrs\"\n @click=\"emojiClicked(reaction)\"\n >\n <span class=\"d-recipe-emoji-row__emoji\">\n <dt-emoji\n size=\"200\"\n :code=\"reaction.emojiUnicodeOrShortname\"\n />\n </span>\n <span class=\"d-recipe-emoji-row__reaction-number\">\n {{ reaction.num }}\n </span>\n </dt-button>\n </template>\n </dt-tooltip>\n </span>\n <!-- TODO: Replace picker slot with a button with localized text and emit any event needed -->\n <!-- @slot Slot for emoji picker component, including the anchor. -->\n <slot name=\"picker\" />\n </span>\n</template>\n\n<script>\nimport { REACTIONS_ATTRIBUTES } from './emoji_row_constants.js';\nimport { DtButton } from '@/components/button';\nimport { DtTooltip } from '@/components/tooltip';\nimport { DtEmoji } from '@/components/emoji';\nimport { DtEmojiTextWrapper } from '@/components/emoji_text_wrapper';\nimport { DtLocalizationMixin } from '@/common/mixins';\n\nexport default {\n name: 'DtRecipeEmojiRow',\n\n components: { DtTooltip, DtButton, DtEmoji, DtEmojiTextWrapper },\n\n mixins: [DtLocalizationMixin],\n\n props: {\n /**\n * Provide an array of reaction objects to be shown.\n */\n reactions: {\n type: Array,\n default: () => [],\n validator: (reactions) => {\n for (const reaction of reactions) {\n const validInput = REACTIONS_ATTRIBUTES.every((attribute) => reaction[attribute] !== undefined ?? false);\n if (!validInput) return false;\n }\n return true;\n },\n },\n },\n\n emits: [\n 'emoji-clicked',\n 'emoji-hovered',\n ],\n\n methods: {\n emojiClicked (reaction) {\n this.$emit('emoji-clicked', reaction.emojiUnicodeOrShortname);\n },\n\n emojiHovered (reaction, state) {\n this.$emit('emoji-hovered', {\n reaction: reaction.emojiUnicodeOrShortname,\n state,\n });\n },\n\n reactionLabel (reaction) {\n return this.i18n.$t('DIALTONE_EMOJI_ROW_REACTION_LABEL', {\n
|
|
1
|
+
{"version":3,"file":"emoji-row.cjs","sources":["../../../recipes/conversation_view/emoji_row/emoji_row.vue"],"sourcesContent":["<template>\n <span class=\"d-recipe-emoji-row\">\n <span\n v-for=\"reaction in reactions\"\n :key=\"reaction.unicodeOutput\"\n >\n <dt-tooltip\n class=\"d-recipe-emoji-row__tooltip\"\n content-class=\"d-recipe-emoji-row__tooltip-content\"\n sticky=\"popper\"\n @shown=\"(shown) => emojiHovered(reaction, shown)\"\n >\n <span aria-hidden=\"true\">\n <dt-emoji-text-wrapper size=\"200\">\n {{ reactionLabel(reaction) }}\n </dt-emoji-text-wrapper>\n </span>\n <template #anchor=\"{ attrs }\">\n <dt-button\n importance=\"clear\"\n size=\"sm\"\n data-qa=\"feed-item-reaction-button\"\n :class=\"[\n 'd-recipe-emoji-row__reaction',\n reaction.isSelected ? 'd-recipe-emoji-row__reaction--selected' : '',\n ]\"\n :aria-label=\"reactionLabel(reaction)\"\n :attrs=\"attrs\"\n @click=\"emojiClicked(reaction)\"\n >\n <span class=\"d-recipe-emoji-row__emoji\">\n <dt-emoji\n size=\"200\"\n :code=\"reaction.emojiUnicodeOrShortname\"\n />\n </span>\n <span class=\"d-recipe-emoji-row__reaction-number\">\n {{ reaction.num }}\n </span>\n </dt-button>\n </template>\n </dt-tooltip>\n </span>\n <!-- TODO: Replace picker slot with a button with localized text and emit any event needed -->\n <!-- @slot Slot for emoji picker component, including the anchor. -->\n <slot name=\"picker\" />\n </span>\n</template>\n\n<script>\nimport { REACTIONS_ATTRIBUTES } from './emoji_row_constants.js';\nimport { DtButton } from '@/components/button';\nimport { DtTooltip } from '@/components/tooltip';\nimport { DtEmoji } from '@/components/emoji';\nimport { DtEmojiTextWrapper } from '@/components/emoji_text_wrapper';\nimport { DtLocalizationMixin } from '@/common/mixins';\n\nexport default {\n name: 'DtRecipeEmojiRow',\n\n components: { DtTooltip, DtButton, DtEmoji, DtEmojiTextWrapper },\n\n mixins: [DtLocalizationMixin],\n\n props: {\n /**\n * Provide an array of reaction objects to be shown.\n */\n reactions: {\n type: Array,\n default: () => [],\n validator: (reactions) => {\n for (const reaction of reactions) {\n const validInput = REACTIONS_ATTRIBUTES.every((attribute) => reaction[attribute] !== undefined ?? false);\n if (!validInput) return false;\n }\n return true;\n },\n },\n },\n\n emits: [\n 'emoji-clicked',\n 'emoji-hovered',\n ],\n\n methods: {\n emojiClicked (reaction) {\n this.$emit('emoji-clicked', reaction.emojiUnicodeOrShortname);\n },\n\n emojiHovered (reaction, state) {\n this.$emit('emoji-hovered', {\n reaction: reaction.emojiUnicodeOrShortname,\n state,\n });\n },\n\n reactionLabel (reaction) {\n return this.i18n.$t('DIALTONE_EMOJI_ROW_REACTION_LABEL', {\n names: reaction.names,\n reaction: reaction.emojiUnicodeOrShortname,\n });\n },\n },\n};\n</script>\n"],"names":["_sfc_main","DtTooltip","DtButton","DtEmoji","DtEmojiTextWrapper","DtLocalizationMixin","reactions","reaction","REACTIONS_ATTRIBUTES","attribute","state"],"mappings":"maAyDAA,EAAA,CACA,KAAA,mBAEA,WAAA,CAAA,UAAAC,EAAA,QAAA,SAAAC,UAAAC,QAAAA,EAAAA,QAAAC,mBAAAA,EAAAA,OAAA,EAEA,OAAA,CAAAC,EAAAA,OAAA,EAEA,MAAA,CAIA,UAAA,CACA,KAAA,MACA,QAAA,IAAA,CAAA,EACA,UAAAC,GAAA,CACA,UAAAC,KAAAD,EAEA,GAAA,CADAE,uBAAA,MAAAC,GAAAF,EAAAE,CAAA,IAAA,MAAA,EACA,MAAA,GAEA,MAAA,EACA,CACA,CACA,EAEA,MAAA,CACA,gBACA,eACA,EAEA,QAAA,CACA,aAAAF,EAAA,CACA,KAAA,MAAA,gBAAAA,EAAA,uBAAA,CACA,EAEA,aAAAA,EAAAG,EAAA,CACA,KAAA,MAAA,gBAAA,CACA,SAAAH,EAAA,wBACA,MAAAG,CACA,CAAA,CACA,EAEA,cAAAH,EAAA,CACA,OAAA,KAAA,KAAA,GAAA,oCAAA,CACA,MAAAA,EAAA,MACA,SAAAA,EAAA,uBACA,CAAA,CACA,CACA,CACA"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { REACTIONS_ATTRIBUTES as n } from "./emoji-row-constants.js";
|
|
2
|
-
import { n as
|
|
3
|
-
import
|
|
2
|
+
import { n as a } from "../../_plugin-vue2_normalizer-DSLOjnn3.js";
|
|
3
|
+
import s from "../tooltip/tooltip.js";
|
|
4
4
|
import m from "../button/button.js";
|
|
5
5
|
import c from "../emoji/emoji.js";
|
|
6
6
|
import p from "../emoji-text-wrapper/emoji-text-wrapper.js";
|
|
7
7
|
import d from "../../common/mixins/localization.js";
|
|
8
|
-
const
|
|
8
|
+
const _ = {
|
|
9
9
|
name: "DtRecipeEmojiRow",
|
|
10
|
-
components: { DtTooltip:
|
|
10
|
+
components: { DtTooltip: s, DtButton: m, DtEmoji: c, DtEmojiTextWrapper: p },
|
|
11
11
|
mixins: [d],
|
|
12
12
|
props: {
|
|
13
13
|
/**
|
|
@@ -16,9 +16,9 @@ const l = {
|
|
|
16
16
|
reactions: {
|
|
17
17
|
type: Array,
|
|
18
18
|
default: () => [],
|
|
19
|
-
validator: (
|
|
20
|
-
for (const e of
|
|
21
|
-
if (!n.every((
|
|
19
|
+
validator: (i) => {
|
|
20
|
+
for (const e of i)
|
|
21
|
+
if (!n.every((o) => e[o] !== void 0)) return !1;
|
|
22
22
|
return !0;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -28,44 +28,42 @@ const l = {
|
|
|
28
28
|
"emoji-hovered"
|
|
29
29
|
],
|
|
30
30
|
methods: {
|
|
31
|
-
emojiClicked(
|
|
32
|
-
this.$emit("emoji-clicked",
|
|
31
|
+
emojiClicked(i) {
|
|
32
|
+
this.$emit("emoji-clicked", i.emojiUnicodeOrShortname);
|
|
33
33
|
},
|
|
34
|
-
emojiHovered(
|
|
34
|
+
emojiHovered(i, e) {
|
|
35
35
|
this.$emit("emoji-hovered", {
|
|
36
|
-
reaction:
|
|
36
|
+
reaction: i.emojiUnicodeOrShortname,
|
|
37
37
|
state: e
|
|
38
38
|
});
|
|
39
39
|
},
|
|
40
|
-
reactionLabel(
|
|
40
|
+
reactionLabel(i) {
|
|
41
41
|
return this.i18n.$t("DIALTONE_EMOJI_ROW_REACTION_LABEL", {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
selected: t.isSelected.toString(),
|
|
45
|
-
reaction: t.emojiUnicodeOrShortname
|
|
42
|
+
names: i.names,
|
|
43
|
+
reaction: i.emojiUnicodeOrShortname
|
|
46
44
|
});
|
|
47
45
|
}
|
|
48
46
|
}
|
|
49
47
|
};
|
|
50
|
-
var
|
|
51
|
-
var e = this,
|
|
52
|
-
return
|
|
53
|
-
return
|
|
54
|
-
return [
|
|
48
|
+
var l = function() {
|
|
49
|
+
var e = this, t = e._self._c;
|
|
50
|
+
return t("span", { staticClass: "d-recipe-emoji-row" }, [e._l(e.reactions, function(o) {
|
|
51
|
+
return t("span", { key: o.unicodeOutput }, [t("dt-tooltip", { staticClass: "d-recipe-emoji-row__tooltip", attrs: { "content-class": "d-recipe-emoji-row__tooltip-content", sticky: "popper" }, on: { shown: (r) => e.emojiHovered(o, r) }, scopedSlots: e._u([{ key: "anchor", fn: function({ attrs: r }) {
|
|
52
|
+
return [t("dt-button", { class: [
|
|
55
53
|
"d-recipe-emoji-row__reaction",
|
|
56
|
-
|
|
57
|
-
], attrs: { importance: "clear", size: "sm", "data-qa": "feed-item-reaction-button", "aria-label": e.reactionLabel(
|
|
58
|
-
return e.emojiClicked(
|
|
59
|
-
} } }, [
|
|
60
|
-
} }], null, !0) }, [
|
|
54
|
+
o.isSelected ? "d-recipe-emoji-row__reaction--selected" : ""
|
|
55
|
+
], attrs: { importance: "clear", size: "sm", "data-qa": "feed-item-reaction-button", "aria-label": e.reactionLabel(o), attrs: r }, on: { click: function(f) {
|
|
56
|
+
return e.emojiClicked(o);
|
|
57
|
+
} } }, [t("span", { staticClass: "d-recipe-emoji-row__emoji" }, [t("dt-emoji", { attrs: { size: "200", code: o.emojiUnicodeOrShortname } })], 1), t("span", { staticClass: "d-recipe-emoji-row__reaction-number" }, [e._v(" " + e._s(o.num) + " ")])])];
|
|
58
|
+
} }], null, !0) }, [t("span", { attrs: { "aria-hidden": "true" } }, [t("dt-emoji-text-wrapper", { attrs: { size: "200" } }, [e._v(" " + e._s(e.reactionLabel(o)) + " ")])], 1)])], 1);
|
|
61
59
|
}), e._t("picker")], 2);
|
|
62
|
-
}, u = [], j = /* @__PURE__ */
|
|
63
|
-
l,
|
|
60
|
+
}, u = [], j = /* @__PURE__ */ a(
|
|
64
61
|
_,
|
|
62
|
+
l,
|
|
65
63
|
u
|
|
66
64
|
);
|
|
67
|
-
const
|
|
65
|
+
const S = j.exports;
|
|
68
66
|
export {
|
|
69
|
-
|
|
67
|
+
S as default
|
|
70
68
|
};
|
|
71
69
|
//# sourceMappingURL=emoji-row.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emoji-row.js","sources":["../../../recipes/conversation_view/emoji_row/emoji_row.vue"],"sourcesContent":["<template>\n <span class=\"d-recipe-emoji-row\">\n <span\n v-for=\"reaction in reactions\"\n :key=\"reaction.unicodeOutput\"\n >\n <dt-tooltip\n class=\"d-recipe-emoji-row__tooltip\"\n content-class=\"d-recipe-emoji-row__tooltip-content\"\n sticky=\"popper\"\n @shown=\"(shown) => emojiHovered(reaction, shown)\"\n >\n <span aria-hidden=\"true\">\n <dt-emoji-text-wrapper size=\"200\">\n {{ reactionLabel(reaction) }}\n </dt-emoji-text-wrapper>\n </span>\n <template #anchor=\"{ attrs }\">\n <dt-button\n importance=\"clear\"\n size=\"sm\"\n data-qa=\"feed-item-reaction-button\"\n :class=\"[\n 'd-recipe-emoji-row__reaction',\n reaction.isSelected ? 'd-recipe-emoji-row__reaction--selected' : '',\n ]\"\n :aria-label=\"reactionLabel(reaction)\"\n :attrs=\"attrs\"\n @click=\"emojiClicked(reaction)\"\n >\n <span class=\"d-recipe-emoji-row__emoji\">\n <dt-emoji\n size=\"200\"\n :code=\"reaction.emojiUnicodeOrShortname\"\n />\n </span>\n <span class=\"d-recipe-emoji-row__reaction-number\">\n {{ reaction.num }}\n </span>\n </dt-button>\n </template>\n </dt-tooltip>\n </span>\n <!-- TODO: Replace picker slot with a button with localized text and emit any event needed -->\n <!-- @slot Slot for emoji picker component, including the anchor. -->\n <slot name=\"picker\" />\n </span>\n</template>\n\n<script>\nimport { REACTIONS_ATTRIBUTES } from './emoji_row_constants.js';\nimport { DtButton } from '@/components/button';\nimport { DtTooltip } from '@/components/tooltip';\nimport { DtEmoji } from '@/components/emoji';\nimport { DtEmojiTextWrapper } from '@/components/emoji_text_wrapper';\nimport { DtLocalizationMixin } from '@/common/mixins';\n\nexport default {\n name: 'DtRecipeEmojiRow',\n\n components: { DtTooltip, DtButton, DtEmoji, DtEmojiTextWrapper },\n\n mixins: [DtLocalizationMixin],\n\n props: {\n /**\n * Provide an array of reaction objects to be shown.\n */\n reactions: {\n type: Array,\n default: () => [],\n validator: (reactions) => {\n for (const reaction of reactions) {\n const validInput = REACTIONS_ATTRIBUTES.every((attribute) => reaction[attribute] !== undefined ?? false);\n if (!validInput) return false;\n }\n return true;\n },\n },\n },\n\n emits: [\n 'emoji-clicked',\n 'emoji-hovered',\n ],\n\n methods: {\n emojiClicked (reaction) {\n this.$emit('emoji-clicked', reaction.emojiUnicodeOrShortname);\n },\n\n emojiHovered (reaction, state) {\n this.$emit('emoji-hovered', {\n reaction: reaction.emojiUnicodeOrShortname,\n state,\n });\n },\n\n reactionLabel (reaction) {\n return this.i18n.$t('DIALTONE_EMOJI_ROW_REACTION_LABEL', {\n
|
|
1
|
+
{"version":3,"file":"emoji-row.js","sources":["../../../recipes/conversation_view/emoji_row/emoji_row.vue"],"sourcesContent":["<template>\n <span class=\"d-recipe-emoji-row\">\n <span\n v-for=\"reaction in reactions\"\n :key=\"reaction.unicodeOutput\"\n >\n <dt-tooltip\n class=\"d-recipe-emoji-row__tooltip\"\n content-class=\"d-recipe-emoji-row__tooltip-content\"\n sticky=\"popper\"\n @shown=\"(shown) => emojiHovered(reaction, shown)\"\n >\n <span aria-hidden=\"true\">\n <dt-emoji-text-wrapper size=\"200\">\n {{ reactionLabel(reaction) }}\n </dt-emoji-text-wrapper>\n </span>\n <template #anchor=\"{ attrs }\">\n <dt-button\n importance=\"clear\"\n size=\"sm\"\n data-qa=\"feed-item-reaction-button\"\n :class=\"[\n 'd-recipe-emoji-row__reaction',\n reaction.isSelected ? 'd-recipe-emoji-row__reaction--selected' : '',\n ]\"\n :aria-label=\"reactionLabel(reaction)\"\n :attrs=\"attrs\"\n @click=\"emojiClicked(reaction)\"\n >\n <span class=\"d-recipe-emoji-row__emoji\">\n <dt-emoji\n size=\"200\"\n :code=\"reaction.emojiUnicodeOrShortname\"\n />\n </span>\n <span class=\"d-recipe-emoji-row__reaction-number\">\n {{ reaction.num }}\n </span>\n </dt-button>\n </template>\n </dt-tooltip>\n </span>\n <!-- TODO: Replace picker slot with a button with localized text and emit any event needed -->\n <!-- @slot Slot for emoji picker component, including the anchor. -->\n <slot name=\"picker\" />\n </span>\n</template>\n\n<script>\nimport { REACTIONS_ATTRIBUTES } from './emoji_row_constants.js';\nimport { DtButton } from '@/components/button';\nimport { DtTooltip } from '@/components/tooltip';\nimport { DtEmoji } from '@/components/emoji';\nimport { DtEmojiTextWrapper } from '@/components/emoji_text_wrapper';\nimport { DtLocalizationMixin } from '@/common/mixins';\n\nexport default {\n name: 'DtRecipeEmojiRow',\n\n components: { DtTooltip, DtButton, DtEmoji, DtEmojiTextWrapper },\n\n mixins: [DtLocalizationMixin],\n\n props: {\n /**\n * Provide an array of reaction objects to be shown.\n */\n reactions: {\n type: Array,\n default: () => [],\n validator: (reactions) => {\n for (const reaction of reactions) {\n const validInput = REACTIONS_ATTRIBUTES.every((attribute) => reaction[attribute] !== undefined ?? false);\n if (!validInput) return false;\n }\n return true;\n },\n },\n },\n\n emits: [\n 'emoji-clicked',\n 'emoji-hovered',\n ],\n\n methods: {\n emojiClicked (reaction) {\n this.$emit('emoji-clicked', reaction.emojiUnicodeOrShortname);\n },\n\n emojiHovered (reaction, state) {\n this.$emit('emoji-hovered', {\n reaction: reaction.emojiUnicodeOrShortname,\n state,\n });\n },\n\n reactionLabel (reaction) {\n return this.i18n.$t('DIALTONE_EMOJI_ROW_REACTION_LABEL', {\n names: reaction.names,\n reaction: reaction.emojiUnicodeOrShortname,\n });\n },\n },\n};\n</script>\n"],"names":["_sfc_main","DtTooltip","DtButton","DtEmoji","DtEmojiTextWrapper","DtLocalizationMixin","reactions","reaction","REACTIONS_ATTRIBUTES","attribute","state"],"mappings":";;;;;;;AAyDA,MAAAA,IAAA;AAAA,EACA,MAAA;AAAA,EAEA,YAAA,EAAA,WAAAC,GAAA,UAAAC,GAAA,SAAAC,GAAA,oBAAAC,EAAA;AAAA,EAEA,QAAA,CAAAC,CAAA;AAAA,EAEA,OAAA;AAAA;AAAA;AAAA;AAAA,IAIA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA,MAAA,CAAA;AAAA,MACA,WAAA,CAAAC,MAAA;AACA,mBAAAC,KAAAD;AAEA,cAAA,CADAE,EAAA,MAAA,CAAAC,MAAAF,EAAAE,CAAA,MAAA,MAAA,EACA,QAAA;AAEA,eAAA;AAAA,MACA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,OAAA;AAAA,IACA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,SAAA;AAAA,IACA,aAAAF,GAAA;AACA,WAAA,MAAA,iBAAAA,EAAA,uBAAA;AAAA,IACA;AAAA,IAEA,aAAAA,GAAAG,GAAA;AACA,WAAA,MAAA,iBAAA;AAAA,QACA,UAAAH,EAAA;AAAA,QACA,OAAAG;AAAA,MACA,CAAA;AAAA,IACA;AAAA,IAEA,cAAAH,GAAA;AACA,aAAA,KAAA,KAAA,GAAA,qCAAA;AAAA,QACA,OAAAA,EAAA;AAAA,QACA,UAAAA,EAAA;AAAA,MACA,CAAA;AAAA,IACA;AAAA,EACA;AACA;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const i=require("@dialpad/dialtone-icons/vue2"),n=require("../../common/mixins/modal.cjs"),a=require("./modal-constants.cjs"),l=require("../../common/utils/index.cjs"),o=require("../../common/constants/index.cjs"),r=require("../../shared/sr_only_close_button.cjs"),d=require("../../_plugin-vue2_normalizer-e_CkxkSV.cjs"),c=require("../lazy-show/lazy-show.cjs"),u=require("../button/button.cjs"),_=require("../../common/mixins/localization.cjs"),m=require("../notice/notice-constants.cjs"),h={name:"DtModal",components:{DtLazyShow:c.default,DtButton:u.default,DtIconClose:i.DtIconClose,SrOnlyCloseButton:r.default},mixins:[n.default,_.default],props:{copy:{type:String,default:""},describedById:{type:String,default:""},labelledById:{type:String,default:function(){return l.getUniqueString()}},show:{type:Boolean,default:!1},title:{type:String,default:""},bannerTitle:{type:String,default:""},kind:{type:String,default:"default",validator:e=>Object.keys(a.MODAL_KIND_MODIFIERS).includes(e)},size:{type:String,default:"default",validator:e=>Object.keys(a.MODAL_SIZE_MODIFIERS).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 m.NOTICE_KINDS.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("#")}},emits:["update:show"],data(){return{MODAL_KIND_MODIFIERS:a.MODAL_KIND_MODIFIERS,MODAL_SIZE_MODIFIERS:a.MODAL_SIZE_MODIFIERS,MODAL_BANNER_KINDS:a.MODAL_BANNER_KINDS,EVENT_KEYNAMES:o.EVENT_KEYNAMES}},computed:{modalListeners(){return{...this.$listeners,click:e=>{this.closeOnClick&&
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const i=require("@dialpad/dialtone-icons/vue2"),n=require("../../common/mixins/modal.cjs"),a=require("./modal-constants.cjs"),l=require("../../common/utils/index.cjs"),o=require("../../common/constants/index.cjs"),r=require("../../shared/sr_only_close_button.cjs"),d=require("../../_plugin-vue2_normalizer-e_CkxkSV.cjs"),c=require("../lazy-show/lazy-show.cjs"),u=require("../button/button.cjs"),_=require("../../common/mixins/localization.cjs"),m=require("../notice/notice-constants.cjs"),h={name:"DtModal",components:{DtLazyShow:c.default,DtButton:u.default,DtIconClose:i.DtIconClose,SrOnlyCloseButton:r.default},mixins:[n.default,_.default],props:{copy:{type:String,default:""},describedById:{type:String,default:""},labelledById:{type:String,default:function(){return l.getUniqueString()}},show:{type:Boolean,default:!1},title:{type:String,default:""},bannerTitle:{type:String,default:""},kind:{type:String,default:"default",validator:e=>Object.keys(a.MODAL_KIND_MODIFIERS).includes(e)},size:{type:String,default:"default",validator:e=>Object.keys(a.MODAL_SIZE_MODIFIERS).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 m.NOTICE_KINDS.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("#")}},emits:["update:show"],data(){return{MODAL_KIND_MODIFIERS:a.MODAL_KIND_MODIFIERS,MODAL_SIZE_MODIFIERS:a.MODAL_SIZE_MODIFIERS,MODAL_BANNER_KINDS:a.MODAL_BANNER_KINDS,EVENT_KEYNAMES:o.EVENT_KEYNAMES}},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 o.EVENT_KEYNAMES.esc:case o.EVENT_KEYNAMES.escape:this.close();break;case o.EVENT_KEYNAMES.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 a.MODAL_BANNER_KINDS[this.bannerKind]},closeButtonTitle(){return this.i18n.$t("DIALTONE_CLOSE_BUTTON")}},watch:{show:{handler(e){var t;e?(this.previousActiveElement=document.activeElement,l.disableRootScrolling(this.$el.getRootNode().host)):(l.enableRootScrolling(this.$el.getRootNode().host),(t=this.previousActiveElement)==null||t.focus(),this.previousActiveElement=null)}}},methods:{close(){this.$emit("update:show",!1)},async setFocusAfterTransition(){this.initialFocusElement==="first"?await this.focusFirstElement():this.initialFocusElement.startsWith("#")?await this.focusElementById(this.initialFocusElement):this.initialFocusElement instanceof HTMLElement&&this.initialFocusElement.focus()},trapFocus(e){this.show&&this.focusTrappedTabPress(e)},handleModalClick(e){const t=e.target,s=this._getFocusableElements();s.length&&!s.includes(t)&&(s.includes(document.activeElement)||this.focusFirstElement())}}};var f=function(){var t=this,s=t._self._c;return s("dt-lazy-show",t._g({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)?s("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(),s("transition",{attrs:{appear:"",name:"d-modal__dialog"}},[s("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?s("div",{staticClass:"d-modal__header",attrs:{id:t.labelledById,"data-qa":"dt-modal-title"}},[t._t("header")],2):s("h2",{staticClass:"d-modal__header",attrs:{id:t.labelledById,"data-qa":"dt-modal-title"}},[t._v(" "+t._s(t.title)+" ")]),t.$slots.default?s("div",{class:["d-modal__content",t.contentClass],attrs:{"data-qa":"dt-modal-copy"}},[t._t("default")],2):s("p",{class:["d-modal__content",t.contentClass],attrs:{"data-qa":"dt-modal-copy"}},[t._v(" "+t._s(t.copy)+" ")]),t.hasFooterSlot?s("footer",{staticClass:"d-modal__footer"},[t._t("footer")],2):t._e(),t.hideClose?s("sr-only-close-button",{on:{close:t.close}}):s("dt-button",{staticClass:"d-modal__close",attrs:{"data-qa":"dt-modal-close-button",circle:"",size:"lg",importance:"clear","aria-label":t.closeButtonTitle,title:t.closeButtonTitle},on:{click:t.close},scopedSlots:t._u([{key:"icon",fn:function(){return[s("dt-icon-close",{attrs:{size:"400"}})]},proxy:!0}])})],1)])],1)},E=[],b=d.n(h,f,E);const y=b.exports;exports.default=y;
|
|
2
2
|
//# sourceMappingURL=modal.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.cjs","sources":["../../../components/modal/modal.vue"],"sourcesContent":["<template>\n <dt-lazy-show\n transition=\"d-zoom\"\n :show=\"show\"\n :class=\"[\n 'd-modal',\n MODAL_KIND_MODIFIERS[kind],\n MODAL_SIZE_MODIFIERS[size],\n modalClass,\n ]\"\n data-qa=\"dt-modal\"\n :aria-hidden=\"open\"\n v-on=\"modalListeners\"\n >\n <div\n v-if=\"show && ($slots.banner || bannerTitle)\"\n data-qa=\"dt-modal-banner\"\n :class=\"[\n 'd-modal__banner',\n bannerClass,\n bannerKindClass,\n ]\"\n >\n <!-- @slot Slot for the banner, defaults to bannerTitle prop -->\n <slot name=\"banner\">\n {{ bannerTitle }}\n </slot>\n </div>\n <transition\n appear\n name=\"d-modal__dialog\"\n >\n <div\n v-show=\"show\"\n :class=\"[\n 'd-modal__dialog',\n { 'd-modal__dialog--scrollable': fixedHeaderFooter },\n dialogClass,\n ]\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-describedby=\"describedById\"\n :aria-labelledby=\"labelledById\"\n >\n <div\n v-if=\"$slots.header\"\n :id=\"labelledById\"\n class=\"d-modal__header\"\n data-qa=\"dt-modal-title\"\n >\n <!-- @slot Slot for dialog header section, taking the place of any \"title\" text prop -->\n <slot name=\"header\" />\n </div>\n <h2\n v-else\n :id=\"labelledById\"\n class=\"d-modal__header\"\n data-qa=\"dt-modal-title\"\n >\n {{ title }}\n </h2>\n <div\n v-if=\"$slots.default\"\n :class=\"[\n 'd-modal__content',\n contentClass,\n ]\"\n data-qa=\"dt-modal-copy\"\n >\n <!-- @slot Default slot for dialog body section, taking the place of any \"copy\" text prop -->\n <slot />\n </div>\n <p\n v-else\n :class=\"[\n 'd-modal__content',\n contentClass,\n ]\"\n data-qa=\"dt-modal-copy\"\n >\n {{ copy }}\n </p>\n <footer\n v-if=\"hasFooterSlot\"\n class=\"d-modal__footer\"\n >\n <!-- @slot Slot for dialog footer content, often containing cancel and confirm buttons. -->\n <slot name=\"footer\" />\n </footer>\n <sr-only-close-button\n v-if=\"hideClose\"\n @close=\"close\"\n />\n <dt-button\n v-else\n class=\"d-modal__close\"\n data-qa=\"dt-modal-close-button\"\n circle\n size=\"lg\"\n importance=\"clear\"\n :aria-label=\"closeButtonTitle\"\n :title=\"closeButtonTitle\"\n @click=\"close\"\n >\n <template #icon>\n <dt-icon-close\n size=\"400\"\n />\n </template>\n </dt-button>\n </div>\n </transition>\n </dt-lazy-show>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport { DtButton } from '@/components/button';\nimport { DtIconClose } from '@dialpad/dialtone-icons/vue2';\nimport Modal from '@/common/mixins/modal';\nimport {\n MODAL_BANNER_KINDS,\n MODAL_KIND_MODIFIERS,\n MODAL_SIZE_MODIFIERS,\n} from './modal_constants';\nimport { getUniqueString, disableRootScrolling, enableRootScrolling } from '@/common/utils';\nimport { DtLazyShow } from '@/components/lazy_show';\nimport { EVENT_KEYNAMES } from '@/common/constants';\nimport SrOnlyCloseButton from '@/common/sr_only_close_button.vue';\nimport { NOTICE_KINDS } from '@/components/notice';\nimport { DtLocalizationMixin } from '@/common/mixins';\n\n/**\n * Modals focus the user’s attention exclusively on one task or piece of information\n * via a window that sits on top of the page content.\n * @see https://dialtone.dialpad.com/components/modal.html\n */\nexport default {\n name: 'DtModal',\n\n components: {\n DtLazyShow,\n DtButton,\n DtIconClose,\n SrOnlyCloseButton,\n },\n\n mixins: [Modal, DtLocalizationMixin],\n\n props: {\n /**\n * Body text to display as the modal's main content.\n */\n copy: {\n type: String,\n default: '',\n },\n\n /**\n * Id to use for the dialog's aria-describedby.\n * Recommended only if the dialog content itself isn't enough to give full context,\n * as screen readers should recite the dialog contents by default before any aria-description.\n */\n describedById: {\n type: String,\n default: '',\n },\n\n /**\n * Id to use for the dialog's aria-labelledby.\n */\n labelledById: {\n type: String,\n default: function () { return getUniqueString(); },\n },\n\n /**\n * Whether the modal should be shown.\n * Parent component can sync on this value to control the modal's visibility.\n * @values true, false\n */\n show: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Title text to display in the modal header.\n */\n title: {\n type: String,\n default: '',\n },\n\n /**\n * Title text to display in the modal banner.\n */\n bannerTitle: {\n type: String,\n default: '',\n },\n\n /**\n * The theme of the modal. kind - default or danger,\n * @values default, danger\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(MODAL_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * The size of the modal. size - default or full,\n * @values default, full\n */\n size: {\n type: String,\n default: 'default',\n validator: (s) => Object.keys(MODAL_SIZE_MODIFIERS).includes(s),\n },\n\n /**\n * Additional class name for the root modal element.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n modalClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the dialog element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n dialogClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the content element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n contentClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Sets the color of the banner.\n * @values base, error, info, success, warning\n */\n bannerKind: {\n type: String,\n default: 'warning',\n validate (kind) {\n return NOTICE_KINDS.includes(kind);\n },\n },\n\n /**\n * Additional class name for the banner element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n bannerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Hides the close button on the modal\n * @values true, false\n */\n hideClose: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Whether the modal will close when you click outside of the dialog on the overlay.\n * @values true, false\n */\n closeOnClick: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Scrollable modal that allows scroll the modal content keeping the header and footer fixed\n * @values true, false\n */\n fixedHeaderFooter: {\n type: Boolean,\n default: true,\n },\n\n /**\n * The element that is focused when the modal is opened. This can be an\n * HTMLElement within the modal, a string starting with '#' which will\n * find the element by ID. 'first' which will automatically focus\n * the first element, or 'dialog' which will focus the dialog window itself.\n * If the dialog is modal this prop cannot be 'none'.\n */\n initialFocusElement: {\n type: [String, HTMLElement],\n default: 'first',\n validator: initialFocusElement => {\n return initialFocusElement === 'first' ||\n (initialFocusElement instanceof HTMLElement) ||\n initialFocusElement.startsWith('#');\n },\n },\n },\n\n emits: [\n /**\n * The modal will emit a \"false\" boolean value for this event when the user performs a modal-closing action.\n * Parent components can sync on this value to create a 2-way binding to control modal visibility.\n *\n * @event update:show\n * @type {Boolean}\n */\n 'update:show',\n ],\n\n data () {\n return {\n MODAL_KIND_MODIFIERS,\n MODAL_SIZE_MODIFIERS,\n MODAL_BANNER_KINDS,\n EVENT_KEYNAMES,\n };\n },\n\n computed: {\n modalListeners () {\n return {\n ...this.$listeners,\n\n click: event => {\n if (!this.closeOnClick) return;\n (event.target === event.currentTarget) && this.close();\n this.$emit('click', event);\n },\n\n keydown: event => {\n switch (event.code) {\n case EVENT_KEYNAMES.esc:\n case EVENT_KEYNAMES.escape:\n this.close();\n break;\n case EVENT_KEYNAMES.tab:\n this.trapFocus(event);\n break;\n }\n this.$emit('keydown', event);\n },\n\n 'after-enter': event => {\n this.$emit('update:show', true);\n (event.target === event.currentTarget) && this.setFocusAfterTransition();\n },\n };\n },\n\n open () {\n return `${!this.show}`;\n },\n\n hasFooterSlot () {\n return !!this.$slots.footer;\n },\n\n bannerKindClass () {\n return MODAL_BANNER_KINDS[this.bannerKind];\n },\n\n closeButtonTitle () {\n return this.i18n.$t('DIALTONE_CLOSE_BUTTON');\n },\n },\n\n watch: {\n show: {\n handler (isShowing) {\n if (isShowing) {\n // Set a reference to the previously-active element, to which we'll return focus on modal close.\n this.previousActiveElement = document.activeElement;\n disableRootScrolling(this.$el.getRootNode().host);\n } else {\n enableRootScrolling(this.$el.getRootNode().host);\n // Modal is being hidden, so return focus to the previously active element before clearing the reference.\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n }\n },\n },\n },\n\n methods: {\n close () {\n this.$emit('update:show', false);\n },\n\n setFocusAfterTransition () {\n if (this.initialFocusElement === 'first') {\n this.focusFirstElement();\n } else if (this.initialFocusElement.startsWith('#')) {\n this.focusElementById(this.initialFocusElement);\n } else if (this.initialFocusElement instanceof HTMLElement) {\n this.initialFocusElement.focus();\n }\n },\n\n trapFocus (e) {\n if (this.show) {\n this.focusTrappedTabPress(e);\n }\n },\n },\n};\n</script>\n"],"names":["_sfc_main","DtLazyShow","DtButton","DtIconClose","SrOnlyCloseButton","Modal","DtLocalizationMixin","getUniqueString","k","MODAL_KIND_MODIFIERS","s","MODAL_SIZE_MODIFIERS","kind","NOTICE_KINDS","initialFocusElement","MODAL_BANNER_KINDS","EVENT_KEYNAMES","event","isShowing","disableRootScrolling","enableRootScrolling","_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"modal.cjs","sources":["../../../components/modal/modal.vue"],"sourcesContent":["<template>\n <dt-lazy-show\n transition=\"d-zoom\"\n :show=\"show\"\n :class=\"[\n 'd-modal',\n MODAL_KIND_MODIFIERS[kind],\n MODAL_SIZE_MODIFIERS[size],\n modalClass,\n ]\"\n data-qa=\"dt-modal\"\n :aria-hidden=\"open\"\n v-on=\"modalListeners\"\n >\n <div\n v-if=\"show && ($slots.banner || bannerTitle)\"\n data-qa=\"dt-modal-banner\"\n :class=\"[\n 'd-modal__banner',\n bannerClass,\n bannerKindClass,\n ]\"\n >\n <!-- @slot Slot for the banner, defaults to bannerTitle prop -->\n <slot name=\"banner\">\n {{ bannerTitle }}\n </slot>\n </div>\n <transition\n appear\n name=\"d-modal__dialog\"\n >\n <div\n v-show=\"show\"\n :class=\"[\n 'd-modal__dialog',\n { 'd-modal__dialog--scrollable': fixedHeaderFooter },\n dialogClass,\n ]\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-describedby=\"describedById\"\n :aria-labelledby=\"labelledById\"\n >\n <div\n v-if=\"$slots.header\"\n :id=\"labelledById\"\n class=\"d-modal__header\"\n data-qa=\"dt-modal-title\"\n >\n <!-- @slot Slot for dialog header section, taking the place of any \"title\" text prop -->\n <slot name=\"header\" />\n </div>\n <h2\n v-else\n :id=\"labelledById\"\n class=\"d-modal__header\"\n data-qa=\"dt-modal-title\"\n >\n {{ title }}\n </h2>\n <div\n v-if=\"$slots.default\"\n :class=\"[\n 'd-modal__content',\n contentClass,\n ]\"\n data-qa=\"dt-modal-copy\"\n >\n <!-- @slot Default slot for dialog body section, taking the place of any \"copy\" text prop -->\n <slot />\n </div>\n <p\n v-else\n :class=\"[\n 'd-modal__content',\n contentClass,\n ]\"\n data-qa=\"dt-modal-copy\"\n >\n {{ copy }}\n </p>\n <footer\n v-if=\"hasFooterSlot\"\n class=\"d-modal__footer\"\n >\n <!-- @slot Slot for dialog footer content, often containing cancel and confirm buttons. -->\n <slot name=\"footer\" />\n </footer>\n <sr-only-close-button\n v-if=\"hideClose\"\n @close=\"close\"\n />\n <dt-button\n v-else\n class=\"d-modal__close\"\n data-qa=\"dt-modal-close-button\"\n circle\n size=\"lg\"\n importance=\"clear\"\n :aria-label=\"closeButtonTitle\"\n :title=\"closeButtonTitle\"\n @click=\"close\"\n >\n <template #icon>\n <dt-icon-close\n size=\"400\"\n />\n </template>\n </dt-button>\n </div>\n </transition>\n </dt-lazy-show>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport { DtButton } from '@/components/button';\nimport { DtIconClose } from '@dialpad/dialtone-icons/vue2';\nimport Modal from '@/common/mixins/modal';\nimport {\n MODAL_BANNER_KINDS,\n MODAL_KIND_MODIFIERS,\n MODAL_SIZE_MODIFIERS,\n} from './modal_constants';\nimport { getUniqueString, disableRootScrolling, enableRootScrolling } from '@/common/utils';\nimport { DtLazyShow } from '@/components/lazy_show';\nimport { EVENT_KEYNAMES } from '@/common/constants';\nimport SrOnlyCloseButton from '@/common/sr_only_close_button.vue';\nimport { NOTICE_KINDS } from '@/components/notice';\nimport { DtLocalizationMixin } from '@/common/mixins';\n\n/**\n * Modals focus the user’s attention exclusively on one task or piece of information\n * via a window that sits on top of the page content.\n * @see https://dialtone.dialpad.com/components/modal.html\n */\nexport default {\n name: 'DtModal',\n\n components: {\n DtLazyShow,\n DtButton,\n DtIconClose,\n SrOnlyCloseButton,\n },\n\n mixins: [Modal, DtLocalizationMixin],\n\n props: {\n /**\n * Body text to display as the modal's main content.\n */\n copy: {\n type: String,\n default: '',\n },\n\n /**\n * Id to use for the dialog's aria-describedby.\n * Recommended only if the dialog content itself isn't enough to give full context,\n * as screen readers should recite the dialog contents by default before any aria-description.\n */\n describedById: {\n type: String,\n default: '',\n },\n\n /**\n * Id to use for the dialog's aria-labelledby.\n */\n labelledById: {\n type: String,\n default: function () { return getUniqueString(); },\n },\n\n /**\n * Whether the modal should be shown.\n * Parent component can sync on this value to control the modal's visibility.\n * @values true, false\n */\n show: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Title text to display in the modal header.\n */\n title: {\n type: String,\n default: '',\n },\n\n /**\n * Title text to display in the modal banner.\n */\n bannerTitle: {\n type: String,\n default: '',\n },\n\n /**\n * The theme of the modal. kind - default or danger,\n * @values default, danger\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(MODAL_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * The size of the modal. size - default or full,\n * @values default, full\n */\n size: {\n type: String,\n default: 'default',\n validator: (s) => Object.keys(MODAL_SIZE_MODIFIERS).includes(s),\n },\n\n /**\n * Additional class name for the root modal element.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n modalClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the dialog element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n dialogClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the content element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n contentClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Sets the color of the banner.\n * @values base, error, info, success, warning\n */\n bannerKind: {\n type: String,\n default: 'warning',\n validate (kind) {\n return NOTICE_KINDS.includes(kind);\n },\n },\n\n /**\n * Additional class name for the banner element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n bannerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Hides the close button on the modal\n * @values true, false\n */\n hideClose: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Whether the modal will close when you click outside of the dialog on the overlay.\n * @values true, false\n */\n closeOnClick: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Scrollable modal that allows scroll the modal content keeping the header and footer fixed\n * @values true, false\n */\n fixedHeaderFooter: {\n type: Boolean,\n default: true,\n },\n\n /**\n * The element that is focused when the modal is opened. This can be an\n * HTMLElement within the modal, a string starting with '#' which will\n * find the element by ID. 'first' which will automatically focus\n * the first element, or 'dialog' which will focus the dialog window itself.\n * If the dialog is modal this prop cannot be 'none'.\n */\n initialFocusElement: {\n type: [String, HTMLElement],\n default: 'first',\n validator: initialFocusElement => {\n return initialFocusElement === 'first' ||\n (initialFocusElement instanceof HTMLElement) ||\n initialFocusElement.startsWith('#');\n },\n },\n },\n\n emits: [\n /**\n * The modal will emit a \"false\" boolean value for this event when the user performs a modal-closing action.\n * Parent components can sync on this value to create a 2-way binding to control modal visibility.\n *\n * @event update:show\n * @type {Boolean}\n */\n 'update:show',\n ],\n\n data () {\n return {\n MODAL_KIND_MODIFIERS,\n MODAL_SIZE_MODIFIERS,\n MODAL_BANNER_KINDS,\n EVENT_KEYNAMES,\n };\n },\n\n computed: {\n modalListeners () {\n return {\n ...this.$listeners,\n\n click: event => {\n // Handle backdrop clicks for closing modal\n if (this.closeOnClick && event.target === event.currentTarget) {\n this.close();\n } else if (this.show && event.target !== event.currentTarget) {\n // Ensure focus stays within modal when clicking inside it\n this.handleModalClick(event);\n }\n\n this.$emit('click', event);\n },\n\n keydown: event => {\n switch (event.code) {\n case EVENT_KEYNAMES.esc:\n case EVENT_KEYNAMES.escape:\n this.close();\n break;\n case EVENT_KEYNAMES.tab:\n this.trapFocus(event);\n break;\n }\n this.$emit('keydown', event);\n },\n\n 'after-enter': async () => {\n this.$emit('update:show', true);\n await this.setFocusAfterTransition();\n },\n };\n },\n\n open () {\n return `${!this.show}`;\n },\n\n hasFooterSlot () {\n return !!this.$slots.footer;\n },\n\n bannerKindClass () {\n return MODAL_BANNER_KINDS[this.bannerKind];\n },\n\n closeButtonTitle () {\n return this.i18n.$t('DIALTONE_CLOSE_BUTTON');\n },\n },\n\n watch: {\n show: {\n handler (isShowing) {\n if (isShowing) {\n // Set a reference to the previously-active element, to which we'll return focus on modal close.\n this.previousActiveElement = document.activeElement;\n disableRootScrolling(this.$el.getRootNode().host);\n } else {\n enableRootScrolling(this.$el.getRootNode().host);\n // Modal is being hidden, so return focus to the previously active element before clearing the reference.\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n }\n },\n },\n },\n\n methods: {\n close () {\n this.$emit('update:show', false);\n },\n\n async setFocusAfterTransition () {\n if (this.initialFocusElement === 'first') {\n await this.focusFirstElement();\n } else if (this.initialFocusElement.startsWith('#')) {\n await this.focusElementById(this.initialFocusElement);\n } else if (this.initialFocusElement instanceof HTMLElement) {\n this.initialFocusElement.focus();\n }\n },\n\n trapFocus (e) {\n if (this.show) {\n this.focusTrappedTabPress(e);\n }\n },\n\n handleModalClick (event) {\n // Ensure focus stays within modal when clicking inside it\n const clickedElement = event.target;\n const focusableElements = this._getFocusableElements();\n\n // If the clicked element is not focusable, ensure focus stays in modal\n if (focusableElements.length && !focusableElements.includes(clickedElement)) {\n // Check if current active element is still within the modal\n if (!focusableElements.includes(document.activeElement)) {\n this.focusFirstElement();\n }\n }\n },\n },\n};\n</script>\n"],"names":["_sfc_main","DtLazyShow","DtButton","DtIconClose","SrOnlyCloseButton","Modal","DtLocalizationMixin","getUniqueString","k","MODAL_KIND_MODIFIERS","s","MODAL_SIZE_MODIFIERS","kind","NOTICE_KINDS","initialFocusElement","MODAL_BANNER_KINDS","EVENT_KEYNAMES","event","isShowing","disableRootScrolling","enableRootScrolling","_a","clickedElement","focusableElements"],"mappings":"qlBAyIAA,EAAA,CACA,KAAA,UAEA,WAAA,CACA,WAAAC,EAAA,QACA,SAAAC,EAAA,QACA,YAAAC,EAAA,YACA,kBAAAC,EAAA,OACA,EAEA,OAAA,CAAAC,EAAA,QAAAC,SAAA,EAEA,MAAA,CAIA,KAAA,CACA,KAAA,OACA,QAAA,EACA,EAOA,cAAA,CACA,KAAA,OACA,QAAA,EACA,EAKA,aAAA,CACA,KAAA,OACA,QAAA,UAAA,CAAA,OAAAC,EAAA,gBAAA,CAAA,CACA,EAOA,KAAA,CACA,KAAA,QACA,QAAA,EACA,EAKA,MAAA,CACA,KAAA,OACA,QAAA,EACA,EAKA,YAAA,CACA,KAAA,OACA,QAAA,EACA,EAMA,KAAA,CACA,KAAA,OACA,QAAA,UACA,UAAAC,GAAA,OAAA,KAAAC,sBAAA,EAAA,SAAAD,CAAA,CACA,EAMA,KAAA,CACA,KAAA,OACA,QAAA,UACA,UAAAE,GAAA,OAAA,KAAAC,sBAAA,EAAA,SAAAD,CAAA,CACA,EAOA,WAAA,CACA,KAAA,CAAA,OAAA,OAAA,KAAA,EACA,QAAA,EACA,EAOA,YAAA,CACA,KAAA,CAAA,OAAA,OAAA,KAAA,EACA,QAAA,EACA,EAOA,aAAA,CACA,KAAA,CAAA,OAAA,OAAA,KAAA,EACA,QAAA,EACA,EAMA,WAAA,CACA,KAAA,OACA,QAAA,UACA,SAAAE,EAAA,CACA,OAAAC,EAAA,aAAA,SAAAD,CAAA,CACA,CACA,EAOA,YAAA,CACA,KAAA,CAAA,OAAA,OAAA,KAAA,EACA,QAAA,EACA,EAMA,UAAA,CACA,KAAA,QACA,QAAA,EACA,EAMA,aAAA,CACA,KAAA,QACA,QAAA,EACA,EAMA,kBAAA,CACA,KAAA,QACA,QAAA,EACA,EASA,oBAAA,CACA,KAAA,CAAA,OAAA,WAAA,EACA,QAAA,QACA,UAAAE,GACAA,IAAA,SACAA,aAAA,aACAA,EAAA,WAAA,GAAA,CAEA,CACA,EAEA,MAAA,CAQA,aACA,EAEA,MAAA,CACA,MAAA,CACA,qBAAAL,EAAA,qBACA,qBAAAE,EAAA,qBACA,mBAAAI,EAAA,mBACA,eAAAC,EAAA,cACA,CACA,EAEA,SAAA,CACA,gBAAA,CACA,MAAA,CACA,GAAA,KAAA,WAEA,MAAAC,GAAA,CAEA,KAAA,cAAAA,EAAA,SAAAA,EAAA,cACA,KAAA,MAAA,EACA,KAAA,MAAAA,EAAA,SAAAA,EAAA,eAEA,KAAA,iBAAAA,CAAA,EAGA,KAAA,MAAA,QAAAA,CAAA,CACA,EAEA,QAAAA,GAAA,CACA,OAAAA,EAAA,KAAA,CACA,KAAAD,EAAAA,eAAA,IACA,KAAAA,EAAA,eAAA,OACA,KAAA,MAAA,EACA,MACA,KAAAA,EAAA,eAAA,IACA,KAAA,UAAAC,CAAA,EACA,KACA,CACA,KAAA,MAAA,UAAAA,CAAA,CACA,EAEA,cAAA,SAAA,CACA,KAAA,MAAA,cAAA,EAAA,EACA,MAAA,KAAA,yBACA,CACA,CACA,EAEA,MAAA,CACA,MAAA,GAAA,CAAA,KAAA,IAAA,EACA,EAEA,eAAA,CACA,MAAA,CAAA,CAAA,KAAA,OAAA,MACA,EAEA,iBAAA,CACA,OAAAF,EAAA,mBAAA,KAAA,UAAA,CACA,EAEA,kBAAA,CACA,OAAA,KAAA,KAAA,GAAA,uBAAA,CACA,CACA,EAEA,MAAA,CACA,KAAA,CACA,QAAAG,EAAA,OACAA,GAEA,KAAA,sBAAA,SAAA,cACAC,EAAAA,qBAAA,KAAA,IAAA,YAAA,EAAA,IAAA,IAEAC,EAAAA,oBAAA,KAAA,IAAA,YAAA,EAAA,IAAA,GAEAC,EAAA,KAAA,wBAAA,MAAAA,EAAA,QACA,KAAA,sBAAA,KAEA,CACA,CACA,EAEA,QAAA,CACA,OAAA,CACA,KAAA,MAAA,cAAA,EAAA,CACA,EAEA,MAAA,yBAAA,CACA,KAAA,sBAAA,QACA,MAAA,KAAA,oBACA,KAAA,oBAAA,WAAA,GAAA,EACA,MAAA,KAAA,iBAAA,KAAA,mBAAA,EACA,KAAA,+BAAA,aACA,KAAA,oBAAA,OAEA,EAEA,UAAA,EAAA,CACA,KAAA,MACA,KAAA,qBAAA,CAAA,CAEA,EAEA,iBAAAJ,EAAA,CAEA,MAAAK,EAAAL,EAAA,OACAM,EAAA,KAAA,wBAGAA,EAAA,QAAA,CAAAA,EAAA,SAAAD,CAAA,IAEAC,EAAA,SAAA,SAAA,aAAA,GACA,KAAA,kBAAA,EAGA,CACA,CACA"}
|
|
@@ -192,7 +192,7 @@ const b = {
|
|
|
192
192
|
return {
|
|
193
193
|
...this.$listeners,
|
|
194
194
|
click: (e) => {
|
|
195
|
-
this.closeOnClick &&
|
|
195
|
+
this.closeOnClick && e.target === e.currentTarget ? this.close() : this.show && e.target !== e.currentTarget && this.handleModalClick(e), this.$emit("click", e);
|
|
196
196
|
},
|
|
197
197
|
keydown: (e) => {
|
|
198
198
|
switch (e.code) {
|
|
@@ -206,8 +206,8 @@ const b = {
|
|
|
206
206
|
}
|
|
207
207
|
this.$emit("keydown", e);
|
|
208
208
|
},
|
|
209
|
-
"after-enter": (
|
|
210
|
-
this.$emit("update:show", !0),
|
|
209
|
+
"after-enter": async () => {
|
|
210
|
+
this.$emit("update:show", !0), await this.setFocusAfterTransition();
|
|
211
211
|
}
|
|
212
212
|
};
|
|
213
213
|
},
|
|
@@ -236,11 +236,15 @@ const b = {
|
|
|
236
236
|
close() {
|
|
237
237
|
this.$emit("update:show", !1);
|
|
238
238
|
},
|
|
239
|
-
setFocusAfterTransition() {
|
|
240
|
-
this.initialFocusElement === "first" ? this.focusFirstElement() : this.initialFocusElement.startsWith("#") ? this.focusElementById(this.initialFocusElement) : this.initialFocusElement instanceof HTMLElement && this.initialFocusElement.focus();
|
|
239
|
+
async setFocusAfterTransition() {
|
|
240
|
+
this.initialFocusElement === "first" ? await this.focusFirstElement() : this.initialFocusElement.startsWith("#") ? await this.focusElementById(this.initialFocusElement) : this.initialFocusElement instanceof HTMLElement && this.initialFocusElement.focus();
|
|
241
241
|
},
|
|
242
242
|
trapFocus(e) {
|
|
243
243
|
this.show && this.focusTrappedTabPress(e);
|
|
244
|
+
},
|
|
245
|
+
handleModalClick(e) {
|
|
246
|
+
const t = e.target, a = this._getFocusableElements();
|
|
247
|
+
a.length && !a.includes(t) && (a.includes(document.activeElement) || this.focusFirstElement());
|
|
244
248
|
}
|
|
245
249
|
}
|
|
246
250
|
};
|
|
@@ -270,13 +274,13 @@ var g = function() {
|
|
|
270
274
|
], 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", circle: "", size: "lg", importance: "clear", "aria-label": t.closeButtonTitle, title: t.closeButtonTitle }, on: { click: t.close }, scopedSlots: t._u([{ key: "icon", fn: function() {
|
|
271
275
|
return [a("dt-icon-close", { attrs: { size: "400" } })];
|
|
272
276
|
}, proxy: !0 }]) })], 1)])], 1);
|
|
273
|
-
},
|
|
277
|
+
}, E = [], S = /* @__PURE__ */ f(
|
|
274
278
|
b,
|
|
275
279
|
g,
|
|
276
|
-
|
|
280
|
+
E
|
|
277
281
|
);
|
|
278
|
-
const
|
|
282
|
+
const A = S.exports;
|
|
279
283
|
export {
|
|
280
|
-
|
|
284
|
+
A as default
|
|
281
285
|
};
|
|
282
286
|
//# sourceMappingURL=modal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.js","sources":["../../../components/modal/modal.vue"],"sourcesContent":["<template>\n <dt-lazy-show\n transition=\"d-zoom\"\n :show=\"show\"\n :class=\"[\n 'd-modal',\n MODAL_KIND_MODIFIERS[kind],\n MODAL_SIZE_MODIFIERS[size],\n modalClass,\n ]\"\n data-qa=\"dt-modal\"\n :aria-hidden=\"open\"\n v-on=\"modalListeners\"\n >\n <div\n v-if=\"show && ($slots.banner || bannerTitle)\"\n data-qa=\"dt-modal-banner\"\n :class=\"[\n 'd-modal__banner',\n bannerClass,\n bannerKindClass,\n ]\"\n >\n <!-- @slot Slot for the banner, defaults to bannerTitle prop -->\n <slot name=\"banner\">\n {{ bannerTitle }}\n </slot>\n </div>\n <transition\n appear\n name=\"d-modal__dialog\"\n >\n <div\n v-show=\"show\"\n :class=\"[\n 'd-modal__dialog',\n { 'd-modal__dialog--scrollable': fixedHeaderFooter },\n dialogClass,\n ]\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-describedby=\"describedById\"\n :aria-labelledby=\"labelledById\"\n >\n <div\n v-if=\"$slots.header\"\n :id=\"labelledById\"\n class=\"d-modal__header\"\n data-qa=\"dt-modal-title\"\n >\n <!-- @slot Slot for dialog header section, taking the place of any \"title\" text prop -->\n <slot name=\"header\" />\n </div>\n <h2\n v-else\n :id=\"labelledById\"\n class=\"d-modal__header\"\n data-qa=\"dt-modal-title\"\n >\n {{ title }}\n </h2>\n <div\n v-if=\"$slots.default\"\n :class=\"[\n 'd-modal__content',\n contentClass,\n ]\"\n data-qa=\"dt-modal-copy\"\n >\n <!-- @slot Default slot for dialog body section, taking the place of any \"copy\" text prop -->\n <slot />\n </div>\n <p\n v-else\n :class=\"[\n 'd-modal__content',\n contentClass,\n ]\"\n data-qa=\"dt-modal-copy\"\n >\n {{ copy }}\n </p>\n <footer\n v-if=\"hasFooterSlot\"\n class=\"d-modal__footer\"\n >\n <!-- @slot Slot for dialog footer content, often containing cancel and confirm buttons. -->\n <slot name=\"footer\" />\n </footer>\n <sr-only-close-button\n v-if=\"hideClose\"\n @close=\"close\"\n />\n <dt-button\n v-else\n class=\"d-modal__close\"\n data-qa=\"dt-modal-close-button\"\n circle\n size=\"lg\"\n importance=\"clear\"\n :aria-label=\"closeButtonTitle\"\n :title=\"closeButtonTitle\"\n @click=\"close\"\n >\n <template #icon>\n <dt-icon-close\n size=\"400\"\n />\n </template>\n </dt-button>\n </div>\n </transition>\n </dt-lazy-show>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport { DtButton } from '@/components/button';\nimport { DtIconClose } from '@dialpad/dialtone-icons/vue2';\nimport Modal from '@/common/mixins/modal';\nimport {\n MODAL_BANNER_KINDS,\n MODAL_KIND_MODIFIERS,\n MODAL_SIZE_MODIFIERS,\n} from './modal_constants';\nimport { getUniqueString, disableRootScrolling, enableRootScrolling } from '@/common/utils';\nimport { DtLazyShow } from '@/components/lazy_show';\nimport { EVENT_KEYNAMES } from '@/common/constants';\nimport SrOnlyCloseButton from '@/common/sr_only_close_button.vue';\nimport { NOTICE_KINDS } from '@/components/notice';\nimport { DtLocalizationMixin } from '@/common/mixins';\n\n/**\n * Modals focus the user’s attention exclusively on one task or piece of information\n * via a window that sits on top of the page content.\n * @see https://dialtone.dialpad.com/components/modal.html\n */\nexport default {\n name: 'DtModal',\n\n components: {\n DtLazyShow,\n DtButton,\n DtIconClose,\n SrOnlyCloseButton,\n },\n\n mixins: [Modal, DtLocalizationMixin],\n\n props: {\n /**\n * Body text to display as the modal's main content.\n */\n copy: {\n type: String,\n default: '',\n },\n\n /**\n * Id to use for the dialog's aria-describedby.\n * Recommended only if the dialog content itself isn't enough to give full context,\n * as screen readers should recite the dialog contents by default before any aria-description.\n */\n describedById: {\n type: String,\n default: '',\n },\n\n /**\n * Id to use for the dialog's aria-labelledby.\n */\n labelledById: {\n type: String,\n default: function () { return getUniqueString(); },\n },\n\n /**\n * Whether the modal should be shown.\n * Parent component can sync on this value to control the modal's visibility.\n * @values true, false\n */\n show: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Title text to display in the modal header.\n */\n title: {\n type: String,\n default: '',\n },\n\n /**\n * Title text to display in the modal banner.\n */\n bannerTitle: {\n type: String,\n default: '',\n },\n\n /**\n * The theme of the modal. kind - default or danger,\n * @values default, danger\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(MODAL_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * The size of the modal. size - default or full,\n * @values default, full\n */\n size: {\n type: String,\n default: 'default',\n validator: (s) => Object.keys(MODAL_SIZE_MODIFIERS).includes(s),\n },\n\n /**\n * Additional class name for the root modal element.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n modalClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the dialog element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n dialogClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the content element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n contentClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Sets the color of the banner.\n * @values base, error, info, success, warning\n */\n bannerKind: {\n type: String,\n default: 'warning',\n validate (kind) {\n return NOTICE_KINDS.includes(kind);\n },\n },\n\n /**\n * Additional class name for the banner element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n bannerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Hides the close button on the modal\n * @values true, false\n */\n hideClose: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Whether the modal will close when you click outside of the dialog on the overlay.\n * @values true, false\n */\n closeOnClick: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Scrollable modal that allows scroll the modal content keeping the header and footer fixed\n * @values true, false\n */\n fixedHeaderFooter: {\n type: Boolean,\n default: true,\n },\n\n /**\n * The element that is focused when the modal is opened. This can be an\n * HTMLElement within the modal, a string starting with '#' which will\n * find the element by ID. 'first' which will automatically focus\n * the first element, or 'dialog' which will focus the dialog window itself.\n * If the dialog is modal this prop cannot be 'none'.\n */\n initialFocusElement: {\n type: [String, HTMLElement],\n default: 'first',\n validator: initialFocusElement => {\n return initialFocusElement === 'first' ||\n (initialFocusElement instanceof HTMLElement) ||\n initialFocusElement.startsWith('#');\n },\n },\n },\n\n emits: [\n /**\n * The modal will emit a \"false\" boolean value for this event when the user performs a modal-closing action.\n * Parent components can sync on this value to create a 2-way binding to control modal visibility.\n *\n * @event update:show\n * @type {Boolean}\n */\n 'update:show',\n ],\n\n data () {\n return {\n MODAL_KIND_MODIFIERS,\n MODAL_SIZE_MODIFIERS,\n MODAL_BANNER_KINDS,\n EVENT_KEYNAMES,\n };\n },\n\n computed: {\n modalListeners () {\n return {\n ...this.$listeners,\n\n click: event => {\n if (!this.closeOnClick) return;\n (event.target === event.currentTarget) && this.close();\n this.$emit('click', event);\n },\n\n keydown: event => {\n switch (event.code) {\n case EVENT_KEYNAMES.esc:\n case EVENT_KEYNAMES.escape:\n this.close();\n break;\n case EVENT_KEYNAMES.tab:\n this.trapFocus(event);\n break;\n }\n this.$emit('keydown', event);\n },\n\n 'after-enter': event => {\n this.$emit('update:show', true);\n (event.target === event.currentTarget) && this.setFocusAfterTransition();\n },\n };\n },\n\n open () {\n return `${!this.show}`;\n },\n\n hasFooterSlot () {\n return !!this.$slots.footer;\n },\n\n bannerKindClass () {\n return MODAL_BANNER_KINDS[this.bannerKind];\n },\n\n closeButtonTitle () {\n return this.i18n.$t('DIALTONE_CLOSE_BUTTON');\n },\n },\n\n watch: {\n show: {\n handler (isShowing) {\n if (isShowing) {\n // Set a reference to the previously-active element, to which we'll return focus on modal close.\n this.previousActiveElement = document.activeElement;\n disableRootScrolling(this.$el.getRootNode().host);\n } else {\n enableRootScrolling(this.$el.getRootNode().host);\n // Modal is being hidden, so return focus to the previously active element before clearing the reference.\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n }\n },\n },\n },\n\n methods: {\n close () {\n this.$emit('update:show', false);\n },\n\n setFocusAfterTransition () {\n if (this.initialFocusElement === 'first') {\n this.focusFirstElement();\n } else if (this.initialFocusElement.startsWith('#')) {\n this.focusElementById(this.initialFocusElement);\n } else if (this.initialFocusElement instanceof HTMLElement) {\n this.initialFocusElement.focus();\n }\n },\n\n trapFocus (e) {\n if (this.show) {\n this.focusTrappedTabPress(e);\n }\n },\n },\n};\n</script>\n"],"names":["_sfc_main","DtLazyShow","DtButton","DtIconClose","SrOnlyCloseButton","Modal","DtLocalizationMixin","getUniqueString","k","MODAL_KIND_MODIFIERS","s","MODAL_SIZE_MODIFIERS","kind","NOTICE_KINDS","initialFocusElement","MODAL_BANNER_KINDS","EVENT_KEYNAMES","event","isShowing","disableRootScrolling","enableRootScrolling","_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"modal.js","sources":["../../../components/modal/modal.vue"],"sourcesContent":["<template>\n <dt-lazy-show\n transition=\"d-zoom\"\n :show=\"show\"\n :class=\"[\n 'd-modal',\n MODAL_KIND_MODIFIERS[kind],\n MODAL_SIZE_MODIFIERS[size],\n modalClass,\n ]\"\n data-qa=\"dt-modal\"\n :aria-hidden=\"open\"\n v-on=\"modalListeners\"\n >\n <div\n v-if=\"show && ($slots.banner || bannerTitle)\"\n data-qa=\"dt-modal-banner\"\n :class=\"[\n 'd-modal__banner',\n bannerClass,\n bannerKindClass,\n ]\"\n >\n <!-- @slot Slot for the banner, defaults to bannerTitle prop -->\n <slot name=\"banner\">\n {{ bannerTitle }}\n </slot>\n </div>\n <transition\n appear\n name=\"d-modal__dialog\"\n >\n <div\n v-show=\"show\"\n :class=\"[\n 'd-modal__dialog',\n { 'd-modal__dialog--scrollable': fixedHeaderFooter },\n dialogClass,\n ]\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-describedby=\"describedById\"\n :aria-labelledby=\"labelledById\"\n >\n <div\n v-if=\"$slots.header\"\n :id=\"labelledById\"\n class=\"d-modal__header\"\n data-qa=\"dt-modal-title\"\n >\n <!-- @slot Slot for dialog header section, taking the place of any \"title\" text prop -->\n <slot name=\"header\" />\n </div>\n <h2\n v-else\n :id=\"labelledById\"\n class=\"d-modal__header\"\n data-qa=\"dt-modal-title\"\n >\n {{ title }}\n </h2>\n <div\n v-if=\"$slots.default\"\n :class=\"[\n 'd-modal__content',\n contentClass,\n ]\"\n data-qa=\"dt-modal-copy\"\n >\n <!-- @slot Default slot for dialog body section, taking the place of any \"copy\" text prop -->\n <slot />\n </div>\n <p\n v-else\n :class=\"[\n 'd-modal__content',\n contentClass,\n ]\"\n data-qa=\"dt-modal-copy\"\n >\n {{ copy }}\n </p>\n <footer\n v-if=\"hasFooterSlot\"\n class=\"d-modal__footer\"\n >\n <!-- @slot Slot for dialog footer content, often containing cancel and confirm buttons. -->\n <slot name=\"footer\" />\n </footer>\n <sr-only-close-button\n v-if=\"hideClose\"\n @close=\"close\"\n />\n <dt-button\n v-else\n class=\"d-modal__close\"\n data-qa=\"dt-modal-close-button\"\n circle\n size=\"lg\"\n importance=\"clear\"\n :aria-label=\"closeButtonTitle\"\n :title=\"closeButtonTitle\"\n @click=\"close\"\n >\n <template #icon>\n <dt-icon-close\n size=\"400\"\n />\n </template>\n </dt-button>\n </div>\n </transition>\n </dt-lazy-show>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport { DtButton } from '@/components/button';\nimport { DtIconClose } from '@dialpad/dialtone-icons/vue2';\nimport Modal from '@/common/mixins/modal';\nimport {\n MODAL_BANNER_KINDS,\n MODAL_KIND_MODIFIERS,\n MODAL_SIZE_MODIFIERS,\n} from './modal_constants';\nimport { getUniqueString, disableRootScrolling, enableRootScrolling } from '@/common/utils';\nimport { DtLazyShow } from '@/components/lazy_show';\nimport { EVENT_KEYNAMES } from '@/common/constants';\nimport SrOnlyCloseButton from '@/common/sr_only_close_button.vue';\nimport { NOTICE_KINDS } from '@/components/notice';\nimport { DtLocalizationMixin } from '@/common/mixins';\n\n/**\n * Modals focus the user’s attention exclusively on one task or piece of information\n * via a window that sits on top of the page content.\n * @see https://dialtone.dialpad.com/components/modal.html\n */\nexport default {\n name: 'DtModal',\n\n components: {\n DtLazyShow,\n DtButton,\n DtIconClose,\n SrOnlyCloseButton,\n },\n\n mixins: [Modal, DtLocalizationMixin],\n\n props: {\n /**\n * Body text to display as the modal's main content.\n */\n copy: {\n type: String,\n default: '',\n },\n\n /**\n * Id to use for the dialog's aria-describedby.\n * Recommended only if the dialog content itself isn't enough to give full context,\n * as screen readers should recite the dialog contents by default before any aria-description.\n */\n describedById: {\n type: String,\n default: '',\n },\n\n /**\n * Id to use for the dialog's aria-labelledby.\n */\n labelledById: {\n type: String,\n default: function () { return getUniqueString(); },\n },\n\n /**\n * Whether the modal should be shown.\n * Parent component can sync on this value to control the modal's visibility.\n * @values true, false\n */\n show: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Title text to display in the modal header.\n */\n title: {\n type: String,\n default: '',\n },\n\n /**\n * Title text to display in the modal banner.\n */\n bannerTitle: {\n type: String,\n default: '',\n },\n\n /**\n * The theme of the modal. kind - default or danger,\n * @values default, danger\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(MODAL_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * The size of the modal. size - default or full,\n * @values default, full\n */\n size: {\n type: String,\n default: 'default',\n validator: (s) => Object.keys(MODAL_SIZE_MODIFIERS).includes(s),\n },\n\n /**\n * Additional class name for the root modal element.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n modalClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the dialog element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n dialogClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the content element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n contentClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Sets the color of the banner.\n * @values base, error, info, success, warning\n */\n bannerKind: {\n type: String,\n default: 'warning',\n validate (kind) {\n return NOTICE_KINDS.includes(kind);\n },\n },\n\n /**\n * Additional class name for the banner element within the modal.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n bannerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Hides the close button on the modal\n * @values true, false\n */\n hideClose: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Whether the modal will close when you click outside of the dialog on the overlay.\n * @values true, false\n */\n closeOnClick: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Scrollable modal that allows scroll the modal content keeping the header and footer fixed\n * @values true, false\n */\n fixedHeaderFooter: {\n type: Boolean,\n default: true,\n },\n\n /**\n * The element that is focused when the modal is opened. This can be an\n * HTMLElement within the modal, a string starting with '#' which will\n * find the element by ID. 'first' which will automatically focus\n * the first element, or 'dialog' which will focus the dialog window itself.\n * If the dialog is modal this prop cannot be 'none'.\n */\n initialFocusElement: {\n type: [String, HTMLElement],\n default: 'first',\n validator: initialFocusElement => {\n return initialFocusElement === 'first' ||\n (initialFocusElement instanceof HTMLElement) ||\n initialFocusElement.startsWith('#');\n },\n },\n },\n\n emits: [\n /**\n * The modal will emit a \"false\" boolean value for this event when the user performs a modal-closing action.\n * Parent components can sync on this value to create a 2-way binding to control modal visibility.\n *\n * @event update:show\n * @type {Boolean}\n */\n 'update:show',\n ],\n\n data () {\n return {\n MODAL_KIND_MODIFIERS,\n MODAL_SIZE_MODIFIERS,\n MODAL_BANNER_KINDS,\n EVENT_KEYNAMES,\n };\n },\n\n computed: {\n modalListeners () {\n return {\n ...this.$listeners,\n\n click: event => {\n // Handle backdrop clicks for closing modal\n if (this.closeOnClick && event.target === event.currentTarget) {\n this.close();\n } else if (this.show && event.target !== event.currentTarget) {\n // Ensure focus stays within modal when clicking inside it\n this.handleModalClick(event);\n }\n\n this.$emit('click', event);\n },\n\n keydown: event => {\n switch (event.code) {\n case EVENT_KEYNAMES.esc:\n case EVENT_KEYNAMES.escape:\n this.close();\n break;\n case EVENT_KEYNAMES.tab:\n this.trapFocus(event);\n break;\n }\n this.$emit('keydown', event);\n },\n\n 'after-enter': async () => {\n this.$emit('update:show', true);\n await this.setFocusAfterTransition();\n },\n };\n },\n\n open () {\n return `${!this.show}`;\n },\n\n hasFooterSlot () {\n return !!this.$slots.footer;\n },\n\n bannerKindClass () {\n return MODAL_BANNER_KINDS[this.bannerKind];\n },\n\n closeButtonTitle () {\n return this.i18n.$t('DIALTONE_CLOSE_BUTTON');\n },\n },\n\n watch: {\n show: {\n handler (isShowing) {\n if (isShowing) {\n // Set a reference to the previously-active element, to which we'll return focus on modal close.\n this.previousActiveElement = document.activeElement;\n disableRootScrolling(this.$el.getRootNode().host);\n } else {\n enableRootScrolling(this.$el.getRootNode().host);\n // Modal is being hidden, so return focus to the previously active element before clearing the reference.\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n }\n },\n },\n },\n\n methods: {\n close () {\n this.$emit('update:show', false);\n },\n\n async setFocusAfterTransition () {\n if (this.initialFocusElement === 'first') {\n await this.focusFirstElement();\n } else if (this.initialFocusElement.startsWith('#')) {\n await this.focusElementById(this.initialFocusElement);\n } else if (this.initialFocusElement instanceof HTMLElement) {\n this.initialFocusElement.focus();\n }\n },\n\n trapFocus (e) {\n if (this.show) {\n this.focusTrappedTabPress(e);\n }\n },\n\n handleModalClick (event) {\n // Ensure focus stays within modal when clicking inside it\n const clickedElement = event.target;\n const focusableElements = this._getFocusableElements();\n\n // If the clicked element is not focusable, ensure focus stays in modal\n if (focusableElements.length && !focusableElements.includes(clickedElement)) {\n // Check if current active element is still within the modal\n if (!focusableElements.includes(document.activeElement)) {\n this.focusFirstElement();\n }\n }\n },\n },\n};\n</script>\n"],"names":["_sfc_main","DtLazyShow","DtButton","DtIconClose","SrOnlyCloseButton","Modal","DtLocalizationMixin","getUniqueString","k","MODAL_KIND_MODIFIERS","s","MODAL_SIZE_MODIFIERS","kind","NOTICE_KINDS","initialFocusElement","MODAL_BANNER_KINDS","EVENT_KEYNAMES","event","isShowing","disableRootScrolling","enableRootScrolling","_a","clickedElement","focusableElements"],"mappings":"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"}
|