diff --git a/packages/base/src/delegate/ItemNavigation.js b/packages/base/src/delegate/ItemNavigation.js index 0303ce642170..aa434628a7e0 100644 --- a/packages/base/src/delegate/ItemNavigation.js +++ b/packages/base/src/delegate/ItemNavigation.js @@ -1,4 +1,3 @@ -import { renderFinished } from "../Render.js"; import { isDown, isUp, @@ -92,97 +91,101 @@ class ItemNavigation extends EventProvider { }); } - _horizontalNavigationOn() { - return this.horizontalNavigationOn; - } - - _verticalNavigationOn() { - return this.verticalNavigationOn; - } + onkeydown(event) { + if (!this._canNavigate()) { + return; + } - async _onKeyPress(event) { - if (this.currentIndex >= this._getItems().length) { - this.onOverflowBottomEdge(); - } else if (this.currentIndex < 0) { - this.onOverflowTopEdge(); + if (isUp(event) && this.verticalNavigationOn) { + this._handleUp(); + } else if (isDown(event) && this.verticalNavigationOn) { + this._handleDown(); + } else if (isLeft(event) && this.horizontalNavigationOn) { + this._handleLeft(); + } else if (isRight(event) && this.horizontalNavigationOn) { + this._handleRight(); + } else if (isHome(event)) { + this._handleHome(); + } else if (isEnd(event)) { + this._handleEnd(); + } else { + return; // if none of the supported keys is pressed, we don't want to prevent the event or update the item navigation } event.preventDefault(); - - await renderFinished(); - this.update(); this.focusCurrent(); } - onkeydown(event) { - if (isUp(event) && this._verticalNavigationOn()) { - return this._handleUp(event); - } - - if (isDown(event) && this._verticalNavigationOn()) { - return this._handleDown(event); - } - - if (isLeft(event) && this._horizontalNavigationOn()) { - return this._handleLeft(event); + _handleUp() { + const itemsLength = this._getItems().length; + if (this.currentIndex - this.rowSize >= 0) { // no border reached, just decrease the index by a row + this.currentIndex -= this.rowSize; + return; } - if (isRight(event) && this._horizontalNavigationOn()) { - return this._handleRight(event); + if (this.behavior === ItemNavigationBehavior.Cyclic) { // if cyclic, go to the **last** item in the **previous** column + const firstItemInThisColumnIndex = this.currentIndex % this.rowSize; + const firstItemInPreviousColumnIndex = firstItemInThisColumnIndex === 0 ? this.rowSize - 1 : firstItemInThisColumnIndex - 1; // find the first item in the previous column (if the current column is the first column -> move to the last column) + const rows = Math.ceil(itemsLength / this.rowSize); // how many rows there are (even if incomplete, f.e. for 14 items and rowSize=4 -> 4 rows total, although only 2 items on the last row) + let lastItemInPreviousColumnIndex = firstItemInPreviousColumnIndex + (rows - 1) * this.rowSize; // multiply rows by columns, and add the column's first item's index + if (lastItemInPreviousColumnIndex > itemsLength - 1) { // for incomplete rows, use the previous row's last item, as for them the last item is missing + lastItemInPreviousColumnIndex -= this.rowSize; + } + this.currentIndex = lastItemInPreviousColumnIndex; + } else { // not cyclic, so just go to the first item + this.currentIndex = 0; } + } - if (isHome(event)) { - return this._handleHome(event); + _handleDown() { + const itemsLength = this._getItems().length; + if (this.currentIndex + this.rowSize < itemsLength) { // no border reached, just increase the index by a row + this.currentIndex += this.rowSize; + return; } - if (isEnd(event)) { - return this._handleEnd(event); + if (this.behavior === ItemNavigationBehavior.Cyclic) { // if cyclic, go to the **first** item in the **next** column + const firstItemInThisColumnIndex = this.currentIndex % this.rowSize; // find the first item in the current column first + const firstItemInNextColumnIndex = (firstItemInThisColumnIndex + 1) % this.rowSize; // to get the first item in the next column, just increase the index by 1. The modulo by rows is for the case when we are at the last column + this.currentIndex = firstItemInNextColumnIndex; + } else { // not cyclic, so just go to the last item + this.currentIndex = itemsLength - 1; } } - _handleUp(event) { - if (this._canNavigate()) { - this.currentIndex -= this.rowSize; - this._onKeyPress(event); + _handleLeft() { + const itemsLength = this._getItems().length; + if (this.currentIndex > 0) { + this.currentIndex -= 1; + return; } - } - _handleDown(event) { - if (this._canNavigate()) { - this.currentIndex += this.rowSize; - this._onKeyPress(event); + if (this.behavior === ItemNavigationBehavior.Cyclic) { // go to the first item in the next column + this.currentIndex = itemsLength - 1; } } - _handleLeft(event) { - if (this._canNavigate()) { - this.currentIndex -= 1; - this._onKeyPress(event); + _handleRight() { + const itemsLength = this._getItems().length; + if (this.currentIndex < itemsLength - 1) { + this.currentIndex += 1; + return; } - } - _handleRight(event) { - if (this._canNavigate()) { - this.currentIndex += 1; - this._onKeyPress(event); + if (this.behavior === ItemNavigationBehavior.Cyclic) { // go to the first item in the next column + this.currentIndex = 0; } } - _handleHome(event) { - if (this._canNavigate()) { - const homeEndRange = this.rowSize > 1 ? this.rowSize : this._getItems().length; - this.currentIndex -= this.currentIndex % homeEndRange; - this._onKeyPress(event); - } + _handleHome() { + const homeEndRange = this.rowSize > 1 ? this.rowSize : this._getItems().length; + this.currentIndex -= this.currentIndex % homeEndRange; } - _handleEnd(event) { - if (this._canNavigate()) { - const homeEndRange = this.rowSize > 1 ? this.rowSize : this._getItems().length; - this.currentIndex += (homeEndRange - 1 - this.currentIndex % homeEndRange); // eslint-disable-line - this._onKeyPress(event); - } + _handleEnd() { + const homeEndRange = this.rowSize > 1 ? this.rowSize : this._getItems().length; + this.currentIndex += (homeEndRange - 1 - this.currentIndex % homeEndRange); // eslint-disable-line } /** @@ -219,8 +222,7 @@ class ItemNavigation extends EventProvider { } /** - * @public - * @deprecated + * @private */ focusCurrent() { const currentItem = this._getCurrentItem(); @@ -286,28 +288,6 @@ class ItemNavigation extends EventProvider { set current(val) { this.currentIndex = val; } - - onOverflowBottomEdge(event) { - const items = this._getItems(); - - if (this.behavior === ItemNavigationBehavior.Cyclic) { - this.currentIndex = 0; - return; - } - - this.currentIndex = items.length - 1; - } - - onOverflowTopEdge(event) { - const items = this._getItems(); - - if (this.behavior === ItemNavigationBehavior.Cyclic) { - this.currentIndex = items.length - 1; - return; - } - - this.currentIndex = 0; - } } export default ItemNavigation; diff --git a/packages/fiori/src/ProductSwitch.js b/packages/fiori/src/ProductSwitch.js index 2479ac2a931a..cde055cde2c3 100644 --- a/packages/fiori/src/ProductSwitch.js +++ b/packages/fiori/src/ProductSwitch.js @@ -1,5 +1,6 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; +import ItemNavigationBehavior from "@ui5/webcomponents-base/dist/types/ItemNavigationBehavior.js"; import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js"; import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; @@ -64,6 +65,7 @@ class ProductSwitch extends UI5Element { this._itemNavigation = new ItemNavigation(this, { rowSize: 4, + behavior: ItemNavigationBehavior.Cyclic, getItemsCallback: () => this.items, }); } diff --git a/packages/main/bundle.esm.js b/packages/main/bundle.esm.js index ad4a3d784499..daa293de2cc5 100644 --- a/packages/main/bundle.esm.js +++ b/packages/main/bundle.esm.js @@ -2,9 +2,11 @@ import { getAssetsPath, setAssetsPath } from "@ui5/webcomponents-base/dist/confi // setAssetsPath("/my-resources/"); import { addCustomCSS, attachThemeLoaded, detachThemeLoaded } from "@ui5/webcomponents-base/dist/Theming"; +/* attachThemeLoaded(theme => { console.log("Theme load complete: ", theme); }); +*/ // OpenUI5 integration import "@ui5/webcomponents-base/dist/features/OpenUI5Support.js";