import { jsx as E } from "react/jsx-runtime"; import T from "react"; import { o as S } from "./create-component-CVXl33PD.mjs"; import { M as I, s as R, C as M, c as b, a as k, N as l, S as g, b as O, K as x, d as A } from "./menuItemController-CeB921ip.mjs"; import { r as $, _ as s, n as r, x as d, E as m, c as K, b as w, a as D } from "./class-map-CwiboTfb.mjs"; import "./ripple-pQcEjR05.mjs"; import { c as p, g as P, a as L, d as N } from "./item-CpL4zUlE.mjs"; import { a as F } from "./animation-DjClVFum.mjs"; import { o as f } from "./query-assigned-elements-DUhez03i.mjs"; import { n as H } from "./query-assigned-nodes-MKI2zKDb.mjs"; import { i as C, u as B } from "./static-DdXEOlS4.mjs"; import { m as _ } from "./delegate-BXi1gVeU.mjs"; /** * @license * Copyright 2022 Google LLC * SPDX-License-Identifier: Apache-2.0 */ const G = _($); class i extends G { constructor() { super(...arguments), this.disabled = !1, this.type = "menuitem", this.href = "", this.target = "", this.keepOpen = !1, this.selected = !1, this.menuItemController = new I(this, { getHeadlineElements: () => this.headlineElements, getSupportingTextElements: () => this.supportingTextElements, getDefaultElements: () => this.defaultElements, getInteractiveElement: () => this.listItemRoot }); } /** * The text that is selectable via typeahead. If not set, defaults to the * innerText of the item slotted into the `"headline"` slot. */ get typeaheadText() { return this.menuItemController.typeaheadText; } set typeaheadText(e) { this.menuItemController.setTypeaheadText(e); } render() { return this.renderListItem(d`
${this.renderRipple()} ${this.renderFocusRing()}
${this.renderBody()}
`); } /** * Renders the root list item. * * @param content the child content of the list item. */ renderListItem(e) { const o = this.type === "link"; let t; switch (this.menuItemController.tagName) { case "a": t = C`a`; break; case "button": t = C`button`; break; default: case "li": t = C`li`; break; } const n = o && this.target ? this.target : m; return B` <${t} id="item" tabindex=${this.disabled && !o ? -1 : 0} role=${this.menuItemController.role} aria-label=${this.ariaLabel || m} aria-selected=${this.ariaSelected || m} aria-checked=${this.ariaChecked || m} aria-expanded=${this.ariaExpanded || m} aria-haspopup=${this.ariaHasPopup || m} class="list-item ${K(this.getRenderClasses())}" href=${this.href || m} target=${n} @click=${this.menuItemController.onClick} @keydown=${this.menuItemController.onKeydown} >${e} `; } /** * Handles rendering of the ripple element. */ renderRipple() { return d` `; } /** * Handles rendering of the focus ring. */ renderFocusRing() { return d` `; } /** * Classes applied to the list item root. */ getRenderClasses() { return { disabled: this.disabled, selected: this.selected }; } /** * Handles rendering the headline and supporting text. */ renderBody() { return d` `; } focus() { var e; (e = this.listItemRoot) == null || e.focus(); } } i.shadowRootOptions = { ...$.shadowRootOptions, delegatesFocus: !0 }; s([ r({ type: Boolean, reflect: !0 }) ], i.prototype, "disabled", void 0); s([ r() ], i.prototype, "type", void 0); s([ r() ], i.prototype, "href", void 0); s([ r() ], i.prototype, "target", void 0); s([ r({ type: Boolean, attribute: "keep-open" }) ], i.prototype, "keepOpen", void 0); s([ r({ type: Boolean }) ], i.prototype, "selected", void 0); s([ F(".list-item") ], i.prototype, "listItemRoot", void 0); s([ f({ slot: "headline" }) ], i.prototype, "headlineElements", void 0); s([ f({ slot: "supporting-text" }) ], i.prototype, "supportingTextElements", void 0); s([ H({ slot: "" }) ], i.prototype, "defaultElements", void 0); s([ r({ attribute: "typeahead-text" }) ], i.prototype, "typeaheadText", null); /** * @license * Copyright 2022 Google LLC * SPDX-License-Identifier: Apache-2.0 */ let c = class extends i { }; c.styles = [R]; c = s([ w("md-menu-item") ], c); /** * @license * Copyright 2023 Google LLC * SPDX-License-Identifier: Apache-2.0 */ let u = class extends $ { get item() { return this.items[0] ?? null; } get menu() { return this.menus[0] ?? null; } constructor() { super(), this.anchorCorner = M.START_END, this.menuCorner = M.START_START, this.hoverOpenDelay = 400, this.hoverCloseDelay = 400, this.isSubMenu = !0, this.previousOpenTimeout = 0, this.previousCloseTimeout = 0, this.onMouseenter = () => { var e; clearTimeout(this.previousOpenTimeout), clearTimeout(this.previousCloseTimeout), !((e = this.menu) != null && e.open) && (this.hoverOpenDelay ? this.previousOpenTimeout = setTimeout(() => { this.show(); }, this.hoverOpenDelay) : this.show()); }, this.onMouseleave = () => { clearTimeout(this.previousCloseTimeout), clearTimeout(this.previousOpenTimeout), this.hoverCloseDelay ? this.previousCloseTimeout = setTimeout(() => { this.close(); }, this.hoverCloseDelay) : this.close(); }, this.addEventListener("mouseenter", this.onMouseenter), this.addEventListener("mouseleave", this.onMouseleave); } render() { return d` `; } firstUpdated() { this.onSlotchange(); } /** * Shows the submenu. */ async show() { const e = this.menu; if (!e || e.open) return; e.addEventListener("closed", () => { this.item.ariaExpanded = "false", this.dispatchEvent(b()), this.dispatchEvent(p()), e.ariaHidden = "true"; }, { once: !0 }), e.positioning === "document" && (e.positioning = "absolute"), e.quick = !0, e.hasOverflow = !0, e.anchorCorner = this.anchorCorner, e.menuCorner = this.menuCorner, e.anchorElement = this.item, e.defaultFocus = "first-item", e.removeAttribute("aria-hidden"), e.skipRestoreFocus = !1; const o = e.open; if (e.show(), this.item.ariaExpanded = "true", this.item.ariaHasPopup = "menu", e.id && this.item.setAttribute("aria-controls", e.id), this.dispatchEvent(p()), this.dispatchEvent(k()), this.item.selected = !0, !o) { let t = (h) => { }; const n = new Promise((h) => { t = h; }); e.addEventListener("opened", t, { once: !0 }), await n; } } /** * Closes the submenu. */ async close() { const e = this.menu; if (!e || !e.open) return; this.dispatchEvent(b()), e.quick = !0, e.close(), this.dispatchEvent(p()); let o = (n) => { }; const t = new Promise((n) => { o = n; }); e.addEventListener("closed", o, { once: !0 }), await t; } onSlotchange() { var o; if (!this.item) return; this.item.ariaExpanded = "false", this.item.ariaHasPopup = "menu", (o = this.menu) != null && o.id && this.item.setAttribute("aria-controls", this.menu.id), this.item.keepOpen = !0; const e = this.menu; e && (e.isSubmenu = !0, e.ariaHidden = "true"); } onClick() { this.show(); } /** * On item keydown handles opening the submenu. */ async onKeydown(e) { const o = this.isSubmenuOpenKey(e.code); if (e.defaultPrevented) return; const t = o && (l.LEFT === e.code || l.RIGHT === e.code); if ((e.code === g.SPACE || t) && (e.preventDefault(), t && e.stopPropagation()), !o) return; const n = this.menu; if (!n) return; const h = n.items, v = P(h); if (v) { await this.show(), v.tabIndex = 0, v.focus(); return; } } onCloseSubmenu(e) { const { itemPath: o, reason: t } = e.detail; if (o.push(this.item), this.dispatchEvent(b()), t.kind === O.KEYDOWN && t.key === x.ESCAPE) { e.stopPropagation(), this.item.dispatchEvent(L()); return; } this.dispatchEvent(p()); } async onSubMenuKeydown(e) { var n; if (e.defaultPrevented) return; const { close: o, keyCode: t } = this.isSubmenuCloseKey(e.code); o && (e.preventDefault(), (t === l.LEFT || t === l.RIGHT) && e.stopPropagation(), await this.close(), N(this.menu.items), (n = this.item) == null || n.focus(), this.item.tabIndex = 0, this.item.focus()); } /** * Determines whether the given KeyboardEvent code is one that should open * the submenu. This is RTL-aware. By default, left, right, space, or enter. * * @param code The native KeyboardEvent code. * @return Whether or not the key code should open the submenu. */ isSubmenuOpenKey(e) { const t = getComputedStyle(this).direction === "rtl" ? l.LEFT : l.RIGHT; switch (e) { case t: case g.SPACE: case g.ENTER: return !0; default: return !1; } } /** * Determines whether the given KeyboardEvent code is one that should close * the submenu. This is RTL-aware. By default right, left, or escape. * * @param code The native KeyboardEvent code. * @return Whether or not the key code should close the submenu. */ isSubmenuCloseKey(e) { const t = getComputedStyle(this).direction === "rtl" ? l.RIGHT : l.LEFT; switch (e) { case t: case x.ESCAPE: return { close: !0, keyCode: e }; default: return { close: !1 }; } } }; s([ r({ attribute: "anchor-corner" }) ], u.prototype, "anchorCorner", void 0); s([ r({ attribute: "menu-corner" }) ], u.prototype, "menuCorner", void 0); s([ r({ type: Number, attribute: "hover-open-delay" }) ], u.prototype, "hoverOpenDelay", void 0); s([ r({ type: Number, attribute: "hover-close-delay" }) ], u.prototype, "hoverCloseDelay", void 0); s([ r({ type: Boolean, reflect: !0, attribute: "md-sub-menu" }) ], u.prototype, "isSubMenu", void 0); s([ f({ slot: "item", flatten: !0 }) ], u.prototype, "items", void 0); s([ f({ slot: "menu", flatten: !0 }) ], u.prototype, "menus", void 0); /** * @license * Copyright 2024 Google LLC * SPDX-License-Identifier: Apache-2.0 */ const q = D`:host{position:relative;display:flex;flex-direction:column} `; /** * @license * Copyright 2023 Google LLC * SPDX-License-Identifier: Apache-2.0 */ let y = class extends u { }; y.styles = [q]; y = s([ w("md-sub-menu") ], y); const W = S({ react: T, tagName: "md-menu", elementClass: A }), j = S({ react: T, tagName: "md-menu-item", elementClass: c, events: { "close-menu": "onCloseMenu" } }), U = S({ react: T, tagName: "md-sub-menu", elementClass: y }), le = (a) => /* @__PURE__ */ E( W, { ...a } ), ue = (a) => /* @__PURE__ */ E( U, { ...a } ), me = (a) => /* @__PURE__ */ E(j, { ...a }); export { le as Menu, me as MenuItem, ue as SubMenu };