Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ItemNavigation): introduce navigationMode property #910

Merged
merged 5 commits into from
Nov 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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");
});
});