UNPKG

@progress/kendo-react-layout

Version:

React Layout components enable you to create a perceptive and intuitive layout of web projects. KendoReact Layout package

243 lines (242 loc) 9.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 * as s from "react"; import { getActiveElement as u, IconWrap as h, classNames as p } from "@progress/kendo-react-common"; import { Popup as c } from "@progress/kendo-react-popup"; import { shouldOpenItem as I, isFirstItemFromSiblings as M } from "../utils/itemsIdsUtils.mjs"; import { getDOMElementId as d, convertBoolDirectionToString as m, getPopupSettings as g } from "../utils/misc.mjs"; import { MenuItemLink as f } from "./MenuItemLink.mjs"; import { MenuItemArrow as v } from "./MenuItemArrow.mjs"; class k extends s.Component { constructor() { super(...arguments), this.onMouseOver = (e) => { this.props.onMouseOver(this.props.parentItemId), e.stopPropagation(); }, this.onMouseLeave = (e) => { this.props.onMouseLeave(this.props.parentItemId), e.stopPropagation(); }; } render() { const e = this.props.parentItemId; return /* @__PURE__ */ s.createElement( "ul", { className: this.props.className, role: this.props.role ? this.props.role : e !== void 0 ? "menu" : "menubar", id: e !== void 0 ? d(this.props.menuGuid, e) : void 0, onMouseOver: e !== void 0 ? this.onMouseOver : void 0, onMouseLeave: e !== void 0 ? this.onMouseLeave : void 0, "aria-orientation": this.props["aria-orientation"] }, this.renderChildItems() ); } renderChildItems() { return this.props.items.length > 0 ? this.props.items.map((e, t) => /* @__PURE__ */ s.createElement( O, { item: e, animate: this.props.animate, isMenuVertical: this.props.isMenuVertical, isDirectionRightToLeft: this.props.isDirectionRightToLeft, focusedItemId: this.props.focusedItemId, lastItemIdToBeOpened: this.props.lastItemIdToBeOpened, tabbableItemId: this.props.tabbableItemId, itemRender: this.props.itemRender, linkRender: this.props.linkRender, menuGuid: this.props.menuGuid, onMouseOver: this.props.onMouseOver, onMouseLeave: this.props.onMouseLeave, onMouseDown: this.props.onMouseDown, onBlur: this.props.onBlur, onFocus: this.props.onFocus, onClick: this.props.onClick, onOriginalItemNeeded: this.props.onOriginalItemNeeded, key: t } )) : null; } } class O extends s.Component { constructor(e) { super(e), this.isFirstRender = !0, this.onMouseOver = (t) => { this.props.onMouseOver(this.props.item.id), t.stopPropagation(); }, this.onMouseLeave = (t) => { this.props.onMouseLeave(this.props.item.id), t.stopPropagation(); }, this.state = { opened: !1 }; } componentDidMount() { const e = this.props.focusedItemId, t = this.props.item.id; e && e === t && this.itemElement.focus({ preventScroll: !0 }), this.isFirstRender = !1; } componentDidUpdate(e) { const t = this.props.focusedItemId, o = this.props.item.id; if (t) { const n = u(document); e.focusedItemId !== t && t === o && // https://github.com/telerik/kendo-react/issues/216 : // No need to focus the wrapping menu item DOM element // when a child DOM element was clicked. !this.itemElement.contains(n) && this.itemElement.focus({ preventScroll: !0 }); } } render() { const e = this.props.item, t = e.id, o = d(this.props.menuGuid, t), n = e.separator; return /* @__PURE__ */ s.createElement(s.Fragment, null, n ? /* @__PURE__ */ s.createElement( "li", { className: "k-separator k-item", "aria-hidden": !0, key: o, id: o, ref: (i) => { this.itemElement = i; } } ) : /* @__PURE__ */ s.createElement( "li", { id: o, className: this.getMenuItemClassName(e), style: e.cssStyle, tabIndex: t === this.props.tabbableItemId ? 0 : -1, onMouseOver: this.onMouseOver, onMouseLeave: this.onMouseLeave, onMouseDown: (i) => this.props.onMouseDown(i), onBlur: (i) => this.props.onBlur(t, i), onFocus: () => this.props.onFocus(t), onClick: (i) => this.props.onClick(i, t), role: "menuitem", "aria-disabled": e.disabled ? !0 : void 0, "aria-haspopup": e.items.length > 0 ? !0 : void 0, "aria-expanded": e.items.length > 0 ? this.Opened : void 0, "aria-label": e.text, "aria-owns": this.Opened ? o : void 0, ref: (i) => { this.itemElement = i; }, key: o }, this.contentRender ? this.renderContent() : this.renderMenuItemLink() ), this.renderPopupIfOpened()); } renderContent() { const e = this.props.item.contentParentItemId; return /* @__PURE__ */ s.createElement("div", { className: "k-content", role: "presentation" }, /* @__PURE__ */ s.createElement(this.contentRender, { item: this.props.onOriginalItemNeeded(e), itemId: e })); } renderMenuItemLink() { const e = this.props.item; if (this.linkRender) return /* @__PURE__ */ s.createElement( this.linkRender, { item: this.props.onOriginalItemNeeded(e.id), itemId: e.id, opened: this.Opened, dir: m(this.props.isDirectionRightToLeft) } ); const t = this.itemRender ? /* @__PURE__ */ s.createElement(this.itemRender, { item: this.props.onOriginalItemNeeded(e.id), itemId: e.id, key: "1" }) : /* @__PURE__ */ s.createElement("span", { className: "k-menu-link-text" }, e.text); return /* @__PURE__ */ s.createElement(f, { url: e.url, opened: this.Opened }, this.renderMenuIconIfApplicable(), t, this.renderArrowIfApplicable()); } renderPopupIfOpened() { const e = this.props.item.id, t = this.props.animate, { anchorAlign: o, popupAlign: n, collision: i, animationDirection: r } = g( e, this.props.isMenuVertical, this.props.isDirectionRightToLeft ), l = t === !0 ? { openDuration: 300, closeDuration: 300, direction: r } : t === !1 ? !1 : { openDuration: (t == null ? void 0 : t.openDuration) || 300, closeDuration: (t == null ? void 0 : t.closeDuration) || 300, direction: (t == null ? void 0 : t.direction) || r }; return /* @__PURE__ */ s.createElement( c, { anchor: this.itemElement, show: this.Opened, popupClass: this.getPopupClassName(), anchorAlign: o, popupAlign: n, collision: i, animate: l, key: "1" }, /* @__PURE__ */ s.createElement( k, { parentItemId: e, animate: this.props.animate, items: this.props.item.items, menuGuid: this.props.menuGuid, focusedItemId: this.props.focusedItemId, lastItemIdToBeOpened: this.props.lastItemIdToBeOpened, tabbableItemId: this.props.tabbableItemId, itemRender: this.props.itemRender, linkRender: this.props.linkRender, isMenuVertical: this.props.isMenuVertical, isDirectionRightToLeft: this.props.isDirectionRightToLeft, className: "k-group k-menu-group k-reset k-menu-group-md", onMouseOver: this.props.onMouseOver, onMouseLeave: this.props.onMouseLeave, onMouseDown: this.props.onMouseDown, onBlur: this.props.onBlur, onFocus: this.props.onFocus, onClick: this.props.onClick, onOriginalItemNeeded: this.props.onOriginalItemNeeded } ) ); } renderMenuIconIfApplicable() { const { icon: e, svgIcon: t } = this.props.item; return e || t ? /* @__PURE__ */ s.createElement(h, { name: e, icon: t, key: "0" }) : null; } renderArrowIfApplicable() { return this.props.item.items.length > 0 ? /* @__PURE__ */ s.createElement("span", { className: "k-menu-expand-arrow", "aria-hidden": !0 }, /* @__PURE__ */ s.createElement( v, { itemId: this.props.item.id, verticalMenu: this.props.isMenuVertical, dir: m(this.props.isDirectionRightToLeft), key: "2" } )) : null; } get itemRender() { return this.props.item.render || this.props.itemRender; } get linkRender() { return this.props.item.linkRender || this.props.linkRender; } get contentRender() { return this.props.item.contentParentItemId ? this.props.item.contentRender : null; } get Opened() { const e = this.props; return e.item.items.length > 0 && I(e.item.id, e.lastItemIdToBeOpened) && // HACK: Wait for the second render because otherwise the scenario of // popup inside popup throws an error (for example, hover of item with id '0_0'). !this.isFirstRender; } getPopupClassName() { return p("k-menu-popup", { "k-rtl": this.props.isDirectionRightToLeft }); } getMenuItemClassName(e) { return p( "k-item", "k-menu-item", { "k-first": M(e.id), "k-last": e.isLastFromSiblings, "k-disabled": e.disabled }, e.cssClass ); } } export { O as MenuItemInternal, k as MenuItemInternalsList };