@progress/kendo-vue-popup
Version:
Kendo UI for Vue Popup package
254 lines (253 loc) • 8.71 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import { defineComponent as A, createVNode as f, isVNode as C } from "vue";
import { Slide as E } from "@progress/kendo-vue-animation";
import { isWindowAvailable as m, throttle as y, AlignPoint as h, CollisionType as _, FRAME_DURATION as S } from "./util.mjs";
import { AlignService as b } from "./services/alignService.mjs";
import { DOMService as P } from "./services/domService.mjs";
import { PositionService as w } from "./services/positionService.mjs";
import { getDefaultSlots as g, canUseDOM as u, validatePackage as O } from "@progress/kendo-vue-common";
import { packageMetadata as T } from "./package-metadata.mjs";
function x(t) {
return typeof t == "function" || Object.prototype.toString.call(t) === "[object Object]" && !C(t);
}
const D = 100, N = 1, k = {
left: -1e3,
top: 0
}, v = "k-animation-container-shown", $ = "k-popup", F = /* @__PURE__ */ A({
name: "Popup",
props: {
appendTo: {
type: String,
default: ""
},
anchor: {
type: [String, Object],
default: ""
},
className: String,
id: String,
popupClass: String,
collision: {
type: Object,
default: function() {
return {
horizontal: _.fit,
vertical: _.flip
};
}
},
anchorAlign: {
type: Object,
default: function() {
return {
horizontal: h.left,
vertical: h.bottom
};
}
},
popupAlign: {
type: Object,
default: function() {
return {
horizontal: h.left,
vertical: h.top
};
}
},
offset: {
type: Object,
default: function() {
return k;
}
},
show: {
type: Boolean,
default: !1
},
animate: {
type: [Boolean, Object],
default: !0
},
direction: {
type: String,
default: "down"
},
onOpen: Function,
onClose: Function
},
inject: {
kCurrentZIndex: {
default: null
}
},
data() {
return {
hasMounted: !1
};
},
created() {
O(T), this.mountedAppendTo = void 0, this.mountedAnchor = void 0, this._clonedElement = void 0, this._flipped = !1, this._offsetTop = 0, this._offsetLeft = -1e3, this._exitingAnimation = !1, this._prevShow = !1, this._prevShow = this.$props.show, this._domService = new P(), this._alignService = new b(this._domService), this._positionService = new w(this._domService), this.reposition = y(this.reposition.bind(this), S);
},
mounted() {
u && (this.mountedAppendTo = this.appendTo ? this.getParentRef(this.appendTo) : document.body, this.mountedAnchor = this.anchor ? this.getParentRef(this.anchor, !0) : document.body), this._parentElement = this.$el.parentElement, this._clonedElement = this.$el.cloneNode(!0), this.hasMounted = !0, this.mountedAppendTo.appendChild(this.$el);
},
updated() {
this._prevShow = this.$props.show;
},
unmounted() {
this.detachRepositionHandlers();
},
beforeUnmount() {
this._parentElement && this._parentElement.appendChild(this.$el);
},
methods: {
onOpened() {
const t = this.$el;
this.$props.show && t.classList.add(v), this.attachRepositionHandlers(t), this.$emit("open", {
target: this
});
},
onClosing() {
this.$props.show || this.$el.classList.remove(v), this.detachRepositionHandlers();
},
onClosed() {
this._exitingAnimation && (this._exitingAnimation = !1, this.$forceUpdate()), this.$emit("close", {
target: this
});
},
transitionDuration() {
const t = this.$props.animate;
let i = 0, e = 0;
return t && (t === !0 ? i = e = void 0 : (i = t.openDuration, e = t.closeDuration)), {
transitionEnterDuration: i,
transitionExitDuration: e
};
},
getParentRef(t, i) {
let e = this.$parent;
for (; !e.$refs[t]; ) {
if (e && e.kendoAnchorRef && i)
return e.kendoAnchorRef;
if (e = e.$parent, !e && u)
return document.getElementById(t) || document.body;
}
return e.$refs[t].$el || e.$refs[t];
},
position(t, i, e) {
const {
anchorAlign: n,
popupAlign: s,
collision: r,
offset: a
} = t, o = e ? this.mountedAnchor : document.body, l = this._alignService.alignElement({
anchor: e ? o : void 0,
element: i,
elementAlign: s,
anchorAlign: n,
offset: a
});
return this._positionService.positionElement({
anchor: o,
anchorAlign: n,
collisions: r,
element: i,
currentLocation: l,
elementAlign: s
});
},
calculatePosition(t, i) {
if (!i || !m() || !u)
return {
flipped: !1,
offset: t.offset
};
const e = g(this), n = document.createElement("div"), s = this.$el && this.$el.firstChild && this.$el.firstChild.firstChild ? this.$el.firstChild.firstChild.cloneNode(!0) : null, r = s && s.getBoundingClientRect ? s : this._clonedElement;
if (r)
n.appendChild(r);
else {
const o = e && e[0].props ? e[0].props.class : "", l = this.$props.popupClass;
n.innerHTML = `<div class="k-animation-container k-animation-container-relative">
<div class="k-popup k-animation-container k-animation-container-relative">
<div class="${o} ${l}" >
</div>
</div>
</div>`;
}
if (i.appendChild(n), n && n.firstChild) {
const o = n.firstChild;
o.style.position = "absolute", o.style.visibility = "hidden", o.style.display = "block", o.style.left = "-1000", o.style.top = "0";
const l = e && e[0].props ? e[0].props.style : {};
if (l)
for (const [p, c] of Object.entries(l))
o.style[p] = c;
}
const a = this.position(t, n.firstChild, this.$props.anchor);
return n.parentNode.removeChild(n), a;
},
attachRepositionHandlers(t) {
this.detachRepositionHandlers(), this._scrollableParents = this._domService.scrollableParents(this.$props.anchor ? this.mountedAnchor : t), this._scrollableParents.map((i) => i.addEventListener("scroll", this.reposition)), window.addEventListener("resize", this.reposition);
},
detachRepositionHandlers() {
this._scrollableParents && (this._scrollableParents.map((t) => t.removeEventListener("scroll", this.reposition)), this._scrollableParents = void 0), window.removeEventListener("resize", this.reposition);
},
reposition() {
this._clonedElement = this.$el.cloneNode(!0), this.$forceUpdate();
},
getCurrentZIndex() {
return this.kCurrentZIndex ? this.kCurrentZIndex + N : D;
}
},
render() {
const {
className: t,
popupClass: i,
show: e,
id: n
} = this.$props, s = g(this), r = s, a = m() ? this.$props.appendTo ? this.mountedAppendTo || this.getParentRef(this.$props.appendTo) : document.body : void 0;
if (this.$props.show) {
const d = this.calculatePosition(this.$props, a);
this._offsetLeft = d.offset.left, this._offsetTop = d.offset.top, this._flipped = !!d.flipped;
}
const o = this.$props.direction === "down" ? this._flipped ? "up" : "down" : this._flipped ? "down" : "up", {
transitionEnterDuration: l,
transitionExitDuration: p
} = this.transitionDuration(), c = this.getCurrentZIndex();
return this._exitingAnimation = this._exitingAnimation || this._prevShow && !e, this.hasMounted ? e || this._exitingAnimation && a ? f(E, {
id: n,
role: this.appendTo ? "" : "region",
componentChildClassName: [i, $],
className: t,
onEntered: this.onOpened,
onExiting: this.onClosing,
onExited: this.onClosed,
direction: o,
style: {
zIndex: c,
position: "absolute",
top: this._offsetTop + "px",
left: this._offsetLeft + "px"
},
transitionEnterDuration: l,
transitionExitDuration: p,
appear: e
}, x(r) ? r : {
default: () => [r]
}) : null : f("div", {
style: {
display: "none"
},
class: t
}, [f("div", {
class: [i, $]
}, [s])]);
}
});
export {
F as Popup
};