Skip to content

Commit

Permalink
fix(f6navigation): fast navigation in certain container only (#10485)
Browse files Browse the repository at this point in the history
Fast navigation includes two main modes: default and scoped. The default mode is used for navigating across all defined groups, while the scoped mode limits navigation to a specific group, such as within a container like a modal dialog.
  • Loading branch information
nnaydenow authored Jan 23, 2025
1 parent 67b5145 commit 4b2ab63
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 8 deletions.
21 changes: 20 additions & 1 deletion packages/base/src/features/F6Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,27 @@ class F6Navigation {
}

updateGroups() {
const container = this.findContainer();

this.setSelectedGroup();
this.groups = getFastNavigationGroups(document.body);
this.groups = getFastNavigationGroups(container);
}

findContainer() {
const htmlElement = window.document.querySelector("html");
let element = this.deepActive(window.document);

while (element && element !== htmlElement) {
const closestScopeEl = element.closest<HTMLElement>("[data-sap-ui-fastnavgroup-container='true']");

if (closestScopeEl) {
return closestScopeEl;
}

element = element.parentElement ? element.parentElement : (element.parentNode as ShadowRoot).host;
}

return document.body;
}

setSelectedGroup(root: DocumentOrShadowRoot = window.document) {
Expand Down
6 changes: 5 additions & 1 deletion packages/base/src/util/getFastNavigationGroups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ const findFastNavigationGroups = (container: HTMLElement, startFromContainer?: b
findFastNavigationGroups(child as HTMLElement, false);
}

child = assignedElements && assignedElements.length ? assignedElements[++index] : originalChild.nextElementSibling;
if (child === container) {
child = assignedElements && assignedElements.length ? assignedElements[++index] : null;
} else {
child = assignedElements && assignedElements.length ? assignedElements[++index] : originalChild.nextElementSibling;
}
}
};

Expand Down
42 changes: 42 additions & 0 deletions packages/main/cypress/specs/Dialog.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { html } from "lit";
import "@ui5/webcomponents-base/dist/features/F6Navigation.js";
import "../../src/Dialog.js";

describe("Keyboard", () => {
it("F6 navigation", () => {
cy.mount(html`
<button data-sap-ui-fastnavgroup="true" id="test"></button>
<ui5-dialog open>
<div data-sap-ui-fastnavgroup="true">
<button id="first">First group focusable</button>
</div>
<div data-sap-ui-fastnavgroup="true">
<button id="second">Second group focusable</button>
</div>
</ui5-dialog>
<button data-sap-ui-fastnavgroup="true"></button>`);

cy.get("#first")
.should("be.focused");

cy.realPress(["Shift", "F6"]);

cy.get("#second")
.should("be.focused");

cy.realPress(["Shift", "F6"]);

cy.get("#first")
.should("be.focused");

cy.realPress("F6");

cy.get("#second")
.should("be.focused");

cy.realPress("F6");

cy.get("#first")
.should("be.focused");
});
});
80 changes: 74 additions & 6 deletions packages/main/cypress/specs/F6.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe("F6 navigation", () => {
<div class="section">
<ui5-button>After Element</ui5-button>
</div>
</div`);
</div>`);

// act
cy.get("#before").focus();
Expand Down Expand Up @@ -94,7 +94,7 @@ describe("F6 navigation", () => {
<div class="section">
<ui5-button>After Element</ui5-button>
</div>
</div`);
</div>`);

// act
cy.get("#before").focus();
Expand Down Expand Up @@ -149,7 +149,7 @@ describe("F6 navigation", () => {
<div class="section">
<ui5-button>After Element</ui5-button>
</div>
</div`);
</div>`);

// act
cy.get("#before").focus();
Expand Down Expand Up @@ -421,7 +421,7 @@ describe("F6 navigation", () => {
<div class="section">
<ui5-button>After Element</ui5-button>
</div>
</div`);
</div>`);

// act
cy.get("#before").focus();
Expand Down Expand Up @@ -488,7 +488,7 @@ describe("F6 navigation", () => {
<div class="section">
<ui5-button>After Element</ui5-button>
</div>
</div`);
</div>`);

// act
cy.get("#before").focus();
Expand Down Expand Up @@ -543,7 +543,7 @@ describe("F6 navigation", () => {
<div class="section">
<ui5-button>After Element</ui5-button>
</div>
</div`);
</div>`);

// act
cy.get("#before").focus();
Expand Down Expand Up @@ -790,4 +790,72 @@ describe("F6 navigation", () => {
.should("be.focused");
});
});

describe("Groups in container", () => {
it("tests forward navigation", () => {
cy.mount(html`<div>
<div class="section" data-sap-ui-fastnavgroup="true">
<ui5-button>Non group focusable</ui5-button>
</div>
<div data-sap-ui-fastnavgroup-container="true" data-sap-ui-fastnavgroup="true">
<div class="section" data-sap-ui-fastnavgroup="true">
<ui5-button id="first">First group focusable</ui5-button>
</div>
<div class="section" data-sap-ui-fastnavgroup="true">
<ui5-button id="second">Second group focusable</ui5-button>
</div>
</div>
<div class="section" data-sap-ui-fastnavgroup="true">
<ui5-button>Non group focusable</ui5-button>
</div>
</div>`);

// act
cy.get("#first")
.realClick();

cy.realPress("F6");

cy.get("#second")
.should("be.focused");

cy.realPress("F6");

cy.get("#first")
.should("be.focused");
});

it("tests backward navigation", () => {
cy.mount(html`<div>
<div class="section" data-sap-ui-fastnavgroup="true">
<ui5-button>Non group focusable</ui5-button>
</div>
<div data-sap-ui-fastnavgroup-container="true">
<div class="section" data-sap-ui-fastnavgroup="true">
<ui5-button id="first">First group focusable</ui5-button>
</div>
<div class="section" data-sap-ui-fastnavgroup="true">
<ui5-button id="second">Second group focusable</ui5-button>
</div>
</div>
<div class="section" data-sap-ui-fastnavgroup="true">
<ui5-button>Non group focusable</ui5-button>
</div>
</div>`);

// act
cy.get("#first")
.realClick();

cy.realPress(["Shift", "F6"]);

cy.get("#second")
.should("be.focused");

cy.realPress(["Shift", "F6"]);

cy.get("#first")
.should("be.focused");
});
});
});
2 changes: 2 additions & 0 deletions packages/main/src/Dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ class Dialog extends Popup {
this._attachScreenResizeHandler();

this.addEventListener("dragstart", this._dragStartHandler);

this.setAttribute("data-sap-ui-fastnavgroup-container", "true");
}

onExitDOM() {
Expand Down

0 comments on commit 4b2ab63

Please sign in to comment.