@progress/kendo-vue-layout
Version:
182 lines (181 loc) • 7.45 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 I, createVNode as d } from "vue";
import { canUseDOM as m, Keys as l, setRef as u, templateRendering as a, getListeners as h, getRef as c, validatePackage as p, guid as f } from "@progress/kendo-vue-common";
import { isIdEmptyOrZeroLevel as r, EMPTY_ID as s, ZERO_LEVEL_ZERO_ITEM_ID as o, getRootParentId as v, getItemById as n, getDirectParentId as b } from "../utils/itemsIdsUtils.mjs";
import { prepareInputItemsForInternalWork as g } from "../utils/prepareInputItemsForInternalWork.mjs";
import { getNewItemIdUponKeyboardNavigation as R } from "../utils/getNewItemIdUponKeyboardNavigation.mjs";
import { getHoverCloseDelay as H, getHoverOpenDelay as O } from "../utils/hoverDelay.mjs";
import { DirectionHolder as k } from "../utils/DirectionHolder.mjs";
import { MouseOverHandler as C } from "../utils/MouseOverHandler.mjs";
import { packageMetadata as D } from "../../package-metadata.mjs";
import { MenuItemInternalsList as L } from "./MenuItemInternal.mjs";
const N = /* @__PURE__ */ I({
name: "KendoMenu",
props: {
vertical: {
type: Boolean,
default: !1
},
items: Array,
dir: String,
hoverOpenDelay: {
type: Number,
default: void 0
},
hoverCloseDelay: {
type: Number,
default: void 0
},
openOnClick: Boolean,
onSelect: Function,
itemRender: [String, Object, Function],
linkRender: [String, Object, Function],
customCloseItemIds: Array
},
created() {
p(D), this.mouseOverHandler = new C(this.$props.openOnClick, this.reset, this.onItemMouseOver), this.guid = f(), this.directionHolder = new k(), this.inputItems = [], this.currentItems = [];
},
mounted() {
this.isFirstRender = !1, this.menuWrapperEl = c(this, "menuWrapper");
},
updated() {
this.mouseOverHandler.OpenOnClick = this.$props.openOnClick;
},
unmounted() {
this.clearItemHoverAndLeaveRequestsIfApplicable();
},
data() {
return {
focusedItemId: s,
hoveredItemId: s,
tabbableItemId: o,
isFirstRender: !0
};
},
computed: {
menuClassName() {
return {
"k-widget": !0,
"k-reset": !0,
"k-header": !0,
"k-menu": !0,
"k-menu-horizontal": !this.$props.vertical,
"k-menu-vertical": this.$props.vertical
};
}
},
render() {
this.prepareItems(), this.isFirstRender || this.directionHolder.setIsDirectionRightToLeft(this.checkIsDirectionRightToLeft());
let e = this.hoveredItemId ? this.hoveredItemId : this.focusedItemId ? b(this.focusedItemId) : s;
return d("div", {
class: this.getMenuWrapperClassName(),
ref: u(this, "menuWrapper")
}, [d(L, {
class: this.menuClassName,
"aria-orientation": this.$props.vertical ? "vertical" : void 0,
items: this.currentItems,
isMenuVertical: this.$props.vertical,
isDirectionRightToLeft: this.directionHolder.getIsDirectionRightToLeft(),
focusedItemId: this.focusedItemId,
lastItemIdToBeOpened: e,
tabbableItemId: this.tabbableItemId,
itemRender: a.call(this, this.$props.itemRender, h.call(this)),
linkRender: a.call(this, this.$props.linkRender, h.call(this)),
menuGuid: this.guid,
onMouseleave: this.onItemMouseLeave,
onMouseover: this.onItemMouseOver,
onMousedown: this.onItemMouseDown,
onKeydown: this.onKeyDown,
onFocus: this.onItemFocus,
onClick: this.onItemClick,
onBlur: this.onItemBlur,
originalItemNeeded: this.getInputItem
}, null)]);
},
methods: {
reset() {
this.clearItemHoverAndLeaveRequestsIfApplicable(), this.focusedItemId = s, this.hoveredItemId = s, this.tabbableItemId = o;
},
onKeyDown(e) {
if (this.focusedItemId !== s) {
const t = n(this.focusedItemId, this.currentItems), i = R(this.currentItems, t.id, e.keyCode, e.key, this.$props.vertical, this.directionHolder.getIsDirectionRightToLeft());
t.id !== i && (e.preventDefault(), this.setFocusedItemId(i)), (e.keyCode === l.enter || e.keyCode === l.space) && !t.disabled && (this.mouseOverHandler.handleItemSelectedViaKeyboard(), this.dispatchSelectEventIfWired(e, t.id), !e.defaultPrevented && t.items.length === 0 && t.url && m && window.location.assign(t.url));
}
},
onItemMouseOver(e) {
this.mouseOverHandler.IsMouseOverEnabled && (this.clearItemHoverAndLeaveRequestsIfApplicable(), this.itemHoverRequest = window.setTimeout(() => {
this.setHoveredItemId(e), this.itemHoverRequest = null;
}, O({
...this.$props
})));
},
onItemMouseLeave(e) {
this.mouseOverHandler.IsMouseOverEnabled && this.isItemWithDefaultClose(e) && (this.clearItemHoverAndLeaveRequestsIfApplicable(), this.itemLeaveRequest = window.setTimeout(() => {
this.setHoveredItemId(s), this.itemLeaveRequest = null;
}, H({
...this.$props
})));
},
onItemMouseDown() {
this.mouseOverHandler.handleItemMouseDown();
},
onItemFocus(e) {
this.setFocusedItemId(e), this.mouseOverHandler.handleItemFocus();
},
onItemClick(e, t) {
const i = n(t, this.currentItems);
i.disabled || (this.setFocusedItemId(t), this.mouseOverHandler.handleItemClick(t, this.isItemWithDefaultClose(t)), this.dispatchSelectEventIfWired(e, t), !e.defaultPrevented && i.url && m && window.location.assign(i.url));
},
onItemBlur(e) {
this.isItemWithDefaultClose(e) && this.setFocusedItemId(s);
},
getInputItem(e) {
return n(e, this.inputItems);
},
setFocusedItemId(e) {
const t = e === s ? this.tabbableItemId : v(e), i = e === s || r(this.hoveredItemId) && r(e) ? this.hoveredItemId : s;
this.hoveredItemId = i, this.focusedItemId = e, this.tabbableItemId = t;
},
setHoveredItemId(e) {
r(e) && r(this.focusedItemId) ? this.hoveredItemId = e : (this.hoveredItemId = e, this.focusedItemId = s, this.tabbableItemId = o);
},
getMenuWrapperClassName() {
return {
"k-rtl": this.directionHolder.getIsDirectionRightToLeft()
};
},
clearItemHoverAndLeaveRequestsIfApplicable() {
this.itemHoverRequest && (clearTimeout(this.itemHoverRequest), this.itemHoverRequest = null), this.itemLeaveRequest && (clearTimeout(this.itemLeaveRequest), this.itemLeaveRequest = null);
},
isItemWithDefaultClose(e) {
return !this.$props.customCloseItemIds || this.$props.customCloseItemIds.indexOf(e) === -1;
},
checkIsDirectionRightToLeft() {
return this.$props.dir !== void 0 ? this.$props.dir === "rtl" : this.menuWrapperEl && getComputedStyle(this.menuWrapperEl).direction === "rtl";
},
prepareItems() {
const {
items: e,
inputItems: t
} = g.call(this, this.$props.items);
this.currentItems = e, this.inputItems = t;
},
dispatchSelectEventIfWired(e, t) {
this.$emit("select", {
event: e,
component: this,
item: this.getInputItem(t),
itemId: t
});
}
}
});
export {
N as Menu
};