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 @@