Skip to content

Commit

Permalink
feat(ItemNavigation): introduce navigationMode property (#910)
Browse files Browse the repository at this point in the history
(1) The ItemNavigation now has three navigation modes: 
- "Vertical" - "Up|Down" navigation
- "Horizontal"- "Left|Right" navigation
- "Auto" - both "Vertical" and "Horizontal" navigation

(2) From now you can navigate throw the List items and Table rows only vertically
via the "Up" and "Down" arrow keys.

FIXES: #862
  • Loading branch information
MapTo0 authored and ilhan007 committed Nov 27, 2019
1 parent ae95a8d commit 9c43533
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 10 deletions.
22 changes: 18 additions & 4 deletions packages/base/src/delegate/ItemNavigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {

import EventProvider from "../EventProvider.js";
import UI5Element from "../UI5Element.js";
import NavigationMode from "../types/NavigationMode.js";

// navigatable items must have id and tabindex
class ItemNavigation extends EventProvider {
Expand All @@ -19,6 +20,11 @@ class ItemNavigation extends EventProvider {
this.rowSize = options.rowSize || 1;
this.cyclic = options.cyclic || false;

const navigationMode = options.navigationMode;
const autoNavigation = !navigationMode || navigationMode === NavigationMode.Auto;
this.horizontalNavigationOn = autoNavigation || navigationMode === NavigationMode.Horizontal;
this.verticalNavigationOn = autoNavigation || navigationMode === NavigationMode.Vertical;

this.rootWebComponent = rootWebComponent;
this.rootWebComponent.addEventListener("keydown", this.onkeydown.bind(this));
this.rootWebComponent.addEventListener("_componentStateFinalized", () => {
Expand All @@ -32,6 +38,14 @@ class ItemNavigation extends EventProvider {
});
}

_horizontalNavigationOn() {
return this.horizontalNavigationOn;
}

_verticalNavigationOn() {
return this.verticalNavigationOn;
}

_onKeyPress(event) {
const items = this._getItems();

Expand Down Expand Up @@ -59,19 +73,19 @@ class ItemNavigation extends EventProvider {
}

onkeydown(event) {
if (isUp(event)) {
if (isUp(event) && this._verticalNavigationOn()) {
return this._handleUp(event);
}

if (isDown(event)) {
if (isDown(event) && this._verticalNavigationOn()) {
return this._handleDown(event);
}

if (isLeft(event)) {
if (isLeft(event) && this._horizontalNavigationOn()) {
return this._handleLeft(event);
}

if (isRight(event)) {
if (isRight(event) && this._horizontalNavigationOn()) {
return this._handleRight(event);
}

Expand Down
6 changes: 6 additions & 0 deletions packages/base/src/types/NavigationMode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const NavigationMode = {
Auto: "Auto",
Vertical: "Vertical",
Horizontal: "Horizontal",
};
export default NavigationMode;
6 changes: 5 additions & 1 deletion packages/main/src/List.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js";
import { getLastTabbableElement } from "@ui5/webcomponents-base/dist/util/TabbableElements.js";
import { isTabNext } from "@ui5/webcomponents-base/dist/events/PseudoEvents.js";
import NavigationMode from "@ui5/webcomponents-base/dist/types/NavigationMode.js";
import ListMode from "./types/ListMode.js";
import ListSeparators from "./types/ListSeparators.js";
import ListItemType from "./types/ListItemType.js";
Expand Down Expand Up @@ -259,7 +260,10 @@ class List extends UI5Element {
}

initItemNavigation() {
this._itemNavigation = new ItemNavigation(this);
this._itemNavigation = new ItemNavigation(this, {
navigationMode: NavigationMode.Vertical,
});

this._itemNavigation.getItemsCallback = () => this.getSlottedNodes("items");
}

Expand Down
5 changes: 4 additions & 1 deletion packages/main/src/Table.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js";
import NavigationMode from "@ui5/webcomponents-base/dist/types/NavigationMode.js";
import TableTemplate from "./generated/templates/TableTemplate.lit.js";

// Styles
Expand Down Expand Up @@ -161,7 +162,9 @@ class Table extends UI5Element {
constructor() {
super();

this._itemNavigation = new ItemNavigation(this);
this._itemNavigation = new ItemNavigation(this, {
navigationMode: NavigationMode.Vertical,
});

this._itemNavigation.getItemsCallback = function getItemsCallback() {
const columnHeader = this.getColumnHeader();
Expand Down
7 changes: 7 additions & 0 deletions packages/main/test/pages/ItemNavigation.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,12 @@ <h2>Focus does not cycle</h2>
<ui5-li id="item1">Option 1</ui5-li>
<ui5-li id="item2">Option 2</ui5-li>
</ui5-list>

<h2>Vertical navigation only</h2>
<ui5-list>
<ui5-li id="item3">Option 2.1</ui5-li>
<ui5-li id="item4">Option 2.2</ui5-li>
<ui5-li id="item5">Option 2.3</ui5-li>
</ui5-list>
</body>
</html>
25 changes: 21 additions & 4 deletions packages/main/test/specs/ItemNavigation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,31 @@ describe("Item Navigation Tests", () => {
const firstItem = $("#item1");
const secondItem = $("#item2");

browser.pause(2000);
firstItem.click();
firstItem.keys("ArrowLeft");
firstItem.keys("ArrowUp");
assert.strictEqual(firstItem.isFocused(), true, "first item remains focused");
assert.strictEqual(firstItem.isFocused(), true, "first item remains focused - border reached.");

browser.pause(2000);
secondItem.click();
secondItem.keys("ArrowRight");
secondItem.keys("ArrowDown");
assert.strictEqual(secondItem.isFocused(), true, "second item remains focused");
assert.strictEqual(secondItem.isFocused(), true, "second item remains focused - border reached.");
});


it("vertical focus navigation", () => {
const firstItem = $("#item3");
const secondItem = $("#item4");

// horizontal navigation is allowed is prevented
firstItem.click();
firstItem.keys("ArrowRight");
assert.strictEqual(firstItem.isFocused(), true, "first item remains focused - horizontal navigation prevented.");

browser.pause(2000);

// verical navigation is allowed
firstItem.keys("ArrowDown");
assert.strictEqual(secondItem.isFocused(), true, "second item is now focused - vertical navigation allowed.");
});
});
16 changes: 16 additions & 0 deletions packages/main/test/specs/List.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,20 @@ describe("Date Picker Tests", () => {
itemLink.keys("Tab");
assert.strictEqual(itemRadioBtn.isFocused(), true, "the last tabbable element (radio) is focused");
});

it("does not focus next / prev item when right / left arrow is pressed", () => {
const firstListItem = $("#country1");
const secondListItem = $("#country2");

firstListItem.click();

firstListItem.keys("ArrowRight");

assert.ok(firstListItem.isFocused(), "First item remains focussed");
assert.strictEqual(secondListItem.isFocused(), false, "Second list item not should be focused");

firstListItem.keys("ArrowLeft");

assert.ok(firstListItem.isFocused(), "First item remains focussed");
});
});

0 comments on commit 9c43533

Please sign in to comment.