UNPKG

@progress/kendo-vue-popup

Version:

Kendo UI for Vue Popup package

254 lines (253 loc) 8.71 kB
/** * @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 };