|
1 |
| -import { renderFinished } from "../Render.js"; |
2 | 1 | import {
|
3 | 2 | isDown,
|
4 | 3 | isUp,
|
@@ -92,97 +91,101 @@ class ItemNavigation extends EventProvider {
|
92 | 91 | });
|
93 | 92 | }
|
94 | 93 |
|
95 |
| - _horizontalNavigationOn() { |
96 |
| - return this.horizontalNavigationOn; |
97 |
| - } |
98 |
| - |
99 |
| - _verticalNavigationOn() { |
100 |
| - return this.verticalNavigationOn; |
101 |
| - } |
| 94 | + onkeydown(event) { |
| 95 | + if (!this._canNavigate()) { |
| 96 | + return; |
| 97 | + } |
102 | 98 |
|
103 |
| - async _onKeyPress(event) { |
104 |
| - if (this.currentIndex >= this._getItems().length) { |
105 |
| - this.onOverflowBottomEdge(); |
106 |
| - } else if (this.currentIndex < 0) { |
107 |
| - this.onOverflowTopEdge(); |
| 99 | + if (isUp(event) && this.verticalNavigationOn) { |
| 100 | + this._handleUp(); |
| 101 | + } else if (isDown(event) && this.verticalNavigationOn) { |
| 102 | + this._handleDown(); |
| 103 | + } else if (isLeft(event) && this.horizontalNavigationOn) { |
| 104 | + this._handleLeft(); |
| 105 | + } else if (isRight(event) && this.horizontalNavigationOn) { |
| 106 | + this._handleRight(); |
| 107 | + } else if (isHome(event)) { |
| 108 | + this._handleHome(); |
| 109 | + } else if (isEnd(event)) { |
| 110 | + this._handleEnd(); |
| 111 | + } else { |
| 112 | + return; // if none of the supported keys is pressed, we don't want to prevent the event or update the item navigation |
108 | 113 | }
|
109 | 114 |
|
110 | 115 | event.preventDefault();
|
111 |
| - |
112 |
| - await renderFinished(); |
113 |
| - |
114 | 116 | this.update();
|
115 | 117 | this.focusCurrent();
|
116 | 118 | }
|
117 | 119 |
|
118 |
| - onkeydown(event) { |
119 |
| - if (isUp(event) && this._verticalNavigationOn()) { |
120 |
| - return this._handleUp(event); |
121 |
| - } |
122 |
| - |
123 |
| - if (isDown(event) && this._verticalNavigationOn()) { |
124 |
| - return this._handleDown(event); |
125 |
| - } |
126 |
| - |
127 |
| - if (isLeft(event) && this._horizontalNavigationOn()) { |
128 |
| - return this._handleLeft(event); |
| 120 | + _handleUp() { |
| 121 | + const itemsLength = this._getItems().length; |
| 122 | + if (this.currentIndex - this.rowSize >= 0) { // no border reached, just decrease the index by a row |
| 123 | + this.currentIndex -= this.rowSize; |
| 124 | + return; |
129 | 125 | }
|
130 | 126 |
|
131 |
| - if (isRight(event) && this._horizontalNavigationOn()) { |
132 |
| - return this._handleRight(event); |
| 127 | + if (this.behavior === ItemNavigationBehavior.Cyclic) { // if cyclic, go to the **last** item in the **previous** column |
| 128 | + const firstItemInThisColumnIndex = this.currentIndex % this.rowSize; |
| 129 | + 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) |
| 130 | + 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) |
| 131 | + let lastItemInPreviousColumnIndex = firstItemInPreviousColumnIndex + (rows - 1) * this.rowSize; // multiply rows by columns, and add the column's first item's index |
| 132 | + if (lastItemInPreviousColumnIndex > itemsLength - 1) { // for incomplete rows, use the previous row's last item, as for them the last item is missing |
| 133 | + lastItemInPreviousColumnIndex -= this.rowSize; |
| 134 | + } |
| 135 | + this.currentIndex = lastItemInPreviousColumnIndex; |
| 136 | + } else { // not cyclic, so just go to the first item |
| 137 | + this.currentIndex = 0; |
133 | 138 | }
|
| 139 | + } |
134 | 140 |
|
135 |
| - if (isHome(event)) { |
136 |
| - return this._handleHome(event); |
| 141 | + _handleDown() { |
| 142 | + const itemsLength = this._getItems().length; |
| 143 | + if (this.currentIndex + this.rowSize < itemsLength) { // no border reached, just increase the index by a row |
| 144 | + this.currentIndex += this.rowSize; |
| 145 | + return; |
137 | 146 | }
|
138 | 147 |
|
139 |
| - if (isEnd(event)) { |
140 |
| - return this._handleEnd(event); |
| 148 | + if (this.behavior === ItemNavigationBehavior.Cyclic) { // if cyclic, go to the **first** item in the **next** column |
| 149 | + const firstItemInThisColumnIndex = this.currentIndex % this.rowSize; // find the first item in the current column first |
| 150 | + 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 |
| 151 | + this.currentIndex = firstItemInNextColumnIndex; |
| 152 | + } else { // not cyclic, so just go to the last item |
| 153 | + this.currentIndex = itemsLength - 1; |
141 | 154 | }
|
142 | 155 | }
|
143 | 156 |
|
144 |
| - _handleUp(event) { |
145 |
| - if (this._canNavigate()) { |
146 |
| - this.currentIndex -= this.rowSize; |
147 |
| - this._onKeyPress(event); |
| 157 | + _handleLeft() { |
| 158 | + const itemsLength = this._getItems().length; |
| 159 | + if (this.currentIndex > 0) { |
| 160 | + this.currentIndex -= 1; |
| 161 | + return; |
148 | 162 | }
|
149 |
| - } |
150 | 163 |
|
151 |
| - _handleDown(event) { |
152 |
| - if (this._canNavigate()) { |
153 |
| - this.currentIndex += this.rowSize; |
154 |
| - this._onKeyPress(event); |
| 164 | + if (this.behavior === ItemNavigationBehavior.Cyclic) { // go to the first item in the next column |
| 165 | + this.currentIndex = itemsLength - 1; |
155 | 166 | }
|
156 | 167 | }
|
157 | 168 |
|
158 |
| - _handleLeft(event) { |
159 |
| - if (this._canNavigate()) { |
160 |
| - this.currentIndex -= 1; |
161 |
| - this._onKeyPress(event); |
| 169 | + _handleRight() { |
| 170 | + const itemsLength = this._getItems().length; |
| 171 | + if (this.currentIndex < itemsLength - 1) { |
| 172 | + this.currentIndex += 1; |
| 173 | + return; |
162 | 174 | }
|
163 |
| - } |
164 | 175 |
|
165 |
| - _handleRight(event) { |
166 |
| - if (this._canNavigate()) { |
167 |
| - this.currentIndex += 1; |
168 |
| - this._onKeyPress(event); |
| 176 | + if (this.behavior === ItemNavigationBehavior.Cyclic) { // go to the first item in the next column |
| 177 | + this.currentIndex = 0; |
169 | 178 | }
|
170 | 179 | }
|
171 | 180 |
|
172 |
| - _handleHome(event) { |
173 |
| - if (this._canNavigate()) { |
174 |
| - const homeEndRange = this.rowSize > 1 ? this.rowSize : this._getItems().length; |
175 |
| - this.currentIndex -= this.currentIndex % homeEndRange; |
176 |
| - this._onKeyPress(event); |
177 |
| - } |
| 181 | + _handleHome() { |
| 182 | + const homeEndRange = this.rowSize > 1 ? this.rowSize : this._getItems().length; |
| 183 | + this.currentIndex -= this.currentIndex % homeEndRange; |
178 | 184 | }
|
179 | 185 |
|
180 |
| - _handleEnd(event) { |
181 |
| - if (this._canNavigate()) { |
182 |
| - const homeEndRange = this.rowSize > 1 ? this.rowSize : this._getItems().length; |
183 |
| - this.currentIndex += (homeEndRange - 1 - this.currentIndex % homeEndRange); // eslint-disable-line |
184 |
| - this._onKeyPress(event); |
185 |
| - } |
| 186 | + _handleEnd() { |
| 187 | + const homeEndRange = this.rowSize > 1 ? this.rowSize : this._getItems().length; |
| 188 | + this.currentIndex += (homeEndRange - 1 - this.currentIndex % homeEndRange); // eslint-disable-line |
186 | 189 | }
|
187 | 190 |
|
188 | 191 | /**
|
@@ -219,8 +222,7 @@ class ItemNavigation extends EventProvider {
|
219 | 222 | }
|
220 | 223 |
|
221 | 224 | /**
|
222 |
| - * @public |
223 |
| - * @deprecated |
| 225 | + * @private |
224 | 226 | */
|
225 | 227 | focusCurrent() {
|
226 | 228 | const currentItem = this._getCurrentItem();
|
@@ -286,28 +288,6 @@ class ItemNavigation extends EventProvider {
|
286 | 288 | set current(val) {
|
287 | 289 | this.currentIndex = val;
|
288 | 290 | }
|
289 |
| - |
290 |
| - onOverflowBottomEdge(event) { |
291 |
| - const items = this._getItems(); |
292 |
| - |
293 |
| - if (this.behavior === ItemNavigationBehavior.Cyclic) { |
294 |
| - this.currentIndex = 0; |
295 |
| - return; |
296 |
| - } |
297 |
| - |
298 |
| - this.currentIndex = items.length - 1; |
299 |
| - } |
300 |
| - |
301 |
| - onOverflowTopEdge(event) { |
302 |
| - const items = this._getItems(); |
303 |
| - |
304 |
| - if (this.behavior === ItemNavigationBehavior.Cyclic) { |
305 |
| - this.currentIndex = items.length - 1; |
306 |
| - return; |
307 |
| - } |
308 |
| - |
309 |
| - this.currentIndex = 0; |
310 |
| - } |
311 | 291 | }
|
312 | 292 |
|
313 | 293 | export default ItemNavigation;
|
0 commit comments