UNPKG

@progress/kendo-vue-layout

Version:
182 lines (181 loc) 7.45 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 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 };