diff --git a/packages/calcite-components/src/components/menu-item/menu-item.e2e.ts b/packages/calcite-components/src/components/menu-item/menu-item.e2e.ts index f8beb28371b..057d12bf700 100644 --- a/packages/calcite-components/src/components/menu-item/menu-item.e2e.ts +++ b/packages/calcite-components/src/components/menu-item/menu-item.e2e.ts @@ -50,6 +50,39 @@ describe("calcite-menu-item", () => { expect(eventSpy).toHaveReceivedEventTimes(1); }); + describe("href support", () => { + const testHref = "#nature"; + const testEl = ``; + + it("should navigate to a new url when href provided and user interacts with click", async () => { + const page = await newE2EPage(); + await page.setContent(html`${testEl}`); + const originalUrl = page.url(); + await page.waitForChanges(); + + const menuItem = await page.find("calcite-menu-item"); + await page.waitForChanges(); + await menuItem.click(); + await page.waitForChanges(); + const newUrl = page.url(); + expect(newUrl).toEqual(originalUrl + testHref); + }); + + it("should navigate to a new url when href provided and user interacts with `enter` key", async () => { + const page = await newE2EPage(); + await page.setContent(html`${testEl}`); + const originalUrl = page.url(); + await page.waitForChanges(); + + await page.keyboard.press("Tab"); + await page.waitForChanges(); + await page.keyboard.press("Enter"); + await page.waitForChanges(); + const newUrl = page.url(); + expect(newUrl).toEqual(originalUrl + testHref); + }); + }); + it("should emit calciteMenuItemSelect event when user select the text area of the component using Enter or Space key", async () => { const page = await newE2EPage(); await page.setContent(html` diff --git a/packages/calcite-components/src/components/menu-item/menu-item.tsx b/packages/calcite-components/src/components/menu-item/menu-item.tsx index bac34ddeec4..fe7c342d585 100644 --- a/packages/calcite-components/src/components/menu-item/menu-item.tsx +++ b/packages/calcite-components/src/components/menu-item/menu-item.tsx @@ -266,61 +266,54 @@ export class CalciteMenuItem implements LoadableComponent, T9nComponent, Localiz }; private keyDownHandler = async (event: KeyboardEvent): Promise => { - // opening and closing of submenu is handled here. Any other functionality is bubbled to parent menu. - if (event.key === " " || event.key === "Enter") { - this.selectMenuItem(event); - if ( - this.hasSubmenu && - (!this.href || (this.href && event.target === this.dropdownActionEl)) - ) { - this.open = !this.open; + const { hasSubmenu, href, layout, open, submenuItems } = this; + const key = event.key; + const targetIsDropdown = event.target === this.dropdownActionEl; + if (key === " " || key === "Enter") { + if (hasSubmenu && (!href || (href && targetIsDropdown))) { + this.open = !open; } - event.preventDefault(); - } else if (event.key === "Escape") { - if (this.open) { + if (!(href && targetIsDropdown) && key !== "Enter") { + this.selectMenuItem(event); + } + if (key === " " || (href && targetIsDropdown)) { + event.preventDefault(); + } + } else if (key === "Escape") { + if (open) { this.open = false; return; } this.calciteInternalMenuItemKeyEvent.emit({ event }); event.preventDefault(); - } else if (event.key === "ArrowDown" || event.key === "ArrowUp") { + } else if (key === "ArrowDown" || key === "ArrowUp") { event.preventDefault(); - if ( - (event.target === this.dropdownActionEl || !this.href) && - this.hasSubmenu && - !this.open && - this.layout === "horizontal" - ) { + if ((targetIsDropdown || !href) && hasSubmenu && !open && layout === "horizontal") { this.open = true; return; } this.calciteInternalMenuItemKeyEvent.emit({ event, - children: this.submenuItems, - isSubmenuOpen: this.open && this.hasSubmenu, + children: submenuItems, + isSubmenuOpen: open && hasSubmenu, }); - } else if (event.key === "ArrowLeft") { + } else if (key === "ArrowLeft") { event.preventDefault(); this.calciteInternalMenuItemKeyEvent.emit({ event, - children: this.submenuItems, + children: submenuItems, isSubmenuOpen: true, }); - } else if (event.key === "ArrowRight") { + } else if (key === "ArrowRight") { event.preventDefault(); - if ( - (event.target === this.dropdownActionEl || !this.href) && - this.hasSubmenu && - !this.open && - this.layout === "vertical" - ) { + if ((targetIsDropdown || !href) && hasSubmenu && !open && layout === "vertical") { this.open = true; return; } this.calciteInternalMenuItemKeyEvent.emit({ event, - children: this.submenuItems, - isSubmenuOpen: this.open && this.hasSubmenu, + children: submenuItems, + isSubmenuOpen: open && hasSubmenu, }); } }; diff --git a/packages/calcite-components/src/demos/menu.html b/packages/calcite-components/src/demos/menu.html index 0f17c1c94c6..b5c523e4639 100644 --- a/packages/calcite-components/src/demos/menu.html +++ b/packages/calcite-components/src/demos/menu.html @@ -440,4 +440,11 @@

+