@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
223 lines (222 loc) • 6.61 kB
JavaScript
import { ref as o, onMounted as O, nextTick as h, onBeforeUnmount as P, watch as b, createBlock as C, openBlock as S, unref as A, withCtx as u, renderSlot as i, normalizeProps as D, guardReactiveProps as E } from "vue";
import { getUniqueString as M } from "../../common/utils/index.js";
import { TOOLTIP_DELAY_MS as y, TOOLTIP_DIRECTIONS as k } from "../tooltip/tooltip-constants.js";
import L from "../popover/popover.js";
import { POPOVER_APPEND_TO_VALUES as I, POPOVER_PADDING_CLASSES as $ } from "../popover/popover-constants.js";
const U = {
__name: "hovercard",
props: {
/**
* Fade transition when the content display is toggled.
* @type boolean
* @values true, false
*/
transition: {
type: Boolean,
default: !1
},
/**
* Controls whether the hovercard is shown. Leaving this null will have the hovercard trigger on hover by default.
* If you set this value, the default trigger behavior will be disabled, and you can control it as you need.
* Supports .sync modifier
* @values null, true, false
*/
open: {
type: Boolean,
default: null
},
/**
* If the popover does not fit in the direction described by "placement",
* it will attempt to change its direction to the "fallbackPlacements".
* @see https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements"
*/
fallbackPlacements: {
type: Array,
default: () => ["auto"]
},
/**
* The direction the popover displays relative to the anchor.
* @see https://atomiks.github.io/tippyjs/v6/all-props/#placement"
* @values top, top-start, top-end,
* right, right-start, right-end,
* left, left-start, left-end,
* bottom, bottom-start, bottom-end,
* auto, auto-start, auto-end
*/
placement: {
type: String,
default: "top-start",
validator(e) {
return k.includes(e);
}
},
/**
* Padding size class for the popover content.
* @values none, small, medium, large
*/
padding: {
type: String,
default: "large",
validator: (e) => Object.keys($).some((a) => a === e)
},
/**
* Displaces the content box from its anchor element
* by the specified number of pixels.
* @see https://atomiks.github.io/tippyjs/v6/all-props/#offset"
*/
offset: {
type: Array,
default: () => [0, 16]
},
/**
* The id of the tooltip
*/
id: {
type: String,
default() {
return M();
}
},
/**
* Additional class name for the header content wrapper element.
*/
headerClass: {
type: [String, Array, Object],
default: ""
},
/**
* Additional class name for the footer content wrapper element.
*/
footerClass: {
type: [String, Array, Object],
default: ""
},
/**
* Additional class name for the dialog element.
*/
dialogClass: {
type: [String, Array, Object],
default: ""
},
/**
* Additional class name for the content wrapper element.
*/
contentClass: {
type: [String, Array, Object],
default: ""
},
/**
* Sets the element to which the popover is going to append to.
* 'body' will append to the nearest body (supports shadow DOM).
* @values 'body', 'parent', HTMLElement,
*/
appendTo: {
type: [HTMLElement, String],
default: "body",
validator: (e) => I.includes(e) || e instanceof HTMLElement
},
/**
* The enter delay in milliseconds before the hovercard is shown.
* @type number
*/
enterDelay: {
type: Number,
default: y
},
/**
* The leave delay in milliseconds before the hovercard is hidden.
* @type number
*/
leaveDelay: {
type: Number,
default: y
}
},
emits: [
/**
* Emitted when hovercard is shown or hidden
*
* @event opened
* @type {Boolean | Array}
*/
"opened"
],
setup(e) {
const a = e, l = o(a.open), d = o(null), c = o(null), f = o(null), s = o(null), m = o(null);
O(() => {
h(() => {
var t, r, n;
f.value = (n = (r = (t = m.value) == null ? void 0 : t.$refs) == null ? void 0 : r.anchor) == null ? void 0 : n.firstElementChild, s.value = new MutationObserver(() => {
f.value && !f.value.isConnected && (l.value = !1);
}), s.value.observe(document.body, {
childList: !0,
subtree: !0
});
});
}), P(() => {
s.value && s.value.disconnect(), clearTimeout(d), clearTimeout(c);
}), b(() => a.open, (t) => {
l.value = t;
}, { immediate: !0 });
function g() {
d.value = setTimeout(() => {
l.value = !0;
}, a.enterDelay);
}
function T() {
c.value = setTimeout(() => {
l.value = !1;
}, a.leaveDelay);
}
function v() {
a.open === null && (clearTimeout(c.value), g());
}
function p() {
a.open === null && (clearTimeout(d.value), T());
}
return (t, r) => (S(), C(A(L), {
id: e.id,
ref_key: "popover",
ref: m,
open: l.value,
placement: e.placement,
"content-class": e.contentClass,
"dialog-class": e.dialogClass,
"fallback-placements": e.fallbackPlacements,
padding: e.padding,
transition: e.transition ? "fade" : null,
offset: e.offset,
modal: !1,
"initial-focus-element": "none",
"header-class": e.headerClass,
"footer-class": e.footerClass,
"append-to": e.appendTo,
"data-qa": "dt-hovercard",
"enter-delay": e.enterDelay,
"leave-delay": e.leaveDelay,
onOpened: r[0] || (r[0] = (n) => t.$emit("opened", n)),
onMouseenterPopover: v,
onMouseleavePopover: p,
onMouseenterPopoverAnchor: v,
onMouseleavePopoverAnchor: p
}, {
anchor: u(({ attrs: n }) => [
i(t.$slots, "anchor", D(E(n)))
]),
content: u(() => [
i(t.$slots, "content")
]),
headerContent: u(() => [
i(t.$slots, "headerContent")
]),
footerContent: u(() => [
i(t.$slots, "footerContent")
]),
_: 3
}, 8, ["id", "open", "placement", "content-class", "dialog-class", "fallback-placements", "padding", "transition", "offset", "header-class", "footer-class", "append-to", "enter-delay", "leave-delay"]));
}
};
export {
U as default
};
//# sourceMappingURL=hovercard.js.map