UNPKG

@progress/kendo-vue-dialogs

Version:
382 lines (381 loc) 15 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 C, createVNode as o } from "vue"; import { WindowTitleBar as D } from "./WindowTitlebar.mjs"; import { validatePackage as T, shouldShowValidationUI as W, Keys as s, guid as B, templateRendering as c, getListeners as u, getDefaultSlots as H, WatermarkOverlay as k, Draggable as b } from "@progress/kendo-vue-common"; import { ResizeHandlers as F } from "./WindowResizeHandlers.mjs"; import { windowStage as e } from "./StageEnum.mjs"; import { packageMetadata as E } from "./package-metadata.mjs"; import { DEFAULT_DIALOGS_ZINDEX as N } from "./constants.mjs"; const $ = 300, I = 300, m = 120, L = 100, r = 5, O = /* @__PURE__ */ C({ name: "KendoWindow", emits: { resize: null, move: null, close: null, stagechange: null, overlayclick: null }, provide() { return { kCurrentZIndex: N }; }, props: { id: String, appendTo: String, width: { type: [Number], default: void 0 }, height: { type: [Number], default: void 0 }, left: { type: [Number], default: void 0 }, windowStyle: Object, windowClass: String, top: { type: [Number], default: void 0 }, initialWidth: [Number], initialHeight: [Number], initialLeft: [Number], initialTop: [Number], minWidth: { type: [Number], default: m }, minHeight: { type: [Number], default: L }, resizable: { type: Boolean, default: !0 }, draggable: { type: Boolean, default: !0 }, modal: { type: Boolean, default: !1 }, doubleClickStageChange: { type: Boolean, default: !0 }, title: String, titleRender: [String, Function], closeButton: [String, Function], minimizeButton: [String, Function], maximizeButton: [String, Function], restoreButton: [String, Function], shouldUpdateOnDrag: Boolean, stage: { type: String, validator: function(t) { return ["DEFAULT", "MINIMIZED", "FULLSCREEN"].indexOf(t) !== -1; } }, themeColor: { type: String, validator: function(t) { return [void 0, "primary", "dark", "light"].includes(t); } }, dir: String }, created() { T(E), this.showLicenseWatermark = W(E), this.windowCoordinatesState = { leftBeforeAction: this.getInitialLeft(), topBeforeAction: this.getInitialTop(), widthBeforeAction: this.getInitialWidth(), heightBeforeAction: this.getInitialHeight() }, this.titleId = this.generateTitleId(); }, beforeUnmount() { this.$props.appendTo && this.windowWrapper.remove(); }, data() { return { currentStage: this.$props.stage || e.DEFAULT, isDragging: !1, currentTop: this.getInitialTop(), currentLeft: this.getInitialLeft(), currentWidth: this.getInitialWidth(), currentHeight: this.getInitialHeight(), titleId: void 0, showLicenseWatermark: !1 }; }, mounted() { if (window && (window.addEventListener("resize", this.handleBrowserWindowResize), this.$props.appendTo)) { const t = document.querySelector(this.$props.appendTo); this.windowWrapper = this.$refs.wrapper, t.append(this.windowWrapper); } this.$el && (this.windowElement = this.$refs.windowElement); }, unmounted() { window && window.removeEventListener("resize", this.handleBrowserWindowResize); }, computed: { wrapperClass() { return { "k-dialog-wrapper": this.$props.modal }; }, windowElementClass() { const { windowClass: t, themeColor: i } = this.$props; return { "k-window": !0, [t]: t, [`k-window-${i}`]: i, "k-window-minimized": this.currentStage === "MINIMIZED" }; }, computedTop() { return this.windowStage !== e.FULLSCREEN ? Math.max(this.$props.top || this.currentTop, 0) : 0; }, computedLeft() { return this.windowStage !== e.FULLSCREEN ? Math.max(this.$props.left || this.currentLeft, 0) : 0; }, computedWidth() { let t = this.$props.width || this.currentWidth; return this.windowStage === e.FULLSCREEN && (t = window.innerWidth), t; }, computedHeight() { let t = this.$props.height || this.currentHeight; return this.windowStage === e.FULLSCREEN ? t = window.innerHeight : this.windowStage === e.MINIMIZED && (t = 0), t; }, windowStage() { return this.$props.stage || this.currentStage; } }, methods: { onPress(t) { const i = t; this.windowCoordinatesState.differenceLeft = i.pageX - this.computedLeft, this.windowCoordinatesState.differenceTop = i.pageY - this.computedTop; }, onDrag(t) { const i = t; i.originalEvent.preventDefault(), this.windowStage !== e.FULLSCREEN && this.$props.draggable && (this.currentTop = Math.max(i.pageY - this.windowCoordinatesState.differenceTop, 0), this.currentLeft = i.pageX - this.windowCoordinatesState.differenceLeft, this.isDragging = !0, this.dispatchMoveEvent("move", i, !0, !1)); }, onRelease(t) { const i = t; this.windowStage !== e.FULLSCREEN && this.$props.draggable && this.dispatchMoveEvent("move", i, !0, !0), this.isDragging = !1; }, handleKeyDown(t) { if (t.target !== t.currentTarget) return; const i = this.$props.minWidth || m, n = this.$props.minHeight || L; if (t.ctrlKey && this.$props.resizable) { switch (t.keyCode) { case s.up: t.preventDefault(), n <= this.computedHeight - r && (this.currentHeight = this.currentHeight - r); break; case s.down: t.preventDefault(), this.currentHeight = this.currentHeight + r; break; case s.left: i <= this.computedWidth - r && (this.currentWidth = this.currentWidth - r); break; case s.right: this.currentWidth = this.currentWidth + r; break; default: return; } this.dispatchMoveEvent("resize", t, !1, void 0); return; } if (t.altKey) { switch (t.keyCode) { case s.up: this.windowStage === e.MINIMIZED ? (this.handleRestore(t), this.$emit("stagechange", t, this, { state: e.DEFAULT })) : this.windowStage === e.DEFAULT && (this.handleFullscreen(t), this.$emit("stagechange", t, this, { state: e.FULLSCREEN })); break; case s.down: this.windowStage === e.FULLSCREEN ? (this.handleRestore(t), this.$emit("stagechange", t, this, { state: e.DEFAULT })) : this.windowStage === e.DEFAULT && (this.handleMinimize(t), this.$emit("stagechange", t, this, { state: e.MINIMIZED })); break; } return; } if (!t.ctrlKey) switch (t.keyCode) { case s.esc: this.handleCloseWindow(t); return; case s.up: t.preventDefault(), this.currentTop = this.currentTop - r; break; case s.down: t.preventDefault(), this.currentTop = this.currentTop + r; break; case s.left: t.preventDefault(), this.currentLeft = this.currentLeft - r; break; case s.right: t.preventDefault(), this.currentLeft = this.currentLeft + r; break; default: return; } this.dispatchMoveEvent("move", t, !1, void 0); }, getInitialTop() { if (this.$props.top !== void 0) return this.$props.top; if (this.$props.initialTop !== void 0) return this.$props.initialTop; let t = I; return this.$props.height !== void 0 ? t = this.$props.height : this.$props.initialHeight !== void 0 && (t = this.$props.initialHeight), window.innerHeight / 2 - t / 2; }, getInitialLeft() { if (this.$props.left !== void 0) return this.$props.left; if (this.$props.initialLeft !== void 0) return this.$props.initialLeft; let t = $; return this.$props.width !== void 0 ? t = this.$props.width : this.$props.initialWidth !== void 0 && (t = this.$props.initialWidth), window.innerWidth / 2 - t / 2; }, getInitialWidth() { let t = $; return this.$props.width !== void 0 ? t = this.$props.width : this.$props.initialWidth !== void 0 && (t = this.$props.initialWidth), t; }, getInitialHeight() { let t = I; return this.$props.height !== void 0 ? t = this.$props.height : this.$props.initialHeight !== void 0 && (t = this.$props.initialHeight), t; }, handleMinimize(t) { t.preventDefault(), this.windowCoordinatesState.leftBeforeAction = this.computedLeft, this.windowCoordinatesState.topBeforeAction = this.computedTop, this.windowCoordinatesState.widthBeforeAction = this.computedWidth, this.windowCoordinatesState.heightBeforeAction = this.computedHeight, this.currentStage = e.MINIMIZED, this.currentHeight = 0, this.$emit("stagechange", t, this, { state: e.MINIMIZED }); }, handleFullscreen(t) { t.preventDefault(), this.windowCoordinatesState.leftBeforeAction = this.computedLeft, this.windowCoordinatesState.topBeforeAction = this.computedTop, this.windowCoordinatesState.widthBeforeAction = this.computedWidth, this.windowCoordinatesState.heightBeforeAction = this.computedHeight, this.currentLeft = 0, this.currentTop = 0, this.currentWidth = window.innerWidth, this.currentHeight = window.innerHeight, this.currentStage = e.FULLSCREEN, this.$emit("stagechange", t, this, { state: e.FULLSCREEN }); }, handleRestore(t) { t.preventDefault(), this.windowStage === e.FULLSCREEN ? (this.currentStage = e.DEFAULT, this.currentLeft = this.windowCoordinatesState.leftBeforeAction, this.currentTop = this.windowCoordinatesState.topBeforeAction, this.currentWidth = this.windowCoordinatesState.widthBeforeAction, this.currentHeight = this.windowCoordinatesState.heightBeforeAction) : this.windowStage === e.MINIMIZED && (this.currentStage = e.DEFAULT, this.currentHeight = this.windowCoordinatesState.heightBeforeAction), this.$emit("stagechange", t, this, { state: e.DEFAULT }); }, handleCloseWindow(t) { t.preventDefault(), this.$emit("close", t, this, { state: void 0 }); }, handleDoubleClick(t) { this.$props.doubleClickStageChange && (this.windowStage === e.FULLSCREEN || this.windowStage === e.MINIMIZED ? this.handleRestore(t) : this.handleFullscreen(t)); }, handleResize(t, i) { const n = this.computedWidth, h = this.computedHeight, g = this.$props.minWidth || m, l = this.$props.minHeight || L, a = this.computedTop - t.pageY, d = this.computedLeft - t.pageX, p = t.pageX - this.computedLeft, f = t.pageY - this.computedTop; this.isDragging = !i.end, i.direction.indexOf("n") >= 0 && l - (h + a) < 0 && (this.currentTop = t.pageY, this.currentHeight = h + a), i.direction.indexOf("s") >= 0 && l - f < 0 && (this.currentHeight = f), i.direction.indexOf("w") >= 0 && g - (n + d) < 0 && (this.currentLeft = t.pageX, this.currentWidth = n + d), i.direction.indexOf("e") >= 0 && g - p < 0 && (this.currentWidth = p), this.dispatchMoveEvent("resize", t, !0, i.end); }, dispatchMoveEvent(t, i, n, h) { this.$emit(t, { event: i.event, drag: n, end: h, target: this, left: this.currentLeft, top: this.currentTop, width: this.currentWidth, height: this.currentHeight }); }, handleBrowserWindowResize() { this.windowStage === e.FULLSCREEN && (this.currentWidth = window.innerWidth, this.currentHeight = window.innerHeight); }, handleClick(t) { this.$emit("overlayclick", t); }, getActionBarIndex(t) { return t.findIndex((n) => n && n.tag && n.tag.toLowerCase().indexOf("dialogactionsbar") !== -1 || n.componentOptions && n.componentOptions.tag && n.componentOptions.tag.toLowerCase().indexOf("actions-bar") !== -1 || n.type && n.type.name && n.type.name.toLowerCase().indexOf("dialogactionsbar") !== -1); }, generateTitleId() { return "window-title-" + B(); } }, render() { const t = c.call(this, this.$props.titleRender, u.call(this)), i = c.call(this, this.$props.closeButton, u.call(this)), n = c.call(this, this.$props.minimizeButton, u.call(this)), h = c.call(this, this.$props.maximizeButton, u.call(this)), g = c.call(this, this.$props.restoreButton, u.call(this)), l = H(this), a = l || [], d = this.getActionBarIndex(a); let p; d !== -1 && (p = a[d], a.splice(d, 1)); const f = this.showLicenseWatermark ? o(k, null, null) : null, S = o("div", { class: this.wrapperClass, ref: "wrapper", dir: this.$props.dir }, [this.$props.modal && o("div", { class: "k-overlay", onClick: this.handleClick }, null), o("div", { tabindex: 0, onFocus: (w) => w.target.classList.add("k-focus"), onBlur: (w) => w.target.classList.remove("k-focus"), onKeydown: this.handleKeyDown, ref: "windowElement", class: this.windowElementClass, role: "dialog", "aria-modal": this.$props.modal ? !0 : void 0, "aria-labelledby": this.titleId, style: { top: this.computedTop + "px", left: this.computedLeft + "px", width: this.computedWidth + "px", height: this.computedHeight + "px" || "", ...this.$props.windowStyle } }, [o(b, { onPress: this.onPress, onDrag: this.onDrag, onRelease: this.onRelease, ref: "draggable" }, { default: () => [o(D, { stage: this.windowStage, title: this.$props.title, titleId: this.titleId, titleRender: t, onDoubleclick: this.handleDoubleClick, onMinimizeclick: this.handleMinimize, onFullscreenclick: this.handleFullscreen, onRestoreclick: this.handleRestore, onCloseclick: this.handleCloseWindow, closeButton: i, minimizeButton: n, maximizeButton: h, restoreButton: g }, null)] }), this.windowStage !== e.MINIMIZED ? [o("div", { class: "k-window-content" }, [l]), p] : null, this.windowStage === e.DEFAULT && this.$props.resizable ? o(F, { onResize: this.handleResize }, null) : null, f])]); return this.$props.appendTo ? o("div", null, [S]) : S; } }); export { O as Window };