@progress/kendo-vue-dialogs
Version:
382 lines (381 loc) • 15 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 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
};