diff --git a/packages/fiori/cypress/specs/SideNavigation.cy.tsx b/packages/fiori/cypress/specs/SideNavigation.cy.tsx index 4b5566707788..b699c5fa592d 100644 --- a/packages/fiori/cypress/specs/SideNavigation.cy.tsx +++ b/packages/fiori/cypress/specs/SideNavigation.cy.tsx @@ -211,6 +211,114 @@ describe("Side Navigation interaction", () => { cy.get("#unselectableItem").should("be.focused").and("not.have.attr", "expanded"); }); + it("Tests expanding and collapsing of unselectable items with ArrowLeft and ArrowRight", () => { + cy.mount( + + + + + + + ); + + cy.get("#focusStart").realClick(); + cy.realPress("ArrowDown"); + cy.realPress("ArrowRight"); + + cy.get("#unselectableItem").should("have.attr", "expanded"); + + cy.realPress("ArrowLeft"); + + cy.get("#unselectableItem").should("not.have.attr", "expanded"); + + cy.realPress("ArrowRight"); + cy.realPress("ArrowRight"); + + cy.get("#unselectableItem").should("have.attr", "expanded"); + + cy.realPress("ArrowLeft"); + cy.realPress("ArrowLeft"); + + cy.get("#unselectableItem").should("not.have.attr", "expanded"); + + cy.get("#sn").invoke("prop", "collapsed", true); + + cy.get("#focusStart").realClick(); + cy.focused().should(($focused) => { + expect($focused.text()).to.equal("focus start"); + }); + cy.realPress("ArrowDown"); + cy.realPress("ArrowRight"); + + cy.get("#sn") + .shadow() + .find("[ui5-responsive-popover]") + .as("popover"); + + cy.get("@popover").should("be.visible"); + + cy.get("#focusStart").realClick(); + cy.realPress("ArrowDown"); + cy.realPress("ArrowLeft"); + + cy.get("@popover").should("not.be.visible"); + }); + + it("Tests expanding and collapsing of unselectable items with ArrowLeft and ArrowRight for rtl", () => { + cy.mount( +
+ + + + + + +
+ ); + + cy.get("#focusStart").realClick(); + cy.realPress("ArrowDown"); + cy.realPress("ArrowLeft"); + + cy.get("#unselectableItem").should("have.attr", "expanded"); + + cy.realPress("ArrowRight"); + + cy.get("#unselectableItem").should("not.have.attr", "expanded"); + + cy.realPress("ArrowLeft"); + cy.realPress("ArrowLeft"); + + cy.get("#unselectableItem").should("have.attr", "expanded"); + + cy.realPress("ArrowRight"); + cy.realPress("ArrowRight"); + + cy.get("#unselectableItem").should("not.have.attr", "expanded"); + + cy.get("#sn").invoke("prop", "collapsed", true); + + cy.get("#focusStart").realClick(); + cy.realPress("ArrowDown"); + cy.realPress("ArrowLeft"); + + cy.get("#sn") + .shadow() + .find("[ui5-responsive-popover]") + .as("popover"); + + cy.get("@popover").should("be.visible"); + + cy.get("#focusStart").realClick(); + cy.focused().should(($focused) => { + expect($focused.text()).to.equal("focus start"); + }); + cy.realPress("ArrowDown"); + cy.realPress("ArrowRight"); + + cy.get("@popover").should("not.be.visible"); + }); + it("Tests expanding and collapsing of unselectable parent item when SideNavigation is collapsed", () => { cy.mount( diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index 14331cde27de..7acde2259314 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -141,11 +141,13 @@ class SideNavigationGroup extends SideNavigationItemBase { _onkeydown(e: KeyboardEvent) { if (isLeft(e) || isMinus(e)) { + e.preventDefault(); this.expanded = false; return; } if (isRight(e) || isPlus(e)) { + e.preventDefault(); this.expanded = true; } } diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index 9826fe5f86c9..b950c136b2df 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -71,7 +71,7 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { _fixed = false; /** - * Defines nested items by passing `ui5-side-navigation-sub-item` to the default slot. + * Defines nested items by passing `ui5-side-navigation-sub-item` to the default slot. * * @public */ @@ -199,13 +199,22 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { } _onkeydown(e: KeyboardEvent) { + const isRTL = this.effectiveDir === "rtl"; + + if (this.sideNavigation.classList.contains("ui5-side-navigation-in-popover") || this.sideNavCollapsed) { + super._onkeydown(e); + return; + } + if (isLeft(e) || isMinus(e)) { - this.expanded = false; + e.preventDefault(); + this.expanded = !!isRTL; return; } if (isRight(e) || isPlus(e)) { - this.expanded = true; + e.preventDefault(); + this.expanded = !isRTL; return; } diff --git a/packages/fiori/src/SideNavigationSelectableItemBase.ts b/packages/fiori/src/SideNavigationSelectableItemBase.ts index 9ab84f33bd34..d37c2ea7ec62 100644 --- a/packages/fiori/src/SideNavigationSelectableItemBase.ts +++ b/packages/fiori/src/SideNavigationSelectableItemBase.ts @@ -1,7 +1,12 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js"; -import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; +import { + isSpace, + isEnter, + isLeft, + isRight, +} from "@ui5/webcomponents-base/dist/Keys.js"; import SideNavigationItemBase from "./SideNavigationItemBase.js"; import type SideNavigationItemDesign from "./types/SideNavigationItemDesign.js"; import type { AccessibilityAttributes } from "@ui5/webcomponents-base/dist/types.js"; @@ -194,13 +199,23 @@ class SideNavigationSelectableItemBase extends SideNavigationItemBase { } _onkeydown(e: KeyboardEvent) { - if (isSpace(e)) { + const isRTL = this.effectiveDir === "rtl"; + + if (isSpace(e) || isRight(e) || isLeft(e)) { e.preventDefault(); } if (isEnter(e)) { this._activate(e); } + + if ((isRTL ? isLeft(e) : isRight(e)) && this.sideNavCollapsed) { + this._activate(e); + } + + if ((isRTL ? isRight(e) : isLeft(e)) && !this.sideNavCollapsed) { + this._activate(e); + } } _onkeyup(e: KeyboardEvent) { diff --git a/packages/fiori/src/themes/SideNavigationGroup.css b/packages/fiori/src/themes/SideNavigationGroup.css index 13eb25e38500..ef28dc29313e 100644 --- a/packages/fiori/src/themes/SideNavigationGroup.css +++ b/packages/fiori/src/themes/SideNavigationGroup.css @@ -9,7 +9,6 @@ .ui5-sn-item.ui5-sn-item-group { min-height: 2rem; padding-inline-start: var(--_ui5_side_navigation_group_padding);; - gap: 0.4375rem; font-family: var(--sapFontFamily); font-size: var(--sapFontSize); }