diff --git a/packages/fiori/cypress/specs/SideNavigation.cy.tsx b/packages/fiori/cypress/specs/SideNavigation.cy.tsx index 71dcc70e4891..bb177d285c1b 100644 --- a/packages/fiori/cypress/specs/SideNavigation.cy.tsx +++ b/packages/fiori/cypress/specs/SideNavigation.cy.tsx @@ -308,6 +308,94 @@ describe("Side Navigation interaction", () => { }); }); + it("Tests link opening with mouse click", () => { + cy.mount( + <SideNavigation id="sideNav"> + <SideNavigationItem id="item" text="1" /> + <SideNavigationItem id="unselectableItemWithLink" text="external link" unselectable={true} href="#test"/> + </SideNavigation> + ); + + cy.url().should("not.include", "#test"); + + cy.get("#unselectableItemWithLink").realClick(); + + cy.url().should("include", "#test"); + + // Remove #test from the URL + cy.window().then(win => { + win.history.back(); + }); + + cy.url().should("not.include", "#test"); + }); + + it("Tests link opening with Enter", () => { + cy.mount( + <SideNavigation> + <SideNavigationItem id="focusStart" text="focus start" /> + <SideNavigationItem text="external link" unselectable={true} href="#test"/> + </SideNavigation> + ); + + cy.url().should("not.include", "#test"); + + cy.get("#focusStart").realClick(); + cy.realPress("ArrowDown"); + cy.realPress("Enter"); + + cy.url().should("include", "#test"); + + // Remove #test from the URL + cy.window().then(win => { + win.history.back(); + }); + + cy.url().should("not.include", "#test"); + }); + + it("Tests link opening with Space", () => { + cy.mount( + <SideNavigation> + <SideNavigationItem id="focusStart" text="focus start" /> + <SideNavigationItem id="linkItem" text="external link" unselectable={true} href="#test"/> + </SideNavigation> + ); + + cy.url().should("not.include", "#test"); + + cy.get("#focusStart").realClick(); + cy.realPress("ArrowDown"); + cy.realPress("Space"); + + cy.url().should("include", "#test"); + + // Remove #test from the URL + cy.window().then(win => { + win.history.back(); + }); + + cy.url().should("not.include", "#test"); + + cy.get("#focusStart").realClick(); + cy.realPress("ArrowDown"); + cy.get("#linkItem").should("be.focused"); + + // act + cy.focused().trigger("keyup", { + key: " ", + }); + + cy.url().should("include", "#test"); + + // Remove #test from the URL + cy.window().then(win => { + win.history.back(); + }); + + cy.url().should("not.include", "#test"); + }); + it("Tests 'selection-change' event", () => { cy.mount( <SideNavigation id="sideNav"> diff --git a/packages/fiori/src/SideNavigationSelectableItemBase.ts b/packages/fiori/src/SideNavigationSelectableItemBase.ts index 2cae53b00af0..9ab84f33bd34 100644 --- a/packages/fiori/src/SideNavigationSelectableItemBase.ts +++ b/packages/fiori/src/SideNavigationSelectableItemBase.ts @@ -206,6 +206,18 @@ class SideNavigationSelectableItemBase extends SideNavigationItemBase { _onkeyup(e: KeyboardEvent) { if (isSpace(e)) { this._activate(e); + + if (this.href && !e.defaultPrevented) { + const customEvent = new MouseEvent("click"); + + customEvent.stopImmediatePropagation(); + if (this.getDomRef()!.querySelector("a")) { + this.getDomRef()!.querySelector("a")!.dispatchEvent(customEvent); + } else { + // when Side Navigation is collapsed and it is first level item we have directly <a> element + this.getDomRef()!.dispatchEvent(customEvent); + } + } } } diff --git a/packages/fiori/test/pages/SideNavigation.html b/packages/fiori/test/pages/SideNavigation.html index e75ab5dfefa1..670287db1238 100644 --- a/packages/fiori/test/pages/SideNavigation.html +++ b/packages/fiori/test/pages/SideNavigation.html @@ -47,6 +47,7 @@ <ui5-side-navigation-sub-item text="Local" href="https://sap.com" target="_blank"></ui5-side-navigation-sub-item> <ui5-side-navigation-sub-item text="Others"></ui5-side-navigation-sub-item> </ui5-side-navigation-item> + <ui5-side-navigation-item id="externalLinkItem" text="External Link Unselectable" icon="chain-link" href="https://sap.com" unselectable target="_blank"></ui5-side-navigation-item> <ui5-side-navigation-item id="externalLinkItem" text="External Link" icon="chain-link" href="https://sap.com" target="_blank"></ui5-side-navigation-item> <ui5-side-navigation-item id="item4" text="Home" icon="home" tooltip="Home tooltip"> diff --git a/packages/fiori/test/specs/SideNavigation.spec.js b/packages/fiori/test/specs/SideNavigation.spec.js index fa047e61df08..95e0bc32988f 100644 --- a/packages/fiori/test/specs/SideNavigation.spec.js +++ b/packages/fiori/test/specs/SideNavigation.spec.js @@ -225,9 +225,9 @@ describe("Component Behavior", () => { // fixed items assert.strictEqual(await sideNavigationFixedTree.getAttribute("aria-roledescription"), roleDescription, "Role description of the SideNavigation fixed tree element is correctly set"); - assert.notExists(await items[10].getAttribute("aria-roledescription"), "Role description of the SideNavigation fixed tree item is not set"); - assert.strictEqual(await items[10].getAttribute("aria-haspopup"), "tree", "There is 'aria-haspopup' with correct value"); - assert.notExists(await items[11].getAttribute("aria-haspopup"), "There is no 'aria-haspopup'"); + assert.notExists(await items[11].getAttribute("aria-roledescription"), "Role description of the SideNavigation fixed tree item is not set"); + assert.strictEqual(await items[11].getAttribute("aria-haspopup"), "tree", "There is 'aria-haspopup' with correct value"); + assert.notExists(await items[12].getAttribute("aria-haspopup"), "There is no 'aria-haspopup'"); // popup await browser.$("#item2").click();