@dialpad/dialtone-vue 4.2.0 → 4.3.1
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/component-documentation.json +1 -1
- package/dist/components/Hovercard/Hovercard.vue.d.ts.map +1 -1
- package/dist/components/Modal/Modal.vue.d.ts +4 -0
- package/dist/components/Modal/Modal.vue.d.ts.map +1 -1
- package/dist/components/Tooltip/Tooltip.vue.d.ts +12 -1
- package/dist/components/Tooltip/Tooltip.vue.d.ts.map +1 -1
- package/dist/lib/hovercard/hovercard.cjs +1 -1
- package/dist/lib/hovercard/hovercard.cjs.map +1 -1
- package/dist/lib/hovercard/hovercard.js +2 -2
- package/dist/lib/hovercard/hovercard.js.map +1 -1
- package/dist/lib/modal/modal.cjs +1 -1
- package/dist/lib/modal/modal.cjs.map +1 -1
- package/dist/lib/modal/modal.js +15 -4
- package/dist/lib/modal/modal.js.map +1 -1
- package/dist/lib/tooltip/tooltip.cjs +1 -1
- package/dist/lib/tooltip/tooltip.cjs.map +1 -1
- package/dist/lib/tooltip/tooltip.js +16 -8
- package/dist/lib/tooltip/tooltip.js.map +1 -1
- package/dist/localization/en-US.cjs +5 -0
- package/dist/localization/en-US.cjs.map +1 -1
- package/dist/localization/en-US.js +1 -1
- package/dist/localization/en-US.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Hovercard.vue.d.ts","sourceRoot":"","sources":["../../../components/Hovercard/Hovercard.vue"],"names":[],"mappings":"AA0DA;
|
|
1
|
+
{"version":3,"file":"Hovercard.vue.d.ts","sourceRoot":"","sources":["../../../components/Hovercard/Hovercard.vue"],"names":[],"mappings":"AA0DA;wBAkxBqB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;;6BAEtE,CAAC,EAAE,CAAC;;;AAdjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yEApbA,IAzOU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAyOV,GAvSkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAuSlC,GAvSkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yEAuSlC,IAzOU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qEAyOV,IAzOU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAwqBP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AArMH,sCAGC;AAED,sCAMC"}
|
|
@@ -109,6 +109,8 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
109
109
|
hasSlotContent: typeof hasSlotContent;
|
|
110
110
|
i18n: any;
|
|
111
111
|
autoTeleportTarget: null;
|
|
112
|
+
mousedownOnBackdrop: boolean;
|
|
113
|
+
mouseupOnBackdrop: boolean;
|
|
112
114
|
}, {
|
|
113
115
|
hasFooterSlot(): boolean;
|
|
114
116
|
bannerKindClass(): any;
|
|
@@ -117,6 +119,8 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
117
119
|
getScrollRoot(): any;
|
|
118
120
|
syncDialogState(isShowing: any): void;
|
|
119
121
|
close(): void;
|
|
122
|
+
onBackdropMousedown(event: any): void;
|
|
123
|
+
onBackdropMouseup(event: any): void;
|
|
120
124
|
onBackdropClick(event: any): void;
|
|
121
125
|
onKeydown(event: any): void;
|
|
122
126
|
onAfterEnter(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.vue.d.ts","sourceRoot":"","sources":["../../../components/Modal/Modal.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Modal.vue.d.ts","sourceRoot":"","sources":["../../../components/Modal/Modal.vue"],"names":[],"mappings":"AAoIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA+kBA,GAriBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAqiBH,GAriBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BA6iBuG,gBAAgB"}
|
|
@@ -16,6 +16,10 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
16
16
|
type: ArrayConstructor;
|
|
17
17
|
default: () => number[];
|
|
18
18
|
};
|
|
19
|
+
showArrow: {
|
|
20
|
+
type: BooleanConstructor;
|
|
21
|
+
default: boolean;
|
|
22
|
+
};
|
|
19
23
|
placement: {
|
|
20
24
|
type: StringConstructor;
|
|
21
25
|
default: string;
|
|
@@ -90,7 +94,9 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
90
94
|
internalShow: boolean;
|
|
91
95
|
currentPlacement: string;
|
|
92
96
|
}, {
|
|
97
|
+
tippyArrow(): false | "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"7\"><path d=\"M 14.5,7 8,0 1.5,7 Z\"/></svg>";
|
|
93
98
|
tippyProps(): {
|
|
99
|
+
arrow: string | boolean;
|
|
94
100
|
offset: unknown[];
|
|
95
101
|
delay: number | boolean;
|
|
96
102
|
placement: string;
|
|
@@ -144,7 +150,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
144
150
|
tooltipHasContent(tooltipInstance: any): boolean;
|
|
145
151
|
initOptions(): {
|
|
146
152
|
content: unknown;
|
|
147
|
-
arrow: string;
|
|
153
|
+
arrow: string | boolean;
|
|
148
154
|
duration: number;
|
|
149
155
|
interactive: boolean;
|
|
150
156
|
trigger: string;
|
|
@@ -223,6 +229,10 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
223
229
|
type: ArrayConstructor;
|
|
224
230
|
default: () => number[];
|
|
225
231
|
};
|
|
232
|
+
showArrow: {
|
|
233
|
+
type: BooleanConstructor;
|
|
234
|
+
default: boolean;
|
|
235
|
+
};
|
|
226
236
|
placement: {
|
|
227
237
|
type: StringConstructor;
|
|
228
238
|
default: string;
|
|
@@ -302,6 +312,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
302
312
|
theme: string;
|
|
303
313
|
fallbackPlacements: unknown[];
|
|
304
314
|
enabled: boolean;
|
|
315
|
+
showArrow: boolean;
|
|
305
316
|
transition: boolean;
|
|
306
317
|
externalAnchor: string;
|
|
307
318
|
externalAnchorElement: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.vue.d.ts","sourceRoot":"","sources":["../../../components/Tooltip/Tooltip.vue"],"names":[],"mappings":"AA2CA
|
|
1
|
+
{"version":3,"file":"Tooltip.vue.d.ts","sourceRoot":"","sources":["../../../components/Tooltip/Tooltip.vue"],"names":[],"mappings":"AA2CA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAmmB+F,gBAAgB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}}),require(`../../chunk-Bmb41Sf3.cjs`);const e=require(`../../common/constants/index.cjs`),t=require(`../../common/utils/index.cjs`),n=require(`../../mode_constants-CzYJW9ua.cjs`),r=require(`../tooltip/tooltip-constants.cjs`),i=require(`../popover/popover-constants.cjs`),a=require(`../popover/popover.cjs`);let o=require(`vue`);var s=Object.assign({name:`DtHovercard`},{__name:`Hovercard`,props:{contentMode:n.t,transition:{type:Boolean,default:!1},open:{type:Boolean,default:null},fallbackPlacements:{type:Array,default:()=>[`auto`]},placement:{type:String,default:`top-start`,validator(e){return r.TOOLTIP_DIRECTIONS.includes(e)}},padding:{type:String,default:`large`,validator:e=>Object.keys(i.POPOVER_PADDING_CLASSES).some(t=>t===e)},offset:{type:Array,default:()=>[0,16]},id:{type:String,default(){return t.getUniqueString()}},anchorClass:{type:[String,Array,Object],default:``},headerClass:{type:[String,Array,Object],default:``},footerClass:{type:[String,Array,Object],default:``},dialogClass:{type:[String,Array,Object],default:``},contentClass:{type:[String,Array,Object],default:``},appendTo:{type:[e.HTML_ELEMENT_TYPE,String],default:`body`,validator:e=>i.POPOVER_APPEND_TO_VALUES.includes(e)||e instanceof HTMLElement},enterDelay:{type:Number,default:300},leaveDelay:{type:Number,default:300},externalAnchorElement:{type:e.HTML_ELEMENT_TYPE,default:null}},emits:[`opened`],setup(e,{expose:t}){let n=e,r=(0,o.ref)(n.open),i=(0,o.ref)(!1),s=(0,o.ref)(!1),c=(0,o.ref)(null),l=(0,o.ref)(null),u=(0,o.ref)(null),d=(0,o.ref)(null),f=(0,o.ref)(null);(0,o.onMounted)(()=>{(0,o.nextTick)(()=>{u.value=f.value?.$refs?.anchor?.firstElementChild,d.value=new MutationObserver(()=>{u.value&&!u.value.isConnected&&(r.value=!1)}),d.value.observe(document.body,{childList:!0,subtree:!0})})}),(0,o.onBeforeUnmount)(()=>{d.value&&d.value.disconnect(),clearTimeout(c),clearTimeout(l)}),(0,o.watch)(()=>n.open,e=>{r.value=e},{immediate:!0}),t({show:h,hide:g});function p(){n.open===null&&(clearTimeout(l.value),c.value=setTimeout(()=>{r.value=!0},n.enterDelay))}function m(){n.open===null&&(clearTimeout(c.value),l.value=setTimeout(()=>{r.value=!1},n.leaveDelay))}function h(){s.value=!0,p()}function g(){s.value=!1,!i.value&&m()}function _(){i.value=!0,p()}function v(){i.value=!1,s.value||m()}return(t,n)=>((0,o.openBlock)(),(0,o.createBlock)((0,o.unref)(a.default),{id:e.id,ref_key:`popover`,ref:f,open:r.value,placement:e.placement,"content-class":e.contentClass,"content-mode":e.contentMode,"dialog-class":e.dialogClass,"fallback-placements":e.fallbackPlacements,padding:e.padding,transition:e.transition?`fade`:null,offset:e.offset,modal:!1,focustrap:r.value,"initial-focus-element":`none`,"header-class":e.headerClass,"footer-class":e.footerClass,"append-to":e.appendTo,"anchor-class":e.anchorClass,"external-anchor-element":e.externalAnchorElement,"data-qa":`dt-hovercard`,"enter-delay":e.enterDelay,"leave-delay":e.leaveDelay,onOpened:n[0]||(n[0]=e=>t.$emit(`opened`,e)),onMouseenterPopover:h,onMouseleavePopover:g,onMouseenterPopoverAnchor:h,onMouseleavePopoverAnchor:g},{anchor:(0,o.withCtx)(({attrs:e})=>[(0,o.renderSlot)(t.$slots,`anchor`,(0,o.normalizeProps)((0,o.guardReactiveProps)(e)))]),content:(0,o.withCtx)(()=>[(0,o.createElementVNode)(`div`,{onFocusin:_,onFocusout:v},[(0,o.renderSlot)(t.$slots,`content`)],32)]),headerContent:(0,o.withCtx)(()=>[(0,o.renderSlot)(t.$slots,`headerContent`)]),footerContent:(0,o.withCtx)(()=>[(0,o.renderSlot)(t.$slots,`footerContent`)]),_:3},8,[`id`,`open`,`placement`,`content-class`,`content-mode`,`dialog-class`,`fallback-placements`,`padding`,`transition`,`offset`,`focustrap`,`header-class`,`footer-class`,`append-to`,`anchor-class`,`external-anchor-element`,`enter-delay`,`leave-delay`]))}});exports.default=s;
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}}),require(`../../chunk-Bmb41Sf3.cjs`);const e=require(`../../common/constants/index.cjs`),t=require(`../../common/utils/index.cjs`),n=require(`../../mode_constants-CzYJW9ua.cjs`),r=require(`../tooltip/tooltip-constants.cjs`),i=require(`../popover/popover-constants.cjs`),a=require(`../popover/popover.cjs`);let o=require(`vue`);var s=Object.assign({name:`DtHovercard`},{__name:`Hovercard`,props:{contentMode:n.t,transition:{type:Boolean,default:!1},open:{type:Boolean,default:null},fallbackPlacements:{type:Array,default:()=>[`auto`]},placement:{type:String,default:`top-start`,validator(e){return r.TOOLTIP_DIRECTIONS.includes(e)}},padding:{type:String,default:`large`,validator:e=>Object.keys(i.POPOVER_PADDING_CLASSES).some(t=>t===e)},offset:{type:Array,default:()=>[0,16]},id:{type:String,default(){return t.getUniqueString()}},anchorClass:{type:[String,Array,Object],default:``},headerClass:{type:[String,Array,Object],default:``},footerClass:{type:[String,Array,Object],default:``},dialogClass:{type:[String,Array,Object],default:``},contentClass:{type:[String,Array,Object],default:``},appendTo:{type:[e.HTML_ELEMENT_TYPE,String],default:`body`,validator:e=>i.POPOVER_APPEND_TO_VALUES.includes(e)||e instanceof HTMLElement},enterDelay:{type:Number,default:300},leaveDelay:{type:Number,default:300},externalAnchorElement:{type:e.HTML_ELEMENT_TYPE,default:null}},emits:[`opened`],setup(e,{expose:t}){let n=e,r=(0,o.ref)(n.open),i=(0,o.ref)(!1),s=(0,o.ref)(!1),c=(0,o.ref)(null),l=(0,o.ref)(null),u=(0,o.ref)(null),d=(0,o.ref)(null),f=(0,o.ref)(null);(0,o.onMounted)(()=>{(0,o.nextTick)(()=>{u.value=f.value?.$refs?.anchor?.firstElementChild,d.value=new MutationObserver(()=>{u.value&&!u.value.isConnected&&(clearTimeout(c.value),clearTimeout(l.value),r.value=!1)}),d.value.observe(document.body,{childList:!0,subtree:!0})})}),(0,o.onBeforeUnmount)(()=>{d.value&&d.value.disconnect(),clearTimeout(c.value),clearTimeout(l.value)}),(0,o.watch)(()=>n.open,e=>{r.value=e},{immediate:!0}),t({show:h,hide:g});function p(){n.open===null&&(clearTimeout(l.value),c.value=setTimeout(()=>{r.value=!0},n.enterDelay))}function m(){n.open===null&&(clearTimeout(c.value),l.value=setTimeout(()=>{r.value=!1},n.leaveDelay))}function h(){s.value=!0,p()}function g(){s.value=!1,!i.value&&m()}function _(){i.value=!0,p()}function v(){i.value=!1,s.value||m()}return(t,n)=>((0,o.openBlock)(),(0,o.createBlock)((0,o.unref)(a.default),{id:e.id,ref_key:`popover`,ref:f,open:r.value,placement:e.placement,"content-class":e.contentClass,"content-mode":e.contentMode,"dialog-class":e.dialogClass,"fallback-placements":e.fallbackPlacements,padding:e.padding,transition:e.transition?`fade`:null,offset:e.offset,modal:!1,focustrap:r.value,"initial-focus-element":`none`,"header-class":e.headerClass,"footer-class":e.footerClass,"append-to":e.appendTo,"anchor-class":e.anchorClass,"external-anchor-element":e.externalAnchorElement,"data-qa":`dt-hovercard`,"enter-delay":e.enterDelay,"leave-delay":e.leaveDelay,onOpened:n[0]||(n[0]=e=>t.$emit(`opened`,e)),onMouseenterPopover:h,onMouseleavePopover:g,onMouseenterPopoverAnchor:h,onMouseleavePopoverAnchor:g},{anchor:(0,o.withCtx)(({attrs:e})=>[(0,o.renderSlot)(t.$slots,`anchor`,(0,o.normalizeProps)((0,o.guardReactiveProps)(e)))]),content:(0,o.withCtx)(()=>[(0,o.createElementVNode)(`div`,{onFocusin:_,onFocusout:v},[(0,o.renderSlot)(t.$slots,`content`)],32)]),headerContent:(0,o.withCtx)(()=>[(0,o.renderSlot)(t.$slots,`headerContent`)]),footerContent:(0,o.withCtx)(()=>[(0,o.renderSlot)(t.$slots,`footerContent`)]),_:3},8,[`id`,`open`,`placement`,`content-class`,`content-mode`,`dialog-class`,`fallback-placements`,`padding`,`transition`,`offset`,`focustrap`,`header-class`,`footer-class`,`append-to`,`anchor-class`,`external-anchor-element`,`enter-delay`,`leave-delay`]))}});exports.default=s;
|
|
2
2
|
//# sourceMappingURL=hovercard.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hovercard.cjs","names":["$emit"],"sources":["../../../components/Hovercard/Hovercard.vue"],"sourcesContent":["<!-- eslint-disable vue/multi-word-component-names -->\n<template>\n <dt-popover\n :id=\"id\"\n ref=\"popover\"\n :open=\"hovercardOpen\"\n :placement=\"placement\"\n :content-class=\"contentClass\"\n :content-mode=\"contentMode\"\n :dialog-class=\"dialogClass\"\n :fallback-placements=\"fallbackPlacements\"\n :padding=\"padding\"\n :transition=\"transition ? 'fade' : null\"\n :offset=\"offset\"\n :modal=\"false\"\n :focustrap=\"hovercardOpen\"\n initial-focus-element=\"none\"\n :header-class=\"headerClass\"\n :footer-class=\"footerClass\"\n :append-to=\"appendTo\"\n :anchor-class=\"anchorClass\"\n :external-anchor-element=\"externalAnchorElement\"\n data-qa=\"dt-hovercard\"\n :enter-delay=\"enterDelay\"\n :leave-delay=\"leaveDelay\"\n @opened=\"(e) => ($emit('opened', e))\"\n @mouseenter-popover=\"onMouseEnter\"\n @mouseleave-popover=\"onMouseLeave\"\n @mouseenter-popover-anchor=\"onMouseEnter\"\n @mouseleave-popover-anchor=\"onMouseLeave\"\n >\n <template #anchor=\"{ attrs }\">\n <!-- @slot Anchor element that activates the hovercard. Usually a button. -->\n <slot\n name=\"anchor\"\n v-bind=\"attrs\"\n />\n </template>\n <template #content>\n <div\n @focusin=\"onContentFocusIn\"\n @focusout=\"onContentFocusOut\"\n >\n <!-- @slot Slot for the content that is displayed in the hovercard. -->\n <slot name=\"content\" />\n </div>\n </template>\n <template #headerContent>\n <!-- @slot Slot for hovercard header content -->\n <slot name=\"headerContent\" />\n </template>\n\n <template #footerContent>\n <!-- @slot Slot for the footer content. -->\n <slot name=\"footerContent\" />\n </template>\n </dt-popover>\n</template>\n\n<script setup>\nimport { ref, watch, nextTick, onMounted, onBeforeUnmount } from 'vue';\nimport { POPOVER_APPEND_TO_VALUES, POPOVER_PADDING_CLASSES, DtPopover } from '@/components/Popover/index.js';\nimport { TOOLTIP_DIRECTIONS, TOOLTIP_DELAY_MS } from '@/components/Tooltip/index.js';\nimport { getUniqueString } from '@/common/utils';\nimport { HTML_ELEMENT_TYPE } from '@/common/constants';\nimport { CONTENT_MODE_PROP } from '@/common/mode_constants';\n\ndefineOptions({\n name: 'DtHovercard',\n});\n\nconst props = defineProps({\n /**\n * Applies a color mode to the positioned content element.\n * @values light, dark, invert\n */\n contentMode: CONTENT_MODE_PROP,\n\n /**\n * Fade transition when the content display is toggled.\n * @type boolean\n * @values true, false\n */\n transition: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Controls whether the hovercard is shown. Leaving this null will have the hovercard trigger on hover by default.\n * If you set this value, the default trigger behavior will be disabled, and you can control it as you need.\n * Supports .sync modifier\n * @values null, true, false\n */\n open: {\n type: Boolean,\n default: null,\n },\n\n /**\n * If the popover does not fit in the direction described by \"placement\",\n * it will attempt to change its direction to the \"fallbackPlacements\".\n * @see https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements\"\n */\n fallbackPlacements: {\n type: Array,\n default: () => {\n return ['auto'];\n },\n },\n\n /**\n * The direction the popover displays relative to the anchor.\n * @see https://atomiks.github.io/tippyjs/v6/all-props/#placement\"\n * @values top, top-start, top-end,\n * right, right-start, right-end,\n * left, left-start, left-end,\n * bottom, bottom-start, bottom-end\n */\n placement: {\n type: String,\n default: 'top-start',\n validator (placement) {\n return TOOLTIP_DIRECTIONS.includes(placement);\n },\n },\n\n /**\n * Padding size class for the popover content.\n * @values none, small, medium, large\n */\n padding: {\n type: String,\n default: 'large',\n validator: (padding) => {\n return Object.keys(POPOVER_PADDING_CLASSES).some((item) => item === padding);\n },\n },\n\n /**\n * Displaces the content box from its anchor element\n * by the specified number of pixels.\n * @see https://atomiks.github.io/tippyjs/v6/all-props/#offset\"\n */\n offset: {\n type: Array,\n default: () => [0, 16],\n },\n\n /**\n * The id of the tooltip\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Additional class name for the anchor wrapper element.\n */\n anchorClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the header content wrapper element.\n */\n headerClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the footer content wrapper element.\n */\n footerClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the dialog element.\n */\n dialogClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the content wrapper element.\n */\n contentClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Sets the element to which the popover is going to append to.\n * 'body' will append to the nearest body (supports shadow DOM).\n * @values 'body', 'parent', 'root', HTMLElement,\n */\n appendTo: {\n type: [HTML_ELEMENT_TYPE, String],\n default: 'body',\n validator: appendTo => {\n return POPOVER_APPEND_TO_VALUES.includes(appendTo) ||\n (appendTo instanceof HTMLElement);\n },\n },\n\n /**\n * The enter delay in milliseconds before the hovercard is shown.\n * @type number\n */\n enterDelay: {\n type: Number,\n default: TOOLTIP_DELAY_MS,\n },\n\n /**\n * The leave delay in milliseconds before the hovercard is hidden.\n * @type number\n */\n leaveDelay: {\n type: Number,\n default: TOOLTIP_DELAY_MS,\n },\n\n /**\n * External anchor element reference. Use this instead of the anchor slot when\n * the anchor may be inside a Shadow DOM, as querySelector cannot pierce shadow boundaries.\n */\n externalAnchorElement: {\n type: HTML_ELEMENT_TYPE,\n default: null,\n },\n});\n\ndefineEmits([\n /**\n * Emitted when hovercard is shown or hidden\n *\n * @event opened\n * @type {Boolean | Array}\n */\n 'opened',\n]);\n\nconst hovercardOpen = ref(props.open);\nconst contentFocused = ref(false);\nconst mouseOverHovercard = ref(false);\nconst inTimer = ref(null);\nconst outTimer = ref(null);\nconst anchorEl = ref(null);\nconst observer = ref(null);\nconst popover = ref(null);\n\nonMounted(() => {\n nextTick(() => {\n anchorEl.value = popover.value?.$refs?.anchor?.firstElementChild;\n\n observer.value = new MutationObserver(() => {\n if (anchorEl.value && !anchorEl.value.isConnected) {\n hovercardOpen.value = false;\n }\n });\n\n observer.value.observe(document.body, {\n childList: true,\n subtree: true,\n });\n });\n});\n\nonBeforeUnmount(() => {\n if (observer.value) {\n observer.value.disconnect();\n }\n clearTimeout(inTimer);\n clearTimeout(outTimer);\n});\n\nwatch(() => props.open, (open) => {\n hovercardOpen.value = open;\n}, { immediate: true });\n\ndefineExpose({ show: onMouseEnter, hide: onMouseLeave });\n\nfunction setInTimer () {\n if (props.open === null) {\n clearTimeout(outTimer.value);\n inTimer.value = setTimeout(() => {\n hovercardOpen.value = true;\n }, props.enterDelay);\n }\n}\n\nfunction setOutTimer () {\n if (props.open === null) {\n clearTimeout(inTimer.value);\n outTimer.value = setTimeout(() => {\n hovercardOpen.value = false;\n }, props.leaveDelay);\n }\n}\n\nfunction onMouseEnter () {\n mouseOverHovercard.value = true;\n setInTimer();\n}\n\nfunction onMouseLeave () {\n mouseOverHovercard.value = false;\n if (contentFocused.value) {\n return;\n }\n setOutTimer();\n}\n\nfunction onContentFocusIn () {\n contentFocused.value = true;\n setInTimer();\n}\n\nfunction onContentFocusOut () {\n contentFocused.value = false;\n\n // If mouse is not over the hovercard, close it\n if (!mouseOverHovercard.value) {\n setOutTimer();\n }\n}\n</script>\n"],"mappings":"09CAuEA,IAAM,EAAQ,EAkLR,GAAA,EAAA,EAAA,KAAoB,EAAM,KAAK,CAC/B,GAAA,EAAA,EAAA,KAAqB,GAAM,CAC3B,GAAA,EAAA,EAAA,KAAyB,GAAM,CAC/B,GAAA,EAAA,EAAA,KAAc,KAAK,CACnB,GAAA,EAAA,EAAA,KAAe,KAAK,CACpB,GAAA,EAAA,EAAA,KAAe,KAAK,CACpB,GAAA,EAAA,EAAA,KAAe,KAAK,CACpB,GAAA,EAAA,EAAA,KAAc,KAAK,EAEzB,EAAA,EAAA,eAAgB,EACd,EAAA,EAAA,cAAe,CACb,EAAS,MAAQ,EAAQ,OAAO,OAAO,QAAQ,kBAE/C,EAAS,MAAQ,IAAI,qBAAuB,CACtC,EAAS,OAAS,CAAC,EAAS,MAAM,cACpC,EAAc,MAAQ,KAExB,CAEF,EAAS,MAAM,QAAQ,SAAS,KAAM,CACpC,UAAW,GACX,QAAS,GACV,CAAC,EACF,EACF,EAEF,EAAA,EAAA,qBAAsB,CAChB,EAAS,OACX,EAAS,MAAM,YAAY,CAE7B,aAAa,EAAQ,CACrB,aAAa,EAAS,EACtB,EAEF,EAAA,EAAA,WAAY,EAAM,KAAO,GAAS,CAChC,EAAc,MAAQ,GACrB,CAAE,UAAW,GAAM,CAAC,CAEvB,EAAa,CAAE,KAAM,EAAc,KAAM,EAAc,CAAC,CAExD,SAAS,GAAc,CACjB,EAAM,OAAS,OACjB,aAAa,EAAS,MAAM,CAC5B,EAAQ,MAAQ,eAAiB,CAC/B,EAAc,MAAQ,IACrB,EAAM,WAAW,EAIxB,SAAS,GAAe,CAClB,EAAM,OAAS,OACjB,aAAa,EAAQ,MAAM,CAC3B,EAAS,MAAQ,eAAiB,CAChC,EAAc,MAAQ,IACrB,EAAM,WAAW,EAIxB,SAAS,GAAgB,CACvB,EAAmB,MAAQ,GAC3B,GAAY,CAGd,SAAS,GAAgB,CACvB,EAAmB,MAAQ,GACvB,GAAe,OAGnB,GAAa,CAGf,SAAS,GAAoB,CAC3B,EAAe,MAAQ,GACvB,GAAY,CAGd,SAAS,GAAqB,CAC5B,EAAe,MAAQ,GAGlB,EAAmB,OACtB,GAAa,+DAlRF,EAAA,QAAA,CAAA,CArDV,GAAI,EAAA,WACD,UAAJ,IAAI,EACH,KAAM,EAAA,MACN,UAAW,EAAA,UACX,gBAAe,EAAA,aACf,eAAc,EAAA,YACd,eAAc,EAAA,YACd,sBAAqB,EAAA,mBACrB,QAAS,EAAA,QACT,WAAY,EAAA,WAAU,OAAA,KACtB,OAAQ,EAAA,OACR,MAAO,GACP,UAAW,EAAA,MACZ,wBAAsB,OACrB,eAAc,EAAA,YACd,eAAc,EAAA,YACd,YAAW,EAAA,SACX,eAAc,EAAA,YACd,0BAAyB,EAAA,sBAC1B,UAAQ,eACP,cAAa,EAAA,WACb,cAAa,EAAA,WACb,SAAM,EAAA,KAAA,EAAA,GAAG,GAAOA,EAAAA,MAAK,SAAW,EAAC,EACjC,oBAAoB,EACpB,oBAAoB,EACpB,0BAA2B,EAC3B,0BAA2B,IAEjB,QAAA,EAAA,EAAA,UAKP,CALiB,WAAK,EAAA,EAAA,EAAA,YAKtB,EAAA,OAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,EAAA,oBADQ,EAAK,CAAA,CAAA,CAAA,CAAA,CAGN,SAAA,EAAA,EAAA,aAOH,EAAA,EAAA,EAAA,oBAAA,MAAA,CALH,UAAS,EACT,WAAU,qBAGY,EAAA,OAAA,UAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAGhB,eAAA,EAAA,EAAA,aAEoB,EAAA,EAAA,EAAA,YAAA,EAAA,OAAA,gBAAA,CAAA,CAAA,CAGpB,eAAA,EAAA,EAAA,aAEoB,EAAA,EAAA,EAAA,YAAA,EAAA,OAAA,gBAAA,CAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"hovercard.cjs","names":["$emit"],"sources":["../../../components/Hovercard/Hovercard.vue"],"sourcesContent":["<!-- eslint-disable vue/multi-word-component-names -->\n<template>\n <dt-popover\n :id=\"id\"\n ref=\"popover\"\n :open=\"hovercardOpen\"\n :placement=\"placement\"\n :content-class=\"contentClass\"\n :content-mode=\"contentMode\"\n :dialog-class=\"dialogClass\"\n :fallback-placements=\"fallbackPlacements\"\n :padding=\"padding\"\n :transition=\"transition ? 'fade' : null\"\n :offset=\"offset\"\n :modal=\"false\"\n :focustrap=\"hovercardOpen\"\n initial-focus-element=\"none\"\n :header-class=\"headerClass\"\n :footer-class=\"footerClass\"\n :append-to=\"appendTo\"\n :anchor-class=\"anchorClass\"\n :external-anchor-element=\"externalAnchorElement\"\n data-qa=\"dt-hovercard\"\n :enter-delay=\"enterDelay\"\n :leave-delay=\"leaveDelay\"\n @opened=\"(e) => ($emit('opened', e))\"\n @mouseenter-popover=\"onMouseEnter\"\n @mouseleave-popover=\"onMouseLeave\"\n @mouseenter-popover-anchor=\"onMouseEnter\"\n @mouseleave-popover-anchor=\"onMouseLeave\"\n >\n <template #anchor=\"{ attrs }\">\n <!-- @slot Anchor element that activates the hovercard. Usually a button. -->\n <slot\n name=\"anchor\"\n v-bind=\"attrs\"\n />\n </template>\n <template #content>\n <div\n @focusin=\"onContentFocusIn\"\n @focusout=\"onContentFocusOut\"\n >\n <!-- @slot Slot for the content that is displayed in the hovercard. -->\n <slot name=\"content\" />\n </div>\n </template>\n <template #headerContent>\n <!-- @slot Slot for hovercard header content -->\n <slot name=\"headerContent\" />\n </template>\n\n <template #footerContent>\n <!-- @slot Slot for the footer content. -->\n <slot name=\"footerContent\" />\n </template>\n </dt-popover>\n</template>\n\n<script setup>\nimport { ref, watch, nextTick, onMounted, onBeforeUnmount } from 'vue';\nimport { POPOVER_APPEND_TO_VALUES, POPOVER_PADDING_CLASSES, DtPopover } from '@/components/Popover/index.js';\nimport { TOOLTIP_DIRECTIONS, TOOLTIP_DELAY_MS } from '@/components/Tooltip/index.js';\nimport { getUniqueString } from '@/common/utils';\nimport { HTML_ELEMENT_TYPE } from '@/common/constants';\nimport { CONTENT_MODE_PROP } from '@/common/mode_constants';\n\ndefineOptions({\n name: 'DtHovercard',\n});\n\nconst props = defineProps({\n /**\n * Applies a color mode to the positioned content element.\n * @values light, dark, invert\n */\n contentMode: CONTENT_MODE_PROP,\n\n /**\n * Fade transition when the content display is toggled.\n * @type boolean\n * @values true, false\n */\n transition: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Controls whether the hovercard is shown. Leaving this null will have the hovercard trigger on hover by default.\n * If you set this value, the default trigger behavior will be disabled, and you can control it as you need.\n * Supports .sync modifier\n * @values null, true, false\n */\n open: {\n type: Boolean,\n default: null,\n },\n\n /**\n * If the popover does not fit in the direction described by \"placement\",\n * it will attempt to change its direction to the \"fallbackPlacements\".\n * @see https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements\"\n */\n fallbackPlacements: {\n type: Array,\n default: () => {\n return ['auto'];\n },\n },\n\n /**\n * The direction the popover displays relative to the anchor.\n * @see https://atomiks.github.io/tippyjs/v6/all-props/#placement\"\n * @values top, top-start, top-end,\n * right, right-start, right-end,\n * left, left-start, left-end,\n * bottom, bottom-start, bottom-end\n */\n placement: {\n type: String,\n default: 'top-start',\n validator (placement) {\n return TOOLTIP_DIRECTIONS.includes(placement);\n },\n },\n\n /**\n * Padding size class for the popover content.\n * @values none, small, medium, large\n */\n padding: {\n type: String,\n default: 'large',\n validator: (padding) => {\n return Object.keys(POPOVER_PADDING_CLASSES).some((item) => item === padding);\n },\n },\n\n /**\n * Displaces the content box from its anchor element\n * by the specified number of pixels.\n * @see https://atomiks.github.io/tippyjs/v6/all-props/#offset\"\n */\n offset: {\n type: Array,\n default: () => [0, 16],\n },\n\n /**\n * The id of the tooltip\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Additional class name for the anchor wrapper element.\n */\n anchorClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the header content wrapper element.\n */\n headerClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the footer content wrapper element.\n */\n footerClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the dialog element.\n */\n dialogClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the content wrapper element.\n */\n contentClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Sets the element to which the popover is going to append to.\n * 'body' will append to the nearest body (supports shadow DOM).\n * @values 'body', 'parent', 'root', HTMLElement,\n */\n appendTo: {\n type: [HTML_ELEMENT_TYPE, String],\n default: 'body',\n validator: appendTo => {\n return POPOVER_APPEND_TO_VALUES.includes(appendTo) ||\n (appendTo instanceof HTMLElement);\n },\n },\n\n /**\n * The enter delay in milliseconds before the hovercard is shown.\n * @type number\n */\n enterDelay: {\n type: Number,\n default: TOOLTIP_DELAY_MS,\n },\n\n /**\n * The leave delay in milliseconds before the hovercard is hidden.\n * @type number\n */\n leaveDelay: {\n type: Number,\n default: TOOLTIP_DELAY_MS,\n },\n\n /**\n * External anchor element reference. Use this instead of the anchor slot when\n * the anchor may be inside a Shadow DOM, as querySelector cannot pierce shadow boundaries.\n */\n externalAnchorElement: {\n type: HTML_ELEMENT_TYPE,\n default: null,\n },\n});\n\ndefineEmits([\n /**\n * Emitted when hovercard is shown or hidden\n *\n * @event opened\n * @type {Boolean | Array}\n */\n 'opened',\n]);\n\nconst hovercardOpen = ref(props.open);\nconst contentFocused = ref(false);\nconst mouseOverHovercard = ref(false);\nconst inTimer = ref(null);\nconst outTimer = ref(null);\nconst anchorEl = ref(null);\nconst observer = ref(null);\nconst popover = ref(null);\n\nonMounted(() => {\n nextTick(() => {\n anchorEl.value = popover.value?.$refs?.anchor?.firstElementChild;\n\n observer.value = new MutationObserver(() => {\n if (anchorEl.value && !anchorEl.value.isConnected) {\n clearTimeout(inTimer.value);\n clearTimeout(outTimer.value);\n hovercardOpen.value = false;\n }\n });\n\n observer.value.observe(document.body, {\n childList: true,\n subtree: true,\n });\n });\n});\n\nonBeforeUnmount(() => {\n if (observer.value) {\n observer.value.disconnect();\n }\n clearTimeout(inTimer.value);\n clearTimeout(outTimer.value);\n});\n\nwatch(() => props.open, (open) => {\n hovercardOpen.value = open;\n}, { immediate: true });\n\ndefineExpose({ show: onMouseEnter, hide: onMouseLeave });\n\nfunction setInTimer () {\n if (props.open === null) {\n clearTimeout(outTimer.value);\n inTimer.value = setTimeout(() => {\n hovercardOpen.value = true;\n }, props.enterDelay);\n }\n}\n\nfunction setOutTimer () {\n if (props.open === null) {\n clearTimeout(inTimer.value);\n outTimer.value = setTimeout(() => {\n hovercardOpen.value = false;\n }, props.leaveDelay);\n }\n}\n\nfunction onMouseEnter () {\n mouseOverHovercard.value = true;\n setInTimer();\n}\n\nfunction onMouseLeave () {\n mouseOverHovercard.value = false;\n if (contentFocused.value) {\n return;\n }\n setOutTimer();\n}\n\nfunction onContentFocusIn () {\n contentFocused.value = true;\n setInTimer();\n}\n\nfunction onContentFocusOut () {\n contentFocused.value = false;\n\n // If mouse is not over the hovercard, close it\n if (!mouseOverHovercard.value) {\n setOutTimer();\n }\n}\n</script>\n"],"mappings":"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"}
|
|
@@ -108,14 +108,14 @@ var b = /* @__PURE__ */ Object.assign({ name: "DtHovercard" }, {
|
|
|
108
108
|
p(() => {
|
|
109
109
|
u(() => {
|
|
110
110
|
S.value = w.value?.$refs?.anchor?.firstElementChild, C.value = new MutationObserver(() => {
|
|
111
|
-
S.value && !S.value.isConnected && (r.value = !1);
|
|
111
|
+
S.value && !S.value.isConnected && (clearTimeout(b.value), clearTimeout(x.value), r.value = !1);
|
|
112
112
|
}), C.value.observe(document.body, {
|
|
113
113
|
childList: !0,
|
|
114
114
|
subtree: !0
|
|
115
115
|
});
|
|
116
116
|
});
|
|
117
117
|
}), f(() => {
|
|
118
|
-
C.value && C.value.disconnect(), clearTimeout(b), clearTimeout(x);
|
|
118
|
+
C.value && C.value.disconnect(), clearTimeout(b.value), clearTimeout(x.value);
|
|
119
119
|
}), v(() => n.open, (e) => {
|
|
120
120
|
r.value = e;
|
|
121
121
|
}, { immediate: !0 }), t({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hovercard.js","names":["$emit"],"sources":["../../../components/Hovercard/Hovercard.vue"],"sourcesContent":["<!-- eslint-disable vue/multi-word-component-names -->\n<template>\n <dt-popover\n :id=\"id\"\n ref=\"popover\"\n :open=\"hovercardOpen\"\n :placement=\"placement\"\n :content-class=\"contentClass\"\n :content-mode=\"contentMode\"\n :dialog-class=\"dialogClass\"\n :fallback-placements=\"fallbackPlacements\"\n :padding=\"padding\"\n :transition=\"transition ? 'fade' : null\"\n :offset=\"offset\"\n :modal=\"false\"\n :focustrap=\"hovercardOpen\"\n initial-focus-element=\"none\"\n :header-class=\"headerClass\"\n :footer-class=\"footerClass\"\n :append-to=\"appendTo\"\n :anchor-class=\"anchorClass\"\n :external-anchor-element=\"externalAnchorElement\"\n data-qa=\"dt-hovercard\"\n :enter-delay=\"enterDelay\"\n :leave-delay=\"leaveDelay\"\n @opened=\"(e) => ($emit('opened', e))\"\n @mouseenter-popover=\"onMouseEnter\"\n @mouseleave-popover=\"onMouseLeave\"\n @mouseenter-popover-anchor=\"onMouseEnter\"\n @mouseleave-popover-anchor=\"onMouseLeave\"\n >\n <template #anchor=\"{ attrs }\">\n <!-- @slot Anchor element that activates the hovercard. Usually a button. -->\n <slot\n name=\"anchor\"\n v-bind=\"attrs\"\n />\n </template>\n <template #content>\n <div\n @focusin=\"onContentFocusIn\"\n @focusout=\"onContentFocusOut\"\n >\n <!-- @slot Slot for the content that is displayed in the hovercard. -->\n <slot name=\"content\" />\n </div>\n </template>\n <template #headerContent>\n <!-- @slot Slot for hovercard header content -->\n <slot name=\"headerContent\" />\n </template>\n\n <template #footerContent>\n <!-- @slot Slot for the footer content. -->\n <slot name=\"footerContent\" />\n </template>\n </dt-popover>\n</template>\n\n<script setup>\nimport { ref, watch, nextTick, onMounted, onBeforeUnmount } from 'vue';\nimport { POPOVER_APPEND_TO_VALUES, POPOVER_PADDING_CLASSES, DtPopover } from '@/components/Popover/index.js';\nimport { TOOLTIP_DIRECTIONS, TOOLTIP_DELAY_MS } from '@/components/Tooltip/index.js';\nimport { getUniqueString } from '@/common/utils';\nimport { HTML_ELEMENT_TYPE } from '@/common/constants';\nimport { CONTENT_MODE_PROP } from '@/common/mode_constants';\n\ndefineOptions({\n name: 'DtHovercard',\n});\n\nconst props = defineProps({\n /**\n * Applies a color mode to the positioned content element.\n * @values light, dark, invert\n */\n contentMode: CONTENT_MODE_PROP,\n\n /**\n * Fade transition when the content display is toggled.\n * @type boolean\n * @values true, false\n */\n transition: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Controls whether the hovercard is shown. Leaving this null will have the hovercard trigger on hover by default.\n * If you set this value, the default trigger behavior will be disabled, and you can control it as you need.\n * Supports .sync modifier\n * @values null, true, false\n */\n open: {\n type: Boolean,\n default: null,\n },\n\n /**\n * If the popover does not fit in the direction described by \"placement\",\n * it will attempt to change its direction to the \"fallbackPlacements\".\n * @see https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements\"\n */\n fallbackPlacements: {\n type: Array,\n default: () => {\n return ['auto'];\n },\n },\n\n /**\n * The direction the popover displays relative to the anchor.\n * @see https://atomiks.github.io/tippyjs/v6/all-props/#placement\"\n * @values top, top-start, top-end,\n * right, right-start, right-end,\n * left, left-start, left-end,\n * bottom, bottom-start, bottom-end\n */\n placement: {\n type: String,\n default: 'top-start',\n validator (placement) {\n return TOOLTIP_DIRECTIONS.includes(placement);\n },\n },\n\n /**\n * Padding size class for the popover content.\n * @values none, small, medium, large\n */\n padding: {\n type: String,\n default: 'large',\n validator: (padding) => {\n return Object.keys(POPOVER_PADDING_CLASSES).some((item) => item === padding);\n },\n },\n\n /**\n * Displaces the content box from its anchor element\n * by the specified number of pixels.\n * @see https://atomiks.github.io/tippyjs/v6/all-props/#offset\"\n */\n offset: {\n type: Array,\n default: () => [0, 16],\n },\n\n /**\n * The id of the tooltip\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Additional class name for the anchor wrapper element.\n */\n anchorClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the header content wrapper element.\n */\n headerClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the footer content wrapper element.\n */\n footerClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the dialog element.\n */\n dialogClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the content wrapper element.\n */\n contentClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Sets the element to which the popover is going to append to.\n * 'body' will append to the nearest body (supports shadow DOM).\n * @values 'body', 'parent', 'root', HTMLElement,\n */\n appendTo: {\n type: [HTML_ELEMENT_TYPE, String],\n default: 'body',\n validator: appendTo => {\n return POPOVER_APPEND_TO_VALUES.includes(appendTo) ||\n (appendTo instanceof HTMLElement);\n },\n },\n\n /**\n * The enter delay in milliseconds before the hovercard is shown.\n * @type number\n */\n enterDelay: {\n type: Number,\n default: TOOLTIP_DELAY_MS,\n },\n\n /**\n * The leave delay in milliseconds before the hovercard is hidden.\n * @type number\n */\n leaveDelay: {\n type: Number,\n default: TOOLTIP_DELAY_MS,\n },\n\n /**\n * External anchor element reference. Use this instead of the anchor slot when\n * the anchor may be inside a Shadow DOM, as querySelector cannot pierce shadow boundaries.\n */\n externalAnchorElement: {\n type: HTML_ELEMENT_TYPE,\n default: null,\n },\n});\n\ndefineEmits([\n /**\n * Emitted when hovercard is shown or hidden\n *\n * @event opened\n * @type {Boolean | Array}\n */\n 'opened',\n]);\n\nconst hovercardOpen = ref(props.open);\nconst contentFocused = ref(false);\nconst mouseOverHovercard = ref(false);\nconst inTimer = ref(null);\nconst outTimer = ref(null);\nconst anchorEl = ref(null);\nconst observer = ref(null);\nconst popover = ref(null);\n\nonMounted(() => {\n nextTick(() => {\n anchorEl.value = popover.value?.$refs?.anchor?.firstElementChild;\n\n observer.value = new MutationObserver(() => {\n if (anchorEl.value && !anchorEl.value.isConnected) {\n hovercardOpen.value = false;\n }\n });\n\n observer.value.observe(document.body, {\n childList: true,\n subtree: true,\n });\n });\n});\n\nonBeforeUnmount(() => {\n if (observer.value) {\n observer.value.disconnect();\n }\n clearTimeout(inTimer);\n clearTimeout(outTimer);\n});\n\nwatch(() => props.open, (open) => {\n hovercardOpen.value = open;\n}, { immediate: true });\n\ndefineExpose({ show: onMouseEnter, hide: onMouseLeave });\n\nfunction setInTimer () {\n if (props.open === null) {\n clearTimeout(outTimer.value);\n inTimer.value = setTimeout(() => {\n hovercardOpen.value = true;\n }, props.enterDelay);\n }\n}\n\nfunction setOutTimer () {\n if (props.open === null) {\n clearTimeout(inTimer.value);\n outTimer.value = setTimeout(() => {\n hovercardOpen.value = false;\n }, props.leaveDelay);\n }\n}\n\nfunction onMouseEnter () {\n mouseOverHovercard.value = true;\n setInTimer();\n}\n\nfunction onMouseLeave () {\n mouseOverHovercard.value = false;\n if (contentFocused.value) {\n return;\n }\n setOutTimer();\n}\n\nfunction onContentFocusIn () {\n contentFocused.value = true;\n setInTimer();\n}\n\nfunction onContentFocusOut () {\n contentFocused.value = false;\n\n // If mouse is not over the hovercard, close it\n if (!mouseOverHovercard.value) {\n setOutTimer();\n }\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuEA,IAAM,IAAQ,GAkLR,IAAgB,EAAI,EAAM,KAAK,EAC/B,IAAiB,EAAI,GAAM,EAC3B,IAAqB,EAAI,GAAM,EAC/B,IAAU,EAAI,KAAK,EACnB,IAAW,EAAI,KAAK,EACpB,IAAW,EAAI,KAAK,EACpB,IAAW,EAAI,KAAK,EACpB,IAAU,EAAI,KAAK;AA+BzB,EA7BA,QAAgB;AACd,WAAe;AASb,IARA,EAAS,QAAQ,EAAQ,OAAO,OAAO,QAAQ,mBAE/C,EAAS,QAAQ,IAAI,uBAAuB;AAC1C,KAAI,EAAS,SAAS,CAAC,EAAS,MAAM,gBACpC,EAAc,QAAQ;MAExB,EAEF,EAAS,MAAM,QAAQ,SAAS,MAAM;KACpC,WAAW;KACX,SAAS;KACV,CAAC;KACF;IACF,EAEF,QAAsB;AAKpB,GAJI,EAAS,SACX,EAAS,MAAM,YAAY,EAE7B,aAAa,EAAQ,EACrB,aAAa,EAAS;IACtB,EAEF,QAAY,EAAM,OAAO,MAAS;AAChC,KAAc,QAAQ;KACrB,EAAE,WAAW,IAAM,CAAC,EAEvB,EAAa;GAAE,MAAM;GAAc,MAAM;GAAc,CAAC;EAExD,SAAS,IAAc;AACrB,GAAI,EAAM,SAAS,SACjB,aAAa,EAAS,MAAM,EAC5B,EAAQ,QAAQ,iBAAiB;AAC/B,MAAc,QAAQ;MACrB,EAAM,WAAW;;EAIxB,SAAS,IAAe;AACtB,GAAI,EAAM,SAAS,SACjB,aAAa,EAAQ,MAAM,EAC3B,EAAS,QAAQ,iBAAiB;AAChC,MAAc,QAAQ;MACrB,EAAM,WAAW;;EAIxB,SAAS,IAAgB;AAEvB,GADA,EAAmB,QAAQ,IAC3B,GAAY;;EAGd,SAAS,IAAgB;AACvB,KAAmB,QAAQ,IACvB,GAAe,SAGnB,GAAa;;EAGf,SAAS,IAAoB;AAE3B,GADA,EAAe,QAAQ,IACvB,GAAY;;EAGd,SAAS,IAAqB;AAI5B,GAHA,EAAe,QAAQ,IAGlB,EAAmB,SACtB,GAAa;;yBAxUf,EAsDa,EAAA,EAAA,EAAA;GArDV,IAAI,EAAA;YACD;GAAJ,KAAI;GACH,MAAM,EAAA;GACN,WAAW,EAAA;GACX,iBAAe,EAAA;GACf,gBAAc,EAAA;GACd,gBAAc,EAAA;GACd,uBAAqB,EAAA;GACrB,SAAS,EAAA;GACT,YAAY,EAAA,aAAU,SAAA;GACtB,QAAQ,EAAA;GACR,OAAO;GACP,WAAW,EAAA;GACZ,yBAAsB;GACrB,gBAAc,EAAA;GACd,gBAAc,EAAA;GACd,aAAW,EAAA;GACX,gBAAc,EAAA;GACd,2BAAyB,EAAA;GAC1B,WAAQ;GACP,eAAa,EAAA;GACb,eAAa,EAAA;GACb,UAAM,EAAA,OAAA,EAAA,MAAG,MAAOA,EAAAA,MAAK,UAAW,EAAC;GACjC,qBAAoB;GACpB,qBAAoB;GACpB,2BAA2B;GAC3B,2BAA2B;;GAEjB,QAAM,GAKb,EALiB,eAAK,CAExB,EAGE,EAAA,QAAA,UAAA,EAAA,EADQ,EAAK,CAAA,CAAA,CAAA,CAAA;GAGN,SAAO,QAOV,CANN,EAMM,OAAA;IALH,WAAS;IACT,YAAU;OAGX,EAAuB,EAAA,QAAA,UAAA,CAAA,EAAA,GAAA,CAAA,CAAA;GAGhB,eAAa,QAEO,CAA7B,EAA6B,EAAA,QAAA,gBAAA,CAAA,CAAA;GAGpB,eAAa,QAEO,CAA7B,EAA6B,EAAA,QAAA,gBAAA,CAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"hovercard.js","names":["$emit"],"sources":["../../../components/Hovercard/Hovercard.vue"],"sourcesContent":["<!-- eslint-disable vue/multi-word-component-names -->\n<template>\n <dt-popover\n :id=\"id\"\n ref=\"popover\"\n :open=\"hovercardOpen\"\n :placement=\"placement\"\n :content-class=\"contentClass\"\n :content-mode=\"contentMode\"\n :dialog-class=\"dialogClass\"\n :fallback-placements=\"fallbackPlacements\"\n :padding=\"padding\"\n :transition=\"transition ? 'fade' : null\"\n :offset=\"offset\"\n :modal=\"false\"\n :focustrap=\"hovercardOpen\"\n initial-focus-element=\"none\"\n :header-class=\"headerClass\"\n :footer-class=\"footerClass\"\n :append-to=\"appendTo\"\n :anchor-class=\"anchorClass\"\n :external-anchor-element=\"externalAnchorElement\"\n data-qa=\"dt-hovercard\"\n :enter-delay=\"enterDelay\"\n :leave-delay=\"leaveDelay\"\n @opened=\"(e) => ($emit('opened', e))\"\n @mouseenter-popover=\"onMouseEnter\"\n @mouseleave-popover=\"onMouseLeave\"\n @mouseenter-popover-anchor=\"onMouseEnter\"\n @mouseleave-popover-anchor=\"onMouseLeave\"\n >\n <template #anchor=\"{ attrs }\">\n <!-- @slot Anchor element that activates the hovercard. Usually a button. -->\n <slot\n name=\"anchor\"\n v-bind=\"attrs\"\n />\n </template>\n <template #content>\n <div\n @focusin=\"onContentFocusIn\"\n @focusout=\"onContentFocusOut\"\n >\n <!-- @slot Slot for the content that is displayed in the hovercard. -->\n <slot name=\"content\" />\n </div>\n </template>\n <template #headerContent>\n <!-- @slot Slot for hovercard header content -->\n <slot name=\"headerContent\" />\n </template>\n\n <template #footerContent>\n <!-- @slot Slot for the footer content. -->\n <slot name=\"footerContent\" />\n </template>\n </dt-popover>\n</template>\n\n<script setup>\nimport { ref, watch, nextTick, onMounted, onBeforeUnmount } from 'vue';\nimport { POPOVER_APPEND_TO_VALUES, POPOVER_PADDING_CLASSES, DtPopover } from '@/components/Popover/index.js';\nimport { TOOLTIP_DIRECTIONS, TOOLTIP_DELAY_MS } from '@/components/Tooltip/index.js';\nimport { getUniqueString } from '@/common/utils';\nimport { HTML_ELEMENT_TYPE } from '@/common/constants';\nimport { CONTENT_MODE_PROP } from '@/common/mode_constants';\n\ndefineOptions({\n name: 'DtHovercard',\n});\n\nconst props = defineProps({\n /**\n * Applies a color mode to the positioned content element.\n * @values light, dark, invert\n */\n contentMode: CONTENT_MODE_PROP,\n\n /**\n * Fade transition when the content display is toggled.\n * @type boolean\n * @values true, false\n */\n transition: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Controls whether the hovercard is shown. Leaving this null will have the hovercard trigger on hover by default.\n * If you set this value, the default trigger behavior will be disabled, and you can control it as you need.\n * Supports .sync modifier\n * @values null, true, false\n */\n open: {\n type: Boolean,\n default: null,\n },\n\n /**\n * If the popover does not fit in the direction described by \"placement\",\n * it will attempt to change its direction to the \"fallbackPlacements\".\n * @see https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements\"\n */\n fallbackPlacements: {\n type: Array,\n default: () => {\n return ['auto'];\n },\n },\n\n /**\n * The direction the popover displays relative to the anchor.\n * @see https://atomiks.github.io/tippyjs/v6/all-props/#placement\"\n * @values top, top-start, top-end,\n * right, right-start, right-end,\n * left, left-start, left-end,\n * bottom, bottom-start, bottom-end\n */\n placement: {\n type: String,\n default: 'top-start',\n validator (placement) {\n return TOOLTIP_DIRECTIONS.includes(placement);\n },\n },\n\n /**\n * Padding size class for the popover content.\n * @values none, small, medium, large\n */\n padding: {\n type: String,\n default: 'large',\n validator: (padding) => {\n return Object.keys(POPOVER_PADDING_CLASSES).some((item) => item === padding);\n },\n },\n\n /**\n * Displaces the content box from its anchor element\n * by the specified number of pixels.\n * @see https://atomiks.github.io/tippyjs/v6/all-props/#offset\"\n */\n offset: {\n type: Array,\n default: () => [0, 16],\n },\n\n /**\n * The id of the tooltip\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Additional class name for the anchor wrapper element.\n */\n anchorClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the header content wrapper element.\n */\n headerClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the footer content wrapper element.\n */\n footerClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the dialog element.\n */\n dialogClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Additional class name for the content wrapper element.\n */\n contentClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Sets the element to which the popover is going to append to.\n * 'body' will append to the nearest body (supports shadow DOM).\n * @values 'body', 'parent', 'root', HTMLElement,\n */\n appendTo: {\n type: [HTML_ELEMENT_TYPE, String],\n default: 'body',\n validator: appendTo => {\n return POPOVER_APPEND_TO_VALUES.includes(appendTo) ||\n (appendTo instanceof HTMLElement);\n },\n },\n\n /**\n * The enter delay in milliseconds before the hovercard is shown.\n * @type number\n */\n enterDelay: {\n type: Number,\n default: TOOLTIP_DELAY_MS,\n },\n\n /**\n * The leave delay in milliseconds before the hovercard is hidden.\n * @type number\n */\n leaveDelay: {\n type: Number,\n default: TOOLTIP_DELAY_MS,\n },\n\n /**\n * External anchor element reference. Use this instead of the anchor slot when\n * the anchor may be inside a Shadow DOM, as querySelector cannot pierce shadow boundaries.\n */\n externalAnchorElement: {\n type: HTML_ELEMENT_TYPE,\n default: null,\n },\n});\n\ndefineEmits([\n /**\n * Emitted when hovercard is shown or hidden\n *\n * @event opened\n * @type {Boolean | Array}\n */\n 'opened',\n]);\n\nconst hovercardOpen = ref(props.open);\nconst contentFocused = ref(false);\nconst mouseOverHovercard = ref(false);\nconst inTimer = ref(null);\nconst outTimer = ref(null);\nconst anchorEl = ref(null);\nconst observer = ref(null);\nconst popover = ref(null);\n\nonMounted(() => {\n nextTick(() => {\n anchorEl.value = popover.value?.$refs?.anchor?.firstElementChild;\n\n observer.value = new MutationObserver(() => {\n if (anchorEl.value && !anchorEl.value.isConnected) {\n clearTimeout(inTimer.value);\n clearTimeout(outTimer.value);\n hovercardOpen.value = false;\n }\n });\n\n observer.value.observe(document.body, {\n childList: true,\n subtree: true,\n });\n });\n});\n\nonBeforeUnmount(() => {\n if (observer.value) {\n observer.value.disconnect();\n }\n clearTimeout(inTimer.value);\n clearTimeout(outTimer.value);\n});\n\nwatch(() => props.open, (open) => {\n hovercardOpen.value = open;\n}, { immediate: true });\n\ndefineExpose({ show: onMouseEnter, hide: onMouseLeave });\n\nfunction setInTimer () {\n if (props.open === null) {\n clearTimeout(outTimer.value);\n inTimer.value = setTimeout(() => {\n hovercardOpen.value = true;\n }, props.enterDelay);\n }\n}\n\nfunction setOutTimer () {\n if (props.open === null) {\n clearTimeout(inTimer.value);\n outTimer.value = setTimeout(() => {\n hovercardOpen.value = false;\n }, props.leaveDelay);\n }\n}\n\nfunction onMouseEnter () {\n mouseOverHovercard.value = true;\n setInTimer();\n}\n\nfunction onMouseLeave () {\n mouseOverHovercard.value = false;\n if (contentFocused.value) {\n return;\n }\n setOutTimer();\n}\n\nfunction onContentFocusIn () {\n contentFocused.value = true;\n setInTimer();\n}\n\nfunction onContentFocusOut () {\n contentFocused.value = false;\n\n // If mouse is not over the hovercard, close it\n if (!mouseOverHovercard.value) {\n setOutTimer();\n }\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuEA,IAAM,IAAQ,GAkLR,IAAgB,EAAI,EAAM,KAAK,EAC/B,IAAiB,EAAI,GAAM,EAC3B,IAAqB,EAAI,GAAM,EAC/B,IAAU,EAAI,KAAK,EACnB,IAAW,EAAI,KAAK,EACpB,IAAW,EAAI,KAAK,EACpB,IAAW,EAAI,KAAK,EACpB,IAAU,EAAI,KAAK;AAiCzB,EA/BA,QAAgB;AACd,WAAe;AAWb,IAVA,EAAS,QAAQ,EAAQ,OAAO,OAAO,QAAQ,mBAE/C,EAAS,QAAQ,IAAI,uBAAuB;AAC1C,KAAI,EAAS,SAAS,CAAC,EAAS,MAAM,gBACpC,aAAa,EAAQ,MAAM,EAC3B,aAAa,EAAS,MAAM,EAC5B,EAAc,QAAQ;MAExB,EAEF,EAAS,MAAM,QAAQ,SAAS,MAAM;KACpC,WAAW;KACX,SAAS;KACV,CAAC;KACF;IACF,EAEF,QAAsB;AAKpB,GAJI,EAAS,SACX,EAAS,MAAM,YAAY,EAE7B,aAAa,EAAQ,MAAM,EAC3B,aAAa,EAAS,MAAM;IAC5B,EAEF,QAAY,EAAM,OAAO,MAAS;AAChC,KAAc,QAAQ;KACrB,EAAE,WAAW,IAAM,CAAC,EAEvB,EAAa;GAAE,MAAM;GAAc,MAAM;GAAc,CAAC;EAExD,SAAS,IAAc;AACrB,GAAI,EAAM,SAAS,SACjB,aAAa,EAAS,MAAM,EAC5B,EAAQ,QAAQ,iBAAiB;AAC/B,MAAc,QAAQ;MACrB,EAAM,WAAW;;EAIxB,SAAS,IAAe;AACtB,GAAI,EAAM,SAAS,SACjB,aAAa,EAAQ,MAAM,EAC3B,EAAS,QAAQ,iBAAiB;AAChC,MAAc,QAAQ;MACrB,EAAM,WAAW;;EAIxB,SAAS,IAAgB;AAEvB,GADA,EAAmB,QAAQ,IAC3B,GAAY;;EAGd,SAAS,IAAgB;AACvB,KAAmB,QAAQ,IACvB,GAAe,SAGnB,GAAa;;EAGf,SAAS,IAAoB;AAE3B,GADA,EAAe,QAAQ,IACvB,GAAY;;EAGd,SAAS,IAAqB;AAI5B,GAHA,EAAe,QAAQ,IAGlB,EAAmB,SACtB,GAAa;;yBA1Uf,EAsDa,EAAA,EAAA,EAAA;GArDV,IAAI,EAAA;YACD;GAAJ,KAAI;GACH,MAAM,EAAA;GACN,WAAW,EAAA;GACX,iBAAe,EAAA;GACf,gBAAc,EAAA;GACd,gBAAc,EAAA;GACd,uBAAqB,EAAA;GACrB,SAAS,EAAA;GACT,YAAY,EAAA,aAAU,SAAA;GACtB,QAAQ,EAAA;GACR,OAAO;GACP,WAAW,EAAA;GACZ,yBAAsB;GACrB,gBAAc,EAAA;GACd,gBAAc,EAAA;GACd,aAAW,EAAA;GACX,gBAAc,EAAA;GACd,2BAAyB,EAAA;GAC1B,WAAQ;GACP,eAAa,EAAA;GACb,eAAa,EAAA;GACb,UAAM,EAAA,OAAA,EAAA,MAAG,MAAOA,EAAAA,MAAK,UAAW,EAAC;GACjC,qBAAoB;GACpB,qBAAoB;GACpB,2BAA2B;GAC3B,2BAA2B;;GAEjB,QAAM,GAKb,EALiB,eAAK,CAExB,EAGE,EAAA,QAAA,UAAA,EAAA,EADQ,EAAK,CAAA,CAAA,CAAA,CAAA;GAGN,SAAO,QAOV,CANN,EAMM,OAAA;IALH,WAAS;IACT,YAAU;OAGX,EAAuB,EAAA,QAAA,UAAA,CAAA,EAAA,GAAA,CAAA,CAAA;GAGhB,eAAa,QAEO,CAA7B,EAA6B,EAAA,QAAA,gBAAA,CAAA,CAAA;GAGpB,eAAa,QAEO,CAA7B,EAA6B,EAAA,QAAA,gBAAA,CAAA,CAAA"}
|
package/dist/lib/modal/modal.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}}),require(`../../chunk-Bmb41Sf3.cjs`);const e=require(`../../common/constants/index.cjs`),t=require(`../../common/utils/index.cjs`),n=require(`../../_plugin-vue_export-helper-D8jCH6HB.cjs`),r=require(`../../common/mixins/mode.cjs`),i=require(`../notice/notice-constants.cjs`),a=require(`../text/text.cjs`),o=require(`../../localization/index.cjs`),s=require(`../button/button.cjs`),c=require(`../../shared/sr_only_close_button.cjs`),l=require(`./modal-constants.cjs`);let u=require(`vue`),d=require(`@dialpad/dialtone-icons/vue`);var f=`button:not(:disabled),[href],input:not(:disabled),select:not(:disabled),textarea:not(:disabled),details,[tabindex]:not([tabindex="-1"]):not(:disabled):not([aria-disabled="true"])`,p={name:`DtModal`,components:{DtButton:s.default,DtText:a.default,DtIconClose:d.DtIconClose,SrOnlyCloseButton:c.default},mixins:[r.default],props:{copy:{type:String,default:``},describedById:{type:String,default:``},labelledById:{type:String,default:function(){return t.getUniqueString()}},open:{type:Boolean,default:!1},headerText:{type:String,default:void 0},bannerHeaderText:{type:String,default:void 0},kind:{type:String,default:`default`,validator:e=>Object.keys(l.MODAL_KIND_MODIFIERS).includes(e)},fullscreen:{type:Boolean,default:!1},modalClass:{type:[String,Object,Array],default:``},dialogClass:{type:[String,Object,Array],default:``},contentClass:{type:[String,Object,Array],default:``},bannerKind:{type:String,default:`warning`,validator(e){return i.NOTICE_KINDS.includes(e)}},bannerClass:{type:[String,Object,Array],default:``},headerClass:{type:[String,Object,Array],default:``},footerClass:{type:[String,Object,Array],default:``},showClose:{type:Boolean,default:!0},closeOnClick:{type:Boolean,default:!0},fixedHeaderFooter:{type:Boolean,default:!0},initialFocusElement:{type:[String,e.HTML_ELEMENT_TYPE],default:`first`,validator:e=>e===`first`||e instanceof HTMLElement||e.startsWith(`#`)},appendTo:{type:String,default:void 0},transparentBackdrop:{type:Boolean,default:!1},modal:{type:Boolean,default:!1}},emits:[`click`,`keydown`,`update:open`],data(){return{MODAL_KIND_MODIFIERS:l.MODAL_KIND_MODIFIERS,MODAL_BANNER_KINDS:l.MODAL_BANNER_KINDS,hasSlotContent:t.hasSlotContent,i18n:new o.DialtoneLocalization,autoTeleportTarget:null}},computed:{hasFooterSlot(){return!!this.$slots.footer},bannerKindClass(){return l.MODAL_BANNER_KINDS[this.bannerKind]},closeButtonTitle(){return this.i18n.$t(`DIALTONE_CLOSE_BUTTON`)}},watch:{open(e){this.syncDialogState(e)}},mounted(){if(!this.appendTo){let e=this.$el?.getRootNode();if(e instanceof ShadowRoot){this.autoTeleportTarget=e,this.open&&this.$nextTick(()=>{this.open&&this.syncDialogState(!0)});return}}this.open&&this.syncDialogState(!0)},beforeUnmount(){let e=this.$refs.dialogEl;e?.open&&(e.close(),t.enableRootScrolling(this.getScrollRoot())),this.previousActiveElement=null},methods:{getScrollRoot(){return t.returnFirstEl(this.$refs.dialogEl)?.getRootNode()?.host},syncDialogState(e){let n=this.$refs.dialogEl;n&&(e?(this.previousActiveElement=document.activeElement,n.open||(this.modal?n.showModal():n.show()),t.disableRootScrolling(this.getScrollRoot())):n.open&&t.enableRootScrolling(this.getScrollRoot()))},close(){this.$emit(`update:open`,!1)},onBackdropClick(e){this.closeOnClick&&e.target===e.currentTarget&&this.close(),this.$emit(`click`,e)},onKeydown(e){!this.modal&&e.key===`Escape`&&!e.defaultPrevented&&(e.preventDefault(),this.close()),this.$emit(`keydown`,e)},async onAfterEnter(){this.$emit(`update:open`,!0),await this.setFocusAfterTransition()},onAfterLeave(){let e=this.$refs.dialogEl;e?.open&&e.close(),this.previousActiveElement?.focus(),this.previousActiveElement=null},focusFirstTabbable(e){let t=[...e.querySelectorAll(f)];if(!t.length)return;let n=t[0];n.matches(`[type="radio"]:not(:checked)`)&&(n=t.find(e=>e.checked&&e.name===n.name)||n),n.focus({preventScroll:!0})},async setFocusAfterTransition(){let e=this.$refs.dialogEl;if(e)if(await this.$nextTick(),this.initialFocusElement===`first`)this.focusFirstTabbable(e);else if(typeof this.initialFocusElement==`string`&&this.initialFocusElement.startsWith(`#`)){let t=e.querySelector(this.initialFocusElement);t?t.focus():(console.warn(`Could not find the element specified in dt-modal prop "initialFocusElement". Defaulting to focusing the first element.`),this.focusFirstTabbable(e))}else this.initialFocusElement instanceof HTMLElement&&this.initialFocusElement.focus()}}},m=[`aria-modal`,`aria-describedby`,`aria-labelledby`],h=[`id`];function g(e,t,n,r,i,a){let o=(0,u.resolveComponent)(`dt-text`),s=(0,u.resolveComponent)(`sr-only-close-button`),c=(0,u.resolveComponent)(`dt-icon-close`),l=(0,u.resolveComponent)(`dt-button`),d=(0,u.resolveDirective)(`dt-focustrap`);return(0,u.openBlock)(),(0,u.createBlock)(u.Teleport,{disabled:!n.appendTo&&!i.autoTeleportTarget,to:n.appendTo||i.autoTeleportTarget},[(0,u.withDirectives)(((0,u.openBlock)(),(0,u.createElementBlock)(`dialog`,(0,u.mergeProps)({ref:`dialogEl`,class:[`d-modal`,i.MODAL_KIND_MODIFIERS[n.kind],{"d-modal--full":n.fullscreen},{"d-modal--transparent-backdrop":n.transparentBackdrop},n.modalClass],"data-qa":`dt-modal`,"aria-modal":n.modal?`true`:void 0,"aria-describedby":n.describedById||void 0,"aria-labelledby":n.labelledById},e.modeAttrs,{onCancel:t[0]||(t[0]=(0,u.withModifiers)((...e)=>a.close&&a.close(...e),[`prevent`])),
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}}),require(`../../chunk-Bmb41Sf3.cjs`);const e=require(`../../common/constants/index.cjs`),t=require(`../../common/utils/index.cjs`),n=require(`../../_plugin-vue_export-helper-D8jCH6HB.cjs`),r=require(`../../common/mixins/mode.cjs`),i=require(`../notice/notice-constants.cjs`),a=require(`../text/text.cjs`),o=require(`../../localization/index.cjs`),s=require(`../button/button.cjs`),c=require(`../../shared/sr_only_close_button.cjs`),l=require(`./modal-constants.cjs`);let u=require(`vue`),d=require(`@dialpad/dialtone-icons/vue`);var f=`button:not(:disabled),[href],input:not(:disabled),select:not(:disabled),textarea:not(:disabled),details,[tabindex]:not([tabindex="-1"]):not(:disabled):not([aria-disabled="true"])`,p={name:`DtModal`,components:{DtButton:s.default,DtText:a.default,DtIconClose:d.DtIconClose,SrOnlyCloseButton:c.default},mixins:[r.default],props:{copy:{type:String,default:``},describedById:{type:String,default:``},labelledById:{type:String,default:function(){return t.getUniqueString()}},open:{type:Boolean,default:!1},headerText:{type:String,default:void 0},bannerHeaderText:{type:String,default:void 0},kind:{type:String,default:`default`,validator:e=>Object.keys(l.MODAL_KIND_MODIFIERS).includes(e)},fullscreen:{type:Boolean,default:!1},modalClass:{type:[String,Object,Array],default:``},dialogClass:{type:[String,Object,Array],default:``},contentClass:{type:[String,Object,Array],default:``},bannerKind:{type:String,default:`warning`,validator(e){return i.NOTICE_KINDS.includes(e)}},bannerClass:{type:[String,Object,Array],default:``},headerClass:{type:[String,Object,Array],default:``},footerClass:{type:[String,Object,Array],default:``},showClose:{type:Boolean,default:!0},closeOnClick:{type:Boolean,default:!0},fixedHeaderFooter:{type:Boolean,default:!0},initialFocusElement:{type:[String,e.HTML_ELEMENT_TYPE],default:`first`,validator:e=>e===`first`||e instanceof HTMLElement||e.startsWith(`#`)},appendTo:{type:String,default:void 0},transparentBackdrop:{type:Boolean,default:!1},modal:{type:Boolean,default:!1}},emits:[`click`,`keydown`,`update:open`],data(){return{MODAL_KIND_MODIFIERS:l.MODAL_KIND_MODIFIERS,MODAL_BANNER_KINDS:l.MODAL_BANNER_KINDS,hasSlotContent:t.hasSlotContent,i18n:new o.DialtoneLocalization,autoTeleportTarget:null,mousedownOnBackdrop:!1,mouseupOnBackdrop:!1}},computed:{hasFooterSlot(){return!!this.$slots.footer},bannerKindClass(){return l.MODAL_BANNER_KINDS[this.bannerKind]},closeButtonTitle(){return this.i18n.$t(`DIALTONE_CLOSE_BUTTON`)}},watch:{open(e){this.syncDialogState(e)}},mounted(){if(!this.appendTo){let e=this.$el?.getRootNode();if(e instanceof ShadowRoot){this.autoTeleportTarget=e,this.open&&this.$nextTick(()=>{this.open&&this.syncDialogState(!0)});return}}this.open&&this.syncDialogState(!0)},beforeUnmount(){let e=this.$refs.dialogEl;e?.open&&(e.close(),t.enableRootScrolling(this.getScrollRoot())),this.previousActiveElement=null},methods:{getScrollRoot(){return t.returnFirstEl(this.$refs.dialogEl)?.getRootNode()?.host},syncDialogState(e){let n=this.$refs.dialogEl;n&&(e?(this.previousActiveElement=document.activeElement,n.open||(this.modal?n.showModal():n.show()),t.disableRootScrolling(this.getScrollRoot())):n.open&&t.enableRootScrolling(this.getScrollRoot()))},close(){this.$emit(`update:open`,!1)},onBackdropMousedown(e){this.mousedownOnBackdrop=e.target===e.currentTarget},onBackdropMouseup(e){this.mouseupOnBackdrop=e.target===e.currentTarget},onBackdropClick(e){let t=this.mousedownOnBackdrop&&this.mouseupOnBackdrop;this.closeOnClick&&e.target===e.currentTarget&&t&&this.close(),this.$emit(`click`,e)},onKeydown(e){!this.modal&&e.key===`Escape`&&!e.defaultPrevented&&(e.preventDefault(),this.close()),this.$emit(`keydown`,e)},async onAfterEnter(){this.$emit(`update:open`,!0),await this.setFocusAfterTransition()},onAfterLeave(){let e=this.$refs.dialogEl;e?.open&&e.close(),this.previousActiveElement?.focus(),this.previousActiveElement=null},focusFirstTabbable(e){let t=[...e.querySelectorAll(f)];if(!t.length)return;let n=t[0];n.matches(`[type="radio"]:not(:checked)`)&&(n=t.find(e=>e.checked&&e.name===n.name)||n),n.focus({preventScroll:!0})},async setFocusAfterTransition(){let e=this.$refs.dialogEl;if(e)if(await this.$nextTick(),this.initialFocusElement===`first`)this.focusFirstTabbable(e);else if(typeof this.initialFocusElement==`string`&&this.initialFocusElement.startsWith(`#`)){let t=e.querySelector(this.initialFocusElement);t?t.focus():(console.warn(`Could not find the element specified in dt-modal prop "initialFocusElement". Defaulting to focusing the first element.`),this.focusFirstTabbable(e))}else this.initialFocusElement instanceof HTMLElement&&this.initialFocusElement.focus()}}},m=[`aria-modal`,`aria-describedby`,`aria-labelledby`],h=[`id`];function g(e,t,n,r,i,a){let o=(0,u.resolveComponent)(`dt-text`),s=(0,u.resolveComponent)(`sr-only-close-button`),c=(0,u.resolveComponent)(`dt-icon-close`),l=(0,u.resolveComponent)(`dt-button`),d=(0,u.resolveDirective)(`dt-focustrap`);return(0,u.openBlock)(),(0,u.createBlock)(u.Teleport,{disabled:!n.appendTo&&!i.autoTeleportTarget,to:n.appendTo||i.autoTeleportTarget},[(0,u.withDirectives)(((0,u.openBlock)(),(0,u.createElementBlock)(`dialog`,(0,u.mergeProps)({ref:`dialogEl`,class:[`d-modal`,i.MODAL_KIND_MODIFIERS[n.kind],{"d-modal--full":n.fullscreen},{"d-modal--transparent-backdrop":n.transparentBackdrop},n.modalClass],"data-qa":`dt-modal`,"aria-modal":n.modal?`true`:void 0,"aria-describedby":n.describedById||void 0,"aria-labelledby":n.labelledById},e.modeAttrs,{onCancel:t[0]||(t[0]=(0,u.withModifiers)((...e)=>a.close&&a.close(...e),[`prevent`])),onMousedown:t[1]||(t[1]=(...e)=>a.onBackdropMousedown&&a.onBackdropMousedown(...e)),onMouseup:t[2]||(t[2]=(...e)=>a.onBackdropMouseup&&a.onBackdropMouseup(...e)),onClick:t[3]||(t[3]=(...e)=>a.onBackdropClick&&a.onBackdropClick(...e)),onKeydown:t[4]||(t[4]=(...e)=>a.onKeydown&&a.onKeydown(...e))}),[n.open&&(i.hasSlotContent(e.$slots.banner)||n.bannerHeaderText)?((0,u.openBlock)(),(0,u.createElementBlock)(`div`,{key:0,"data-qa":`dt-modal-banner`,class:(0,u.normalizeClass)([`d-modal__banner`,n.bannerClass,a.bannerKindClass])},[(0,u.renderSlot)(e.$slots,`banner`,{},()=>[(0,u.createTextVNode)((0,u.toDisplayString)(n.bannerHeaderText),1)])],2)):(0,u.createCommentVNode)(``,!0),(0,u.createVNode)(u.Transition,{appear:n.open,name:`d-modal__dialog`,onAfterEnter:a.onAfterEnter,onAfterLeave:a.onAfterLeave},{default:(0,u.withCtx)(()=>[(0,u.withDirectives)((0,u.createElementVNode)(`div`,{class:(0,u.normalizeClass)([`d-modal__dialog`,{"d-modal__dialog--scrollable":n.fixedHeaderFooter},n.dialogClass])},[i.hasSlotContent(e.$slots.header)?((0,u.openBlock)(),(0,u.createElementBlock)(`div`,{key:0,id:n.labelledById,class:(0,u.normalizeClass)([`d-modal__header`,n.headerClass]),"data-qa":`dt-modal-title`},[(0,u.renderSlot)(e.$slots,`header`)],10,h)):((0,u.openBlock)(),(0,u.createBlock)(o,{key:1,id:n.labelledById,kind:`headline`,size:600,strength:`medium`,density:`100`,"text-box-trim":`start`,as:`h2`,class:(0,u.normalizeClass)([`d-modal__header`,n.headerClass]),"data-qa":`dt-modal-title`},{default:(0,u.withCtx)(()=>[(0,u.createTextVNode)((0,u.toDisplayString)(n.headerText),1)]),_:1},8,[`id`,`class`])),i.hasSlotContent(e.$slots.default)?((0,u.openBlock)(),(0,u.createElementBlock)(`div`,{key:2,class:(0,u.normalizeClass)([`d-modal__content`,n.contentClass]),"data-qa":`dt-modal-copy`},[(0,u.renderSlot)(e.$slots,`default`)],2)):((0,u.openBlock)(),(0,u.createElementBlock)(`p`,{key:3,class:(0,u.normalizeClass)([`d-modal__content`,n.contentClass]),"data-qa":`dt-modal-copy`},(0,u.toDisplayString)(n.copy),3)),a.hasFooterSlot?((0,u.openBlock)(),(0,u.createElementBlock)(`footer`,{key:4,class:(0,u.normalizeClass)([`d-modal__footer`,n.footerClass])},[(0,u.renderSlot)(e.$slots,`footer`)],2)):(0,u.createCommentVNode)(``,!0),n.showClose?((0,u.openBlock)(),(0,u.createBlock)(l,{key:6,class:`d-modal__close`,"data-qa":`dt-modal-close-button`,size:300,kind:`muted`,importance:`clear`,"aria-label":a.closeButtonTitle,title:a.closeButtonTitle,onClick:a.close},{icon:(0,u.withCtx)(({iconSize:e})=>[(0,u.createVNode)(c,{size:e},null,8,[`size`])]),_:1},8,[`aria-label`,`title`,`onClick`])):((0,u.openBlock)(),(0,u.createBlock)(s,{key:5,onClose:a.close},null,8,[`onClose`]))],2),[[u.vShow,n.open]])]),_:3},8,[`appear`,`onAfterEnter`,`onAfterLeave`])],16,m)),[[d,{active:n.open,initialFocus:!1,restoreFocus:!1}]])],8,[`disabled`,`to`])}var _=n.t(p,[[`render`,g]]);exports.default=_;
|
|
2
2
|
//# sourceMappingURL=modal.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.cjs","names":[],"sources":["../../../components/Modal/Modal.vue"],"sourcesContent":["<template>\n <teleport\n :disabled=\"!appendTo && !autoTeleportTarget\"\n :to=\"appendTo || autoTeleportTarget\"\n >\n <!-- eslint-disable-next-line vuejs-accessibility/no-static-element-interactions -->\n <dialog\n ref=\"dialogEl\"\n v-dt-focustrap=\"{ active: open, initialFocus: false, restoreFocus: false }\"\n :class=\"[\n 'd-modal',\n MODAL_KIND_MODIFIERS[kind],\n { 'd-modal--full': fullscreen },\n { 'd-modal--transparent-backdrop': transparentBackdrop },\n modalClass,\n ]\"\n data-qa=\"dt-modal\"\n :aria-modal=\"modal ? 'true' : undefined\"\n :aria-describedby=\"describedById || undefined\"\n :aria-labelledby=\"labelledById\"\n v-bind=\"modeAttrs\"\n @cancel.prevent=\"close\"\n @click=\"onBackdropClick\"\n @keydown=\"onKeydown\"\n >\n <div\n v-if=\"open && (hasSlotContent($slots.banner) || bannerHeaderText)\"\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 bannerHeaderText prop -->\n <slot name=\"banner\">\n {{ bannerHeaderText }}\n </slot>\n </div>\n <transition\n :appear=\"open\"\n name=\"d-modal__dialog\"\n @after-enter=\"onAfterEnter\"\n @after-leave=\"onAfterLeave\"\n >\n <div\n v-show=\"open\"\n :class=\"[\n 'd-modal__dialog',\n { 'd-modal__dialog--scrollable': fixedHeaderFooter },\n dialogClass,\n ]\"\n >\n <div\n v-if=\"hasSlotContent($slots.header)\"\n :id=\"labelledById\"\n :class=\"['d-modal__header', headerClass]\"\n data-qa=\"dt-modal-title\"\n >\n <!-- @slot Slot for dialog header section, taking the place of any \"headerText\" text prop -->\n <slot name=\"header\" />\n </div>\n <dt-text\n v-else\n :id=\"labelledById\"\n kind=\"headline\"\n :size=\"600\"\n strength=\"medium\"\n density=\"100\"\n text-box-trim=\"start\"\n as=\"h2\"\n :class=\"['d-modal__header', headerClass]\"\n data-qa=\"dt-modal-title\"\n >\n {{ headerText }}\n </dt-text>\n <div\n v-if=\"hasSlotContent($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', footerClass]\"\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=\"!showClose\"\n @close=\"close\"\n />\n <dt-button\n v-else\n class=\"d-modal__close\"\n data-qa=\"dt-modal-close-button\"\n :size=\"300\"\n kind=\"muted\"\n importance=\"clear\"\n :aria-label=\"closeButtonTitle\"\n :title=\"closeButtonTitle\"\n @click=\"close\"\n >\n <template #icon=\"{ iconSize }\">\n <dt-icon-close\n :size=\"iconSize\"\n />\n </template>\n </dt-button>\n </div>\n </transition>\n </dialog>\n </teleport>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport { DtButton } from '@/components/Button';\nimport { DtText } from '@/components/Text';\nimport { DtIconClose } from '@dialpad/dialtone-icons/vue';\nimport ModeMixin from '@/common/mixins/mode';\nimport {\n MODAL_BANNER_KINDS,\n MODAL_KIND_MODIFIERS,\n} from './ModalConstants';\nimport { getUniqueString, hasSlotContent, returnFirstEl, disableRootScrolling, enableRootScrolling } from '@/common/utils';\nimport { HTML_ELEMENT_TYPE } from '@/common/constants';\nimport SrOnlyCloseButton from '@/common/sr_only_close_button.vue';\nimport { NOTICE_KINDS } from '@/components/Notice';\nimport { DialtoneLocalization } from '@/localization';\n\nconst focusableSelector = 'button:not(:disabled),[href],input:not(:disabled),select:not(:disabled),' +\n 'textarea:not(:disabled),details,[tabindex]:not([tabindex=\"-1\"]):not(:disabled):not([aria-disabled=\"true\"])';\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 DtButton,\n DtText,\n DtIconClose,\n SrOnlyCloseButton,\n },\n\n mixins: [ModeMixin],\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 open: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Header text to display in the modal header.\n */\n headerText: {\n type: String,\n default: undefined,\n },\n\n /**\n * Header text to display in the modal banner.\n */\n bannerHeaderText: {\n type: String,\n default: undefined,\n },\n\n /**\n * The theme of the modal.\n * @values default, critical\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(MODAL_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * Whether the modal fills the viewport instead of rendering at its default size.\n * @values true, false\n */\n fullscreen: {\n type: Boolean,\n default: false,\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, critical, info, positive, warning\n */\n bannerKind: {\n type: String,\n default: 'warning',\n validator (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 * Additional class name for the header 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 headerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the footer 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 footerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Shows the close button on the modal\n * @values true, false\n */\n showClose: {\n type: Boolean,\n default: true,\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, HTML_ELEMENT_TYPE],\n default: 'first',\n validator: initialFocusElement => {\n return initialFocusElement === 'first' ||\n (initialFocusElement instanceof HTMLElement) ||\n initialFocusElement.startsWith('#');\n },\n },\n\n /**\n * A CSS selector string for the element to portal the modal to. If not provided, the modal will be rendered in its default location.\n */\n appendTo: {\n type: String,\n default: undefined,\n },\n\n /**\n * When true, the surrounding backdrop is rendered fully transparent\n * instead of the default dimming overlay. The dialog box itself\n * remains opaque. Useful when the underlying UI should remain visible.\n * @values true, false\n */\n transparentBackdrop: {\n type: Boolean,\n default: false,\n },\n\n /**\n * When true, the dialog opens with showModal(), which promotes it to the browser\n * top layer. Nothing outside the top layer can paint above it regardless of\n * z-index, so application surfaces such as toasts and call notifications end up\n * behind it. When false, it opens with show() and stays in the normal stacking\n * order, where the Dialtone z-index scale applies and --zi-notification (700)\n * outranks --zi-modal (600) as documented.\n *\n * Focus trapping, scroll locking and Esc-to-close behave identically in both\n * modes. Background inertness does not: only the top layer provides it, so with\n * modal unset the page outside the dialog stays reachable. That is deliberate —\n * it is what lets an application's own overlays remain usable above a modal —\n * and keyboard containment still comes from the focus trap.\n * @values true, false\n */\n modal: {\n type: Boolean,\n default: false,\n },\n },\n\n emits: [\n /**\n * Native button click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n\n /**\n * Native keydown event\n *\n * @event keydown\n * @type {KeyboardEvent}\n */\n 'keydown',\n\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:open\n * @type {Boolean}\n */\n 'update:open',\n ],\n\n data () {\n return {\n MODAL_KIND_MODIFIERS,\n MODAL_BANNER_KINDS,\n hasSlotContent,\n i18n: new DialtoneLocalization(),\n autoTeleportTarget: null,\n };\n },\n\n computed: {\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 open (isShowing) {\n this.syncDialogState(isShowing);\n },\n },\n\n mounted () {\n if (!this.appendTo) {\n const root = this.$el?.getRootNode();\n if (root instanceof ShadowRoot) {\n this.autoTeleportTarget = root;\n // Defer syncDialogState so the teleport renders inside the shadow root first.\n if (this.open) this.$nextTick(() => { if (this.open) this.syncDialogState(true); });\n return;\n }\n }\n if (this.open) {\n this.syncDialogState(true);\n }\n },\n\n beforeUnmount () {\n const dialogEl = this.$refs.dialogEl;\n if (dialogEl?.open) {\n dialogEl.close();\n enableRootScrolling(this.getScrollRoot());\n }\n this.previousActiveElement = null;\n },\n\n methods: {\n getScrollRoot () {\n return returnFirstEl(this.$refs.dialogEl)?.getRootNode()?.host;\n },\n\n syncDialogState (isShowing) {\n const dialogEl = this.$refs.dialogEl;\n if (!dialogEl) return;\n\n if (isShowing) {\n this.previousActiveElement = document.activeElement;\n if (!dialogEl.open) {\n // show() leaves the dialog in the normal stacking order instead of the\n // top layer, where the z-index scale still applies.\n if (this.modal) dialogEl.showModal(); else dialogEl.show();\n }\n disableRootScrolling(this.getScrollRoot());\n } else if (dialogEl.open) {\n // Leave transition plays via v-show on inner content.\n // close() is called in onAfterLeave when transition completes.\n enableRootScrolling(this.getScrollRoot());\n }\n },\n\n\n\n close () {\n this.$emit('update:open', false);\n },\n\n onBackdropClick (event) {\n if (this.closeOnClick && event.target === event.currentTarget) {\n this.close();\n }\n this.$emit('click', event);\n },\n\n onKeydown (event) {\n // The native cancel event only fires for dialogs opened with showModal(), so\n // Esc has to be handled explicitly to keep dismissal identical in both modes.\n // defaultPrevented means a nested widget (dropdown, combobox) already consumed\n // it to close itself, and the modal must not close out from under it.\n if (!this.modal && event.key === 'Escape' && !event.defaultPrevented) {\n event.preventDefault();\n this.close();\n }\n this.$emit('keydown', event);\n },\n\n async onAfterEnter () {\n this.$emit('update:open', true);\n await this.setFocusAfterTransition();\n },\n\n onAfterLeave () {\n const dialogEl = this.$refs.dialogEl;\n if (dialogEl?.open) {\n dialogEl.close();\n }\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n },\n\n focusFirstTabbable (container) {\n const focusable = [...container.querySelectorAll(focusableSelector)];\n if (!focusable.length) return;\n let target = focusable[0];\n // If first focusable is an unchecked radio, prefer the checked radio in the same group.\n if (target.matches('[type=\"radio\"]:not(:checked)')) {\n target = focusable.find(el => el.checked && el.name === target.name) || target;\n }\n target.focus({ preventScroll: true });\n },\n\n async setFocusAfterTransition () {\n const dialogEl = this.$refs.dialogEl;\n if (!dialogEl) return;\n\n await this.$nextTick();\n\n if (this.initialFocusElement === 'first') {\n this.focusFirstTabbable(dialogEl);\n } else if (typeof this.initialFocusElement === 'string' && this.initialFocusElement.startsWith('#')) {\n const el = dialogEl.querySelector(this.initialFocusElement);\n if (el) {\n el.focus();\n } else {\n // eslint-disable-next-line no-console\n console.warn('Could not find the element specified in dt-modal prop \"initialFocusElement\". ' +\n 'Defaulting to focusing the first element.');\n this.focusFirstTabbable(dialogEl);\n }\n } else if (this.initialFocusElement instanceof HTMLElement) {\n this.initialFocusElement.focus();\n }\n },\n },\n};\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"modal.cjs","names":[],"sources":["../../../components/Modal/Modal.vue"],"sourcesContent":["<template>\n <teleport\n :disabled=\"!appendTo && !autoTeleportTarget\"\n :to=\"appendTo || autoTeleportTarget\"\n >\n <!-- eslint-disable-next-line vuejs-accessibility/no-static-element-interactions -->\n <dialog\n ref=\"dialogEl\"\n v-dt-focustrap=\"{ active: open, initialFocus: false, restoreFocus: false }\"\n :class=\"[\n 'd-modal',\n MODAL_KIND_MODIFIERS[kind],\n { 'd-modal--full': fullscreen },\n { 'd-modal--transparent-backdrop': transparentBackdrop },\n modalClass,\n ]\"\n data-qa=\"dt-modal\"\n :aria-modal=\"modal ? 'true' : undefined\"\n :aria-describedby=\"describedById || undefined\"\n :aria-labelledby=\"labelledById\"\n v-bind=\"modeAttrs\"\n @cancel.prevent=\"close\"\n @mousedown=\"onBackdropMousedown\"\n @mouseup=\"onBackdropMouseup\"\n @click=\"onBackdropClick\"\n @keydown=\"onKeydown\"\n >\n <div\n v-if=\"open && (hasSlotContent($slots.banner) || bannerHeaderText)\"\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 bannerHeaderText prop -->\n <slot name=\"banner\">\n {{ bannerHeaderText }}\n </slot>\n </div>\n <transition\n :appear=\"open\"\n name=\"d-modal__dialog\"\n @after-enter=\"onAfterEnter\"\n @after-leave=\"onAfterLeave\"\n >\n <div\n v-show=\"open\"\n :class=\"[\n 'd-modal__dialog',\n { 'd-modal__dialog--scrollable': fixedHeaderFooter },\n dialogClass,\n ]\"\n >\n <div\n v-if=\"hasSlotContent($slots.header)\"\n :id=\"labelledById\"\n :class=\"['d-modal__header', headerClass]\"\n data-qa=\"dt-modal-title\"\n >\n <!-- @slot Slot for dialog header section, taking the place of any \"headerText\" text prop -->\n <slot name=\"header\" />\n </div>\n <dt-text\n v-else\n :id=\"labelledById\"\n kind=\"headline\"\n :size=\"600\"\n strength=\"medium\"\n density=\"100\"\n text-box-trim=\"start\"\n as=\"h2\"\n :class=\"['d-modal__header', headerClass]\"\n data-qa=\"dt-modal-title\"\n >\n {{ headerText }}\n </dt-text>\n <div\n v-if=\"hasSlotContent($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', footerClass]\"\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=\"!showClose\"\n @close=\"close\"\n />\n <dt-button\n v-else\n class=\"d-modal__close\"\n data-qa=\"dt-modal-close-button\"\n :size=\"300\"\n kind=\"muted\"\n importance=\"clear\"\n :aria-label=\"closeButtonTitle\"\n :title=\"closeButtonTitle\"\n @click=\"close\"\n >\n <template #icon=\"{ iconSize }\">\n <dt-icon-close\n :size=\"iconSize\"\n />\n </template>\n </dt-button>\n </div>\n </transition>\n </dialog>\n </teleport>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport { DtButton } from '@/components/Button';\nimport { DtText } from '@/components/Text';\nimport { DtIconClose } from '@dialpad/dialtone-icons/vue';\nimport ModeMixin from '@/common/mixins/mode';\nimport {\n MODAL_BANNER_KINDS,\n MODAL_KIND_MODIFIERS,\n} from './ModalConstants';\nimport { getUniqueString, hasSlotContent, returnFirstEl, disableRootScrolling, enableRootScrolling } from '@/common/utils';\nimport { HTML_ELEMENT_TYPE } from '@/common/constants';\nimport SrOnlyCloseButton from '@/common/sr_only_close_button.vue';\nimport { NOTICE_KINDS } from '@/components/Notice';\nimport { DialtoneLocalization } from '@/localization';\n\nconst focusableSelector = 'button:not(:disabled),[href],input:not(:disabled),select:not(:disabled),' +\n 'textarea:not(:disabled),details,[tabindex]:not([tabindex=\"-1\"]):not(:disabled):not([aria-disabled=\"true\"])';\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 DtButton,\n DtText,\n DtIconClose,\n SrOnlyCloseButton,\n },\n\n mixins: [ModeMixin],\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 open: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Header text to display in the modal header.\n */\n headerText: {\n type: String,\n default: undefined,\n },\n\n /**\n * Header text to display in the modal banner.\n */\n bannerHeaderText: {\n type: String,\n default: undefined,\n },\n\n /**\n * The theme of the modal.\n * @values default, critical\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(MODAL_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * Whether the modal fills the viewport instead of rendering at its default size.\n * @values true, false\n */\n fullscreen: {\n type: Boolean,\n default: false,\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, critical, info, positive, warning\n */\n bannerKind: {\n type: String,\n default: 'warning',\n validator (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 * Additional class name for the header 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 headerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the footer 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 footerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Shows the close button on the modal\n * @values true, false\n */\n showClose: {\n type: Boolean,\n default: true,\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, HTML_ELEMENT_TYPE],\n default: 'first',\n validator: initialFocusElement => {\n return initialFocusElement === 'first' ||\n (initialFocusElement instanceof HTMLElement) ||\n initialFocusElement.startsWith('#');\n },\n },\n\n /**\n * A CSS selector string for the element to portal the modal to. If not provided, the modal will be rendered in its default location.\n */\n appendTo: {\n type: String,\n default: undefined,\n },\n\n /**\n * When true, the surrounding backdrop is rendered fully transparent\n * instead of the default dimming overlay. The dialog box itself\n * remains opaque. Useful when the underlying UI should remain visible.\n * @values true, false\n */\n transparentBackdrop: {\n type: Boolean,\n default: false,\n },\n\n /**\n * When true, the dialog opens with showModal(), which promotes it to the browser\n * top layer. Nothing outside the top layer can paint above it regardless of\n * z-index, so application surfaces such as toasts and call notifications end up\n * behind it. When false, it opens with show() and stays in the normal stacking\n * order, where the Dialtone z-index scale applies and --zi-notification (700)\n * outranks --zi-modal (600) as documented.\n *\n * Focus trapping, scroll locking and Esc-to-close behave identically in both\n * modes. Background inertness does not: only the top layer provides it, so with\n * modal unset the page outside the dialog stays reachable. That is deliberate —\n * it is what lets an application's own overlays remain usable above a modal —\n * and keyboard containment still comes from the focus trap.\n * @values true, false\n */\n modal: {\n type: Boolean,\n default: false,\n },\n },\n\n emits: [\n /**\n * Native button click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n\n /**\n * Native keydown event\n *\n * @event keydown\n * @type {KeyboardEvent}\n */\n 'keydown',\n\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:open\n * @type {Boolean}\n */\n 'update:open',\n ],\n\n data () {\n return {\n MODAL_KIND_MODIFIERS,\n MODAL_BANNER_KINDS,\n hasSlotContent,\n i18n: new DialtoneLocalization(),\n autoTeleportTarget: null,\n mousedownOnBackdrop: false,\n mouseupOnBackdrop: false,\n };\n },\n\n computed: {\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 open (isShowing) {\n this.syncDialogState(isShowing);\n },\n },\n\n mounted () {\n if (!this.appendTo) {\n const root = this.$el?.getRootNode();\n if (root instanceof ShadowRoot) {\n this.autoTeleportTarget = root;\n // Defer syncDialogState so the teleport renders inside the shadow root first.\n if (this.open) this.$nextTick(() => { if (this.open) this.syncDialogState(true); });\n return;\n }\n }\n if (this.open) {\n this.syncDialogState(true);\n }\n },\n\n beforeUnmount () {\n const dialogEl = this.$refs.dialogEl;\n if (dialogEl?.open) {\n dialogEl.close();\n enableRootScrolling(this.getScrollRoot());\n }\n this.previousActiveElement = null;\n },\n\n methods: {\n getScrollRoot () {\n return returnFirstEl(this.$refs.dialogEl)?.getRootNode()?.host;\n },\n\n syncDialogState (isShowing) {\n const dialogEl = this.$refs.dialogEl;\n if (!dialogEl) return;\n\n if (isShowing) {\n this.previousActiveElement = document.activeElement;\n if (!dialogEl.open) {\n // show() leaves the dialog in the normal stacking order instead of the\n // top layer, where the z-index scale still applies.\n if (this.modal) dialogEl.showModal(); else dialogEl.show();\n }\n disableRootScrolling(this.getScrollRoot());\n } else if (dialogEl.open) {\n // Leave transition plays via v-show on inner content.\n // close() is called in onAfterLeave when transition completes.\n enableRootScrolling(this.getScrollRoot());\n }\n },\n\n\n\n close () {\n this.$emit('update:open', false);\n },\n\n onBackdropMousedown (event) {\n this.mousedownOnBackdrop = event.target === event.currentTarget;\n },\n\n onBackdropMouseup (event) {\n this.mouseupOnBackdrop = event.target === event.currentTarget;\n },\n\n onBackdropClick (event) {\n const pressedAndReleasedOnBackdrop = this.mousedownOnBackdrop && this.mouseupOnBackdrop;\n if (this.closeOnClick && event.target === event.currentTarget && pressedAndReleasedOnBackdrop) {\n this.close();\n }\n this.$emit('click', event);\n },\n\n onKeydown (event) {\n // The native cancel event only fires for dialogs opened with showModal(), so\n // Esc has to be handled explicitly to keep dismissal identical in both modes.\n // defaultPrevented means a nested widget (dropdown, combobox) already consumed\n // it to close itself, and the modal must not close out from under it.\n if (!this.modal && event.key === 'Escape' && !event.defaultPrevented) {\n event.preventDefault();\n this.close();\n }\n this.$emit('keydown', event);\n },\n\n async onAfterEnter () {\n this.$emit('update:open', true);\n await this.setFocusAfterTransition();\n },\n\n onAfterLeave () {\n const dialogEl = this.$refs.dialogEl;\n if (dialogEl?.open) {\n dialogEl.close();\n }\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n },\n\n focusFirstTabbable (container) {\n const focusable = [...container.querySelectorAll(focusableSelector)];\n if (!focusable.length) return;\n let target = focusable[0];\n // If first focusable is an unchecked radio, prefer the checked radio in the same group.\n if (target.matches('[type=\"radio\"]:not(:checked)')) {\n target = focusable.find(el => el.checked && el.name === target.name) || target;\n }\n target.focus({ preventScroll: true });\n },\n\n async setFocusAfterTransition () {\n const dialogEl = this.$refs.dialogEl;\n if (!dialogEl) return;\n\n await this.$nextTick();\n\n if (this.initialFocusElement === 'first') {\n this.focusFirstTabbable(dialogEl);\n } else if (typeof this.initialFocusElement === 'string' && this.initialFocusElement.startsWith('#')) {\n const el = dialogEl.querySelector(this.initialFocusElement);\n if (el) {\n el.focus();\n } else {\n // eslint-disable-next-line no-console\n console.warn('Could not find the element specified in dt-modal prop \"initialFocusElement\". ' +\n 'Defaulting to focusing the first element.');\n this.focusFirstTabbable(dialogEl);\n }\n } else if (this.initialFocusElement instanceof HTMLElement) {\n this.initialFocusElement.focus();\n }\n },\n },\n};\n</script>\n"],"mappings":"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"}
|
package/dist/lib/modal/modal.js
CHANGED
|
@@ -152,7 +152,9 @@ var F = "button:not(:disabled),[href],input:not(:disabled),select:not(:disabled)
|
|
|
152
152
|
MODAL_BANNER_KINDS: p,
|
|
153
153
|
hasSlotContent: i,
|
|
154
154
|
i18n: new u(),
|
|
155
|
-
autoTeleportTarget: null
|
|
155
|
+
autoTeleportTarget: null,
|
|
156
|
+
mousedownOnBackdrop: !1,
|
|
157
|
+
mouseupOnBackdrop: !1
|
|
156
158
|
};
|
|
157
159
|
},
|
|
158
160
|
computed: {
|
|
@@ -196,8 +198,15 @@ var F = "button:not(:disabled),[href],input:not(:disabled),select:not(:disabled)
|
|
|
196
198
|
close() {
|
|
197
199
|
this.$emit("update:open", !1);
|
|
198
200
|
},
|
|
201
|
+
onBackdropMousedown(e) {
|
|
202
|
+
this.mousedownOnBackdrop = e.target === e.currentTarget;
|
|
203
|
+
},
|
|
204
|
+
onBackdropMouseup(e) {
|
|
205
|
+
this.mouseupOnBackdrop = e.target === e.currentTarget;
|
|
206
|
+
},
|
|
199
207
|
onBackdropClick(e) {
|
|
200
|
-
|
|
208
|
+
let t = this.mousedownOnBackdrop && this.mouseupOnBackdrop;
|
|
209
|
+
this.closeOnClick && e.target === e.currentTarget && t && this.close(), this.$emit("click", e);
|
|
201
210
|
},
|
|
202
211
|
onKeydown(e) {
|
|
203
212
|
!this.modal && e.key === "Escape" && !e.defaultPrevented && (e.preventDefault(), this.close()), this.$emit("keydown", e);
|
|
@@ -249,8 +258,10 @@ function z(e, t, n, r, i, a) {
|
|
|
249
258
|
"aria-labelledby": n.labelledById
|
|
250
259
|
}, e.modeAttrs, {
|
|
251
260
|
onCancel: t[0] || (t[0] = N((...e) => a.close && a.close(...e), ["prevent"])),
|
|
252
|
-
|
|
253
|
-
|
|
261
|
+
onMousedown: t[1] || (t[1] = (...e) => a.onBackdropMousedown && a.onBackdropMousedown(...e)),
|
|
262
|
+
onMouseup: t[2] || (t[2] = (...e) => a.onBackdropMouseup && a.onBackdropMouseup(...e)),
|
|
263
|
+
onClick: t[3] || (t[3] = (...e) => a.onBackdropClick && a.onBackdropClick(...e)),
|
|
264
|
+
onKeydown: t[4] || (t[4] = (...e) => a.onKeydown && a.onKeydown(...e))
|
|
254
265
|
}), [n.open && (i.hasSlotContent(e.$slots.banner) || n.bannerHeaderText) ? (T(), y("div", {
|
|
255
266
|
key: 0,
|
|
256
267
|
"data-qa": "dt-modal-banner",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.js","names":[],"sources":["../../../components/Modal/Modal.vue"],"sourcesContent":["<template>\n <teleport\n :disabled=\"!appendTo && !autoTeleportTarget\"\n :to=\"appendTo || autoTeleportTarget\"\n >\n <!-- eslint-disable-next-line vuejs-accessibility/no-static-element-interactions -->\n <dialog\n ref=\"dialogEl\"\n v-dt-focustrap=\"{ active: open, initialFocus: false, restoreFocus: false }\"\n :class=\"[\n 'd-modal',\n MODAL_KIND_MODIFIERS[kind],\n { 'd-modal--full': fullscreen },\n { 'd-modal--transparent-backdrop': transparentBackdrop },\n modalClass,\n ]\"\n data-qa=\"dt-modal\"\n :aria-modal=\"modal ? 'true' : undefined\"\n :aria-describedby=\"describedById || undefined\"\n :aria-labelledby=\"labelledById\"\n v-bind=\"modeAttrs\"\n @cancel.prevent=\"close\"\n @click=\"onBackdropClick\"\n @keydown=\"onKeydown\"\n >\n <div\n v-if=\"open && (hasSlotContent($slots.banner) || bannerHeaderText)\"\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 bannerHeaderText prop -->\n <slot name=\"banner\">\n {{ bannerHeaderText }}\n </slot>\n </div>\n <transition\n :appear=\"open\"\n name=\"d-modal__dialog\"\n @after-enter=\"onAfterEnter\"\n @after-leave=\"onAfterLeave\"\n >\n <div\n v-show=\"open\"\n :class=\"[\n 'd-modal__dialog',\n { 'd-modal__dialog--scrollable': fixedHeaderFooter },\n dialogClass,\n ]\"\n >\n <div\n v-if=\"hasSlotContent($slots.header)\"\n :id=\"labelledById\"\n :class=\"['d-modal__header', headerClass]\"\n data-qa=\"dt-modal-title\"\n >\n <!-- @slot Slot for dialog header section, taking the place of any \"headerText\" text prop -->\n <slot name=\"header\" />\n </div>\n <dt-text\n v-else\n :id=\"labelledById\"\n kind=\"headline\"\n :size=\"600\"\n strength=\"medium\"\n density=\"100\"\n text-box-trim=\"start\"\n as=\"h2\"\n :class=\"['d-modal__header', headerClass]\"\n data-qa=\"dt-modal-title\"\n >\n {{ headerText }}\n </dt-text>\n <div\n v-if=\"hasSlotContent($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', footerClass]\"\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=\"!showClose\"\n @close=\"close\"\n />\n <dt-button\n v-else\n class=\"d-modal__close\"\n data-qa=\"dt-modal-close-button\"\n :size=\"300\"\n kind=\"muted\"\n importance=\"clear\"\n :aria-label=\"closeButtonTitle\"\n :title=\"closeButtonTitle\"\n @click=\"close\"\n >\n <template #icon=\"{ iconSize }\">\n <dt-icon-close\n :size=\"iconSize\"\n />\n </template>\n </dt-button>\n </div>\n </transition>\n </dialog>\n </teleport>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport { DtButton } from '@/components/Button';\nimport { DtText } from '@/components/Text';\nimport { DtIconClose } from '@dialpad/dialtone-icons/vue';\nimport ModeMixin from '@/common/mixins/mode';\nimport {\n MODAL_BANNER_KINDS,\n MODAL_KIND_MODIFIERS,\n} from './ModalConstants';\nimport { getUniqueString, hasSlotContent, returnFirstEl, disableRootScrolling, enableRootScrolling } from '@/common/utils';\nimport { HTML_ELEMENT_TYPE } from '@/common/constants';\nimport SrOnlyCloseButton from '@/common/sr_only_close_button.vue';\nimport { NOTICE_KINDS } from '@/components/Notice';\nimport { DialtoneLocalization } from '@/localization';\n\nconst focusableSelector = 'button:not(:disabled),[href],input:not(:disabled),select:not(:disabled),' +\n 'textarea:not(:disabled),details,[tabindex]:not([tabindex=\"-1\"]):not(:disabled):not([aria-disabled=\"true\"])';\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 DtButton,\n DtText,\n DtIconClose,\n SrOnlyCloseButton,\n },\n\n mixins: [ModeMixin],\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 open: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Header text to display in the modal header.\n */\n headerText: {\n type: String,\n default: undefined,\n },\n\n /**\n * Header text to display in the modal banner.\n */\n bannerHeaderText: {\n type: String,\n default: undefined,\n },\n\n /**\n * The theme of the modal.\n * @values default, critical\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(MODAL_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * Whether the modal fills the viewport instead of rendering at its default size.\n * @values true, false\n */\n fullscreen: {\n type: Boolean,\n default: false,\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, critical, info, positive, warning\n */\n bannerKind: {\n type: String,\n default: 'warning',\n validator (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 * Additional class name for the header 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 headerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the footer 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 footerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Shows the close button on the modal\n * @values true, false\n */\n showClose: {\n type: Boolean,\n default: true,\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, HTML_ELEMENT_TYPE],\n default: 'first',\n validator: initialFocusElement => {\n return initialFocusElement === 'first' ||\n (initialFocusElement instanceof HTMLElement) ||\n initialFocusElement.startsWith('#');\n },\n },\n\n /**\n * A CSS selector string for the element to portal the modal to. If not provided, the modal will be rendered in its default location.\n */\n appendTo: {\n type: String,\n default: undefined,\n },\n\n /**\n * When true, the surrounding backdrop is rendered fully transparent\n * instead of the default dimming overlay. The dialog box itself\n * remains opaque. Useful when the underlying UI should remain visible.\n * @values true, false\n */\n transparentBackdrop: {\n type: Boolean,\n default: false,\n },\n\n /**\n * When true, the dialog opens with showModal(), which promotes it to the browser\n * top layer. Nothing outside the top layer can paint above it regardless of\n * z-index, so application surfaces such as toasts and call notifications end up\n * behind it. When false, it opens with show() and stays in the normal stacking\n * order, where the Dialtone z-index scale applies and --zi-notification (700)\n * outranks --zi-modal (600) as documented.\n *\n * Focus trapping, scroll locking and Esc-to-close behave identically in both\n * modes. Background inertness does not: only the top layer provides it, so with\n * modal unset the page outside the dialog stays reachable. That is deliberate —\n * it is what lets an application's own overlays remain usable above a modal —\n * and keyboard containment still comes from the focus trap.\n * @values true, false\n */\n modal: {\n type: Boolean,\n default: false,\n },\n },\n\n emits: [\n /**\n * Native button click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n\n /**\n * Native keydown event\n *\n * @event keydown\n * @type {KeyboardEvent}\n */\n 'keydown',\n\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:open\n * @type {Boolean}\n */\n 'update:open',\n ],\n\n data () {\n return {\n MODAL_KIND_MODIFIERS,\n MODAL_BANNER_KINDS,\n hasSlotContent,\n i18n: new DialtoneLocalization(),\n autoTeleportTarget: null,\n };\n },\n\n computed: {\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 open (isShowing) {\n this.syncDialogState(isShowing);\n },\n },\n\n mounted () {\n if (!this.appendTo) {\n const root = this.$el?.getRootNode();\n if (root instanceof ShadowRoot) {\n this.autoTeleportTarget = root;\n // Defer syncDialogState so the teleport renders inside the shadow root first.\n if (this.open) this.$nextTick(() => { if (this.open) this.syncDialogState(true); });\n return;\n }\n }\n if (this.open) {\n this.syncDialogState(true);\n }\n },\n\n beforeUnmount () {\n const dialogEl = this.$refs.dialogEl;\n if (dialogEl?.open) {\n dialogEl.close();\n enableRootScrolling(this.getScrollRoot());\n }\n this.previousActiveElement = null;\n },\n\n methods: {\n getScrollRoot () {\n return returnFirstEl(this.$refs.dialogEl)?.getRootNode()?.host;\n },\n\n syncDialogState (isShowing) {\n const dialogEl = this.$refs.dialogEl;\n if (!dialogEl) return;\n\n if (isShowing) {\n this.previousActiveElement = document.activeElement;\n if (!dialogEl.open) {\n // show() leaves the dialog in the normal stacking order instead of the\n // top layer, where the z-index scale still applies.\n if (this.modal) dialogEl.showModal(); else dialogEl.show();\n }\n disableRootScrolling(this.getScrollRoot());\n } else if (dialogEl.open) {\n // Leave transition plays via v-show on inner content.\n // close() is called in onAfterLeave when transition completes.\n enableRootScrolling(this.getScrollRoot());\n }\n },\n\n\n\n close () {\n this.$emit('update:open', false);\n },\n\n onBackdropClick (event) {\n if (this.closeOnClick && event.target === event.currentTarget) {\n this.close();\n }\n this.$emit('click', event);\n },\n\n onKeydown (event) {\n // The native cancel event only fires for dialogs opened with showModal(), so\n // Esc has to be handled explicitly to keep dismissal identical in both modes.\n // defaultPrevented means a nested widget (dropdown, combobox) already consumed\n // it to close itself, and the modal must not close out from under it.\n if (!this.modal && event.key === 'Escape' && !event.defaultPrevented) {\n event.preventDefault();\n this.close();\n }\n this.$emit('keydown', event);\n },\n\n async onAfterEnter () {\n this.$emit('update:open', true);\n await this.setFocusAfterTransition();\n },\n\n onAfterLeave () {\n const dialogEl = this.$refs.dialogEl;\n if (dialogEl?.open) {\n dialogEl.close();\n }\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n },\n\n focusFirstTabbable (container) {\n const focusable = [...container.querySelectorAll(focusableSelector)];\n if (!focusable.length) return;\n let target = focusable[0];\n // If first focusable is an unchecked radio, prefer the checked radio in the same group.\n if (target.matches('[type=\"radio\"]:not(:checked)')) {\n target = focusable.find(el => el.checked && el.name === target.name) || target;\n }\n target.focus({ preventScroll: true });\n },\n\n async setFocusAfterTransition () {\n const dialogEl = this.$refs.dialogEl;\n if (!dialogEl) return;\n\n await this.$nextTick();\n\n if (this.initialFocusElement === 'first') {\n this.focusFirstTabbable(dialogEl);\n } else if (typeof this.initialFocusElement === 'string' && this.initialFocusElement.startsWith('#')) {\n const el = dialogEl.querySelector(this.initialFocusElement);\n if (el) {\n el.focus();\n } else {\n // eslint-disable-next-line no-console\n console.warn('Could not find the element specified in dt-modal prop \"initialFocusElement\". ' +\n 'Defaulting to focusing the first element.');\n this.focusFirstTabbable(dialogEl);\n }\n } else if (this.initialFocusElement instanceof HTMLElement) {\n this.initialFocusElement.focus();\n }\n },\n },\n};\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"modal.js","names":[],"sources":["../../../components/Modal/Modal.vue"],"sourcesContent":["<template>\n <teleport\n :disabled=\"!appendTo && !autoTeleportTarget\"\n :to=\"appendTo || autoTeleportTarget\"\n >\n <!-- eslint-disable-next-line vuejs-accessibility/no-static-element-interactions -->\n <dialog\n ref=\"dialogEl\"\n v-dt-focustrap=\"{ active: open, initialFocus: false, restoreFocus: false }\"\n :class=\"[\n 'd-modal',\n MODAL_KIND_MODIFIERS[kind],\n { 'd-modal--full': fullscreen },\n { 'd-modal--transparent-backdrop': transparentBackdrop },\n modalClass,\n ]\"\n data-qa=\"dt-modal\"\n :aria-modal=\"modal ? 'true' : undefined\"\n :aria-describedby=\"describedById || undefined\"\n :aria-labelledby=\"labelledById\"\n v-bind=\"modeAttrs\"\n @cancel.prevent=\"close\"\n @mousedown=\"onBackdropMousedown\"\n @mouseup=\"onBackdropMouseup\"\n @click=\"onBackdropClick\"\n @keydown=\"onKeydown\"\n >\n <div\n v-if=\"open && (hasSlotContent($slots.banner) || bannerHeaderText)\"\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 bannerHeaderText prop -->\n <slot name=\"banner\">\n {{ bannerHeaderText }}\n </slot>\n </div>\n <transition\n :appear=\"open\"\n name=\"d-modal__dialog\"\n @after-enter=\"onAfterEnter\"\n @after-leave=\"onAfterLeave\"\n >\n <div\n v-show=\"open\"\n :class=\"[\n 'd-modal__dialog',\n { 'd-modal__dialog--scrollable': fixedHeaderFooter },\n dialogClass,\n ]\"\n >\n <div\n v-if=\"hasSlotContent($slots.header)\"\n :id=\"labelledById\"\n :class=\"['d-modal__header', headerClass]\"\n data-qa=\"dt-modal-title\"\n >\n <!-- @slot Slot for dialog header section, taking the place of any \"headerText\" text prop -->\n <slot name=\"header\" />\n </div>\n <dt-text\n v-else\n :id=\"labelledById\"\n kind=\"headline\"\n :size=\"600\"\n strength=\"medium\"\n density=\"100\"\n text-box-trim=\"start\"\n as=\"h2\"\n :class=\"['d-modal__header', headerClass]\"\n data-qa=\"dt-modal-title\"\n >\n {{ headerText }}\n </dt-text>\n <div\n v-if=\"hasSlotContent($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', footerClass]\"\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=\"!showClose\"\n @close=\"close\"\n />\n <dt-button\n v-else\n class=\"d-modal__close\"\n data-qa=\"dt-modal-close-button\"\n :size=\"300\"\n kind=\"muted\"\n importance=\"clear\"\n :aria-label=\"closeButtonTitle\"\n :title=\"closeButtonTitle\"\n @click=\"close\"\n >\n <template #icon=\"{ iconSize }\">\n <dt-icon-close\n :size=\"iconSize\"\n />\n </template>\n </dt-button>\n </div>\n </transition>\n </dialog>\n </teleport>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport { DtButton } from '@/components/Button';\nimport { DtText } from '@/components/Text';\nimport { DtIconClose } from '@dialpad/dialtone-icons/vue';\nimport ModeMixin from '@/common/mixins/mode';\nimport {\n MODAL_BANNER_KINDS,\n MODAL_KIND_MODIFIERS,\n} from './ModalConstants';\nimport { getUniqueString, hasSlotContent, returnFirstEl, disableRootScrolling, enableRootScrolling } from '@/common/utils';\nimport { HTML_ELEMENT_TYPE } from '@/common/constants';\nimport SrOnlyCloseButton from '@/common/sr_only_close_button.vue';\nimport { NOTICE_KINDS } from '@/components/Notice';\nimport { DialtoneLocalization } from '@/localization';\n\nconst focusableSelector = 'button:not(:disabled),[href],input:not(:disabled),select:not(:disabled),' +\n 'textarea:not(:disabled),details,[tabindex]:not([tabindex=\"-1\"]):not(:disabled):not([aria-disabled=\"true\"])';\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 DtButton,\n DtText,\n DtIconClose,\n SrOnlyCloseButton,\n },\n\n mixins: [ModeMixin],\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 open: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Header text to display in the modal header.\n */\n headerText: {\n type: String,\n default: undefined,\n },\n\n /**\n * Header text to display in the modal banner.\n */\n bannerHeaderText: {\n type: String,\n default: undefined,\n },\n\n /**\n * The theme of the modal.\n * @values default, critical\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(MODAL_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * Whether the modal fills the viewport instead of rendering at its default size.\n * @values true, false\n */\n fullscreen: {\n type: Boolean,\n default: false,\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, critical, info, positive, warning\n */\n bannerKind: {\n type: String,\n default: 'warning',\n validator (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 * Additional class name for the header 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 headerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the footer 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 footerClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Shows the close button on the modal\n * @values true, false\n */\n showClose: {\n type: Boolean,\n default: true,\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, HTML_ELEMENT_TYPE],\n default: 'first',\n validator: initialFocusElement => {\n return initialFocusElement === 'first' ||\n (initialFocusElement instanceof HTMLElement) ||\n initialFocusElement.startsWith('#');\n },\n },\n\n /**\n * A CSS selector string for the element to portal the modal to. If not provided, the modal will be rendered in its default location.\n */\n appendTo: {\n type: String,\n default: undefined,\n },\n\n /**\n * When true, the surrounding backdrop is rendered fully transparent\n * instead of the default dimming overlay. The dialog box itself\n * remains opaque. Useful when the underlying UI should remain visible.\n * @values true, false\n */\n transparentBackdrop: {\n type: Boolean,\n default: false,\n },\n\n /**\n * When true, the dialog opens with showModal(), which promotes it to the browser\n * top layer. Nothing outside the top layer can paint above it regardless of\n * z-index, so application surfaces such as toasts and call notifications end up\n * behind it. When false, it opens with show() and stays in the normal stacking\n * order, where the Dialtone z-index scale applies and --zi-notification (700)\n * outranks --zi-modal (600) as documented.\n *\n * Focus trapping, scroll locking and Esc-to-close behave identically in both\n * modes. Background inertness does not: only the top layer provides it, so with\n * modal unset the page outside the dialog stays reachable. That is deliberate —\n * it is what lets an application's own overlays remain usable above a modal —\n * and keyboard containment still comes from the focus trap.\n * @values true, false\n */\n modal: {\n type: Boolean,\n default: false,\n },\n },\n\n emits: [\n /**\n * Native button click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n\n /**\n * Native keydown event\n *\n * @event keydown\n * @type {KeyboardEvent}\n */\n 'keydown',\n\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:open\n * @type {Boolean}\n */\n 'update:open',\n ],\n\n data () {\n return {\n MODAL_KIND_MODIFIERS,\n MODAL_BANNER_KINDS,\n hasSlotContent,\n i18n: new DialtoneLocalization(),\n autoTeleportTarget: null,\n mousedownOnBackdrop: false,\n mouseupOnBackdrop: false,\n };\n },\n\n computed: {\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 open (isShowing) {\n this.syncDialogState(isShowing);\n },\n },\n\n mounted () {\n if (!this.appendTo) {\n const root = this.$el?.getRootNode();\n if (root instanceof ShadowRoot) {\n this.autoTeleportTarget = root;\n // Defer syncDialogState so the teleport renders inside the shadow root first.\n if (this.open) this.$nextTick(() => { if (this.open) this.syncDialogState(true); });\n return;\n }\n }\n if (this.open) {\n this.syncDialogState(true);\n }\n },\n\n beforeUnmount () {\n const dialogEl = this.$refs.dialogEl;\n if (dialogEl?.open) {\n dialogEl.close();\n enableRootScrolling(this.getScrollRoot());\n }\n this.previousActiveElement = null;\n },\n\n methods: {\n getScrollRoot () {\n return returnFirstEl(this.$refs.dialogEl)?.getRootNode()?.host;\n },\n\n syncDialogState (isShowing) {\n const dialogEl = this.$refs.dialogEl;\n if (!dialogEl) return;\n\n if (isShowing) {\n this.previousActiveElement = document.activeElement;\n if (!dialogEl.open) {\n // show() leaves the dialog in the normal stacking order instead of the\n // top layer, where the z-index scale still applies.\n if (this.modal) dialogEl.showModal(); else dialogEl.show();\n }\n disableRootScrolling(this.getScrollRoot());\n } else if (dialogEl.open) {\n // Leave transition plays via v-show on inner content.\n // close() is called in onAfterLeave when transition completes.\n enableRootScrolling(this.getScrollRoot());\n }\n },\n\n\n\n close () {\n this.$emit('update:open', false);\n },\n\n onBackdropMousedown (event) {\n this.mousedownOnBackdrop = event.target === event.currentTarget;\n },\n\n onBackdropMouseup (event) {\n this.mouseupOnBackdrop = event.target === event.currentTarget;\n },\n\n onBackdropClick (event) {\n const pressedAndReleasedOnBackdrop = this.mousedownOnBackdrop && this.mouseupOnBackdrop;\n if (this.closeOnClick && event.target === event.currentTarget && pressedAndReleasedOnBackdrop) {\n this.close();\n }\n this.$emit('click', event);\n },\n\n onKeydown (event) {\n // The native cancel event only fires for dialogs opened with showModal(), so\n // Esc has to be handled explicitly to keep dismissal identical in both modes.\n // defaultPrevented means a nested widget (dropdown, combobox) already consumed\n // it to close itself, and the modal must not close out from under it.\n if (!this.modal && event.key === 'Escape' && !event.defaultPrevented) {\n event.preventDefault();\n this.close();\n }\n this.$emit('keydown', event);\n },\n\n async onAfterEnter () {\n this.$emit('update:open', true);\n await this.setFocusAfterTransition();\n },\n\n onAfterLeave () {\n const dialogEl = this.$refs.dialogEl;\n if (dialogEl?.open) {\n dialogEl.close();\n }\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n },\n\n focusFirstTabbable (container) {\n const focusable = [...container.querySelectorAll(focusableSelector)];\n if (!focusable.length) return;\n let target = focusable[0];\n // If first focusable is an unchecked radio, prefer the checked radio in the same group.\n if (target.matches('[type=\"radio\"]:not(:checked)')) {\n target = focusable.find(el => el.checked && el.name === target.name) || target;\n }\n target.focus({ preventScroll: true });\n },\n\n async setFocusAfterTransition () {\n const dialogEl = this.$refs.dialogEl;\n if (!dialogEl) return;\n\n await this.$nextTick();\n\n if (this.initialFocusElement === 'first') {\n this.focusFirstTabbable(dialogEl);\n } else if (typeof this.initialFocusElement === 'string' && this.initialFocusElement.startsWith('#')) {\n const el = dialogEl.querySelector(this.initialFocusElement);\n if (el) {\n el.focus();\n } else {\n // eslint-disable-next-line no-console\n console.warn('Could not find the element specified in dt-modal prop \"initialFocusElement\". ' +\n 'Defaulting to focusing the first element.');\n this.focusFirstTabbable(dialogEl);\n }\n } else if (this.initialFocusElement instanceof HTMLElement) {\n this.initialFocusElement.focus();\n }\n },\n },\n};\n</script>\n"],"mappings":"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"}
|