@progress/kendo-vue-dialogs
Version:
377 lines (376 loc) • 15.2 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2026 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import { defineComponent as D, createVNode as r } from "vue";
import { WindowTitleBar as C } from "./WindowTitlebar.mjs";
import { templateRendering as c, getListeners as u, getDefaultSlots as W, WatermarkOverlay as T, Draggable as B, guid as H, Keys as s, validatePackage as M, shouldShowValidationUI as k, getLicenseMessage as b } from "@progress/kendo-vue-common";
import { ResizeHandlers as N } from "./WindowResizeHandlers.mjs";
import { windowStage as e } from "./StageEnum.mjs";
import { packageMetadata as m } from "./package-metadata.mjs";
import { DEFAULT_DIALOGS_ZINDEX as F } from "./constants.mjs";
const I = 300, $ = 300, S = 120, L = 100, o = 5, O = /* @__PURE__ */ D({
name: "KendoWindow",
emits: {
resize: (t) => !0,
move: (t) => !0,
close: (t) => !0,
stagechange: (t) => !0,
overlayclick: null
},
provide() {
return {
kCurrentZIndex: F
};
},
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: S
},
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;
}
},
dir: String
},
created() {
M(m), this.showLicenseWatermark = k(m), this.licenseMessage = b(m), this.windowCoordinatesState = {
leftBeforeAction: this.getInitialLeft(),
topBeforeAction: this.getInitialTop(),
widthBeforeAction: this.getInitialWidth(),
heightBeforeAction: this.getInitialHeight()
}, this.titleId = this.generateTitleId();
},
beforeUnmount() {
var t;
(t = this.windowWrapper) != null && t.parentNode && 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,
licenseMessage: void 0
};
},
mounted() {
window && window.addEventListener("resize", this.handleBrowserWindowResize);
const t = this.$props.appendTo ? document.querySelector(this.$props.appendTo) : document.body;
t && (this.windowWrapper = this.$el, t.appendChild(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
} = this.$props;
return {
"k-window": !0,
[t]: t,
"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 || S, n = this.$props.minHeight || L;
if (t.ctrlKey && this.$props.resizable) {
switch (t.keyCode) {
case s.up:
t.preventDefault(), n <= this.computedHeight - o && (this.currentHeight = this.currentHeight - o);
break;
case s.down:
t.preventDefault(), this.currentHeight = this.currentHeight + o;
break;
case s.left:
i <= this.computedWidth - o && (this.currentWidth = this.currentWidth - o);
break;
case s.right:
this.currentWidth = this.currentWidth + o;
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 - o;
break;
case s.down:
t.preventDefault(), this.currentTop = this.currentTop + o;
break;
case s.left:
t.preventDefault(), this.currentLeft = this.currentLeft - o;
break;
case s.right:
t.preventDefault(), this.currentLeft = this.currentLeft + o;
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 = $;
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 = I;
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 = I;
return this.$props.width !== void 0 ? t = this.$props.width : this.$props.initialWidth !== void 0 && (t = this.$props.initialWidth), t;
},
getInitialHeight() {
let t = $;
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 || S, l = this.$props.minHeight || L, a = this.computedTop - t.pageY, d = this.computedLeft - t.pageX, p = t.pageX - this.computedLeft, w = 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 - w < 0 && (this.currentHeight = w), 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-" + H();
}
},
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 = W(this), a = l || [], d = this.getActionBarIndex(a);
let p;
d !== -1 && (p = a[d], a.splice(d, 1));
const w = this.showLicenseWatermark ? r(T, {
message: this.licenseMessage
}, null) : null, E = r("div", {
class: this.wrapperClass,
ref: "wrapper",
dir: this.$props.dir
}, [this.$props.modal && r("div", {
class: "k-overlay",
onClick: this.handleClick
}, null), r("div", {
tabindex: 0,
onFocus: (f) => f.target.classList.add("k-focus"),
onBlur: (f) => f.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.$props.title !== void 0 || t ? this.titleId : void 0,
style: {
top: this.computedTop + "px",
left: this.computedLeft + "px",
width: this.computedWidth + "px",
height: this.windowStage !== e.MINIMIZED ? this.computedHeight + "px" : void 0,
overflow: this.windowStage !== e.MINIMIZED ? "hidden" : void 0,
...this.$props.windowStyle
}
}, [r(B, {
onPress: this.onPress,
onDrag: this.onDrag,
onRelease: this.onRelease,
ref: "draggable"
}, {
default: () => [r(C, {
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)]
}), [r("div", {
class: this.windowStage === e.MINIMIZED ? "k-window-content k-hidden" : "k-window-content"
}, [l]), this.windowStage !== e.MINIMIZED ? p : null], this.windowStage === e.DEFAULT && this.$props.resizable ? r(N, {
onResize: this.handleResize
}, null) : null, w])]);
return this.$props.appendTo ? r("div", null, [E]) : E;
}
});
export {
O as Window
};