@@ -58,7 +58,7 @@ export default class GridManager {
5858 row : firstFocusedCoordinates . row ,
5959 col : firstFocusedCoordinates . col ,
6060 element : this . grid [ firstFocusedCoordinates . row ] ?
61- this . grid [ firstFocusedCoordinates . row ] [ firstFocusedCoordinates . col ] : null
61+ this . grid [ firstFocusedCoordinates . row ] [ firstFocusedCoordinates . col ] ?. element : null
6262 } ;
6363
6464 if ( ! this . isValidCell ( firstFocusedCell ) || this . isDisabledCell ( firstFocusedCell . element ) ) {
@@ -84,26 +84,37 @@ export default class GridManager {
8484
8585 setupFocusGrid = ( ) => {
8686 this . grid = [ ] ;
87+ let skippedRows = 0 ;
8788
8889 this . gridNode && Array . prototype . forEach . call (
89- this . gridNode . querySelectorAll ( GridSelector . ROW ) , ( row ) => {
90+ this . gridNode . querySelectorAll ( GridSelector . ROW ) , ( row , rowIndex ) => {
9091 const rowCells = [ ] ;
9192 if ( this . rowNavigation ) {
9293 row . setAttribute ( 'tabindex' , - 1 ) ;
9394 }
9495
9596 Array . prototype . forEach . call (
96- row . querySelectorAll ( this . cellSelector ) , ( cell ) => {
97+ row . querySelectorAll ( this . cellSelector ) , ( cell , cellIndex ) => {
9798 let colSpan = cell . colSpan ;
9899 cell . setAttribute ( 'tabindex' , - 1 ) ;
99100 cell . addEventListener ( 'focus' , this . handleFocusCell ) ;
100-
101- colSpan > 0 ? rowCells . push ( ...this . createFilledArray ( colSpan , cell ) ) : rowCells . push ( cell ) ;
101+ const cellObj = {
102+ row : rowIndex - skippedRows ,
103+ col : cellIndex ,
104+ element : cell ,
105+ rowElement : row ,
106+ focusableElements : cell . querySelectorAll ( GridSelector . FOCUSABLE ) ,
107+ editableElement : cell . querySelector ( GridSelector . EDITABLE )
108+ } ;
109+
110+ colSpan > 0 ? rowCells . push ( ...this . createFilledArray ( colSpan , cellObj ) ) : rowCells . push ( cellObj ) ;
102111 }
103112 ) ;
104113
105114 if ( rowCells . length ) {
106115 this . grid . push ( rowCells ) ;
116+ } else {
117+ skippedRows ++ ;
107118 }
108119 }
109120 ) ;
@@ -133,15 +144,7 @@ export default class GridManager {
133144 const cellCoordinates = knownCoordinates ? knownCoordinates : this . getCellCoordinates ( element ) ;
134145 let cell ;
135146 if ( cellCoordinates ) {
136- cell = {
137- row : cellCoordinates . row ,
138- col : cellCoordinates . col ,
139- element : element
140- } ;
141- if ( element ) {
142- cell . focusableElements = cell . element . querySelectorAll ( GridSelector . FOCUSABLE ) ;
143- cell . editableElement = cell . element . querySelector ( GridSelector . EDITABLE ) ;
144- }
147+ cell = this . grid [ cellCoordinates . row ] [ cellCoordinates . col ] ;
145148 }
146149
147150 return cell ;
@@ -151,9 +154,9 @@ export default class GridManager {
151154 for ( let row = 0 ; row < this . grid . length ; row ++ ) {
152155 for ( let col = 0 ; col < this . grid [ row ] . length ; col ++ ) {
153156 if ( element && (
154- this . grid [ row ] [ col ] === element ||
155- this . grid [ row ] [ col ] . contains ( element ) ||
156- element . contains ( this . grid [ row ] [ col ] )
157+ this . grid [ row ] [ col ] . element === element ||
158+ this . grid [ row ] [ col ] . element . contains ( element ) ||
159+ element . contains ( this . grid [ row ] [ col ] . element )
157160 ) ) {
158161 return { row, col } ;
159162 }
@@ -163,20 +166,18 @@ export default class GridManager {
163166 }
164167
165168 getCurrentCellProperties = ( ) => {
166- return this . getCellProperties (
167- this . grid [ this . focusedRow ] [ this . focusedCol ] ,
168- { row : this . focusedRow , col : this . focusedCol }
169- ) ;
169+ return this . grid [ this . focusedRow ] [ this . focusedCol ] ;
170170 }
171171
172172 setFocusPointer = ( row , col ) => {
173173 if ( this . isValidCell ( { row, col } ) ) {
174- const currentElement = this . grid [ this . focusedRow ] [ this . focusedCol ] ;
175- const nextElement = this . grid [ row ] [ col ] ;
174+ const currentCell = this . grid [ this . focusedRow ] [ this . focusedCol ] ;
175+ const nextCell = this . grid [ row ] [ col ] ;
176+ const elementProp = ! this . rowNavigation ? 'element' : 'rowElement' ;
176177
177178 if ( ! this . editMode ) {
178- currentElement . setAttribute ( 'tabindex' , - 1 ) ;
179- nextElement . setAttribute ( 'tabindex' , 0 ) ;
179+ currentCell [ elementProp ] . setAttribute ( 'tabindex' , - 1 ) ;
180+ nextCell [ elementProp ] . setAttribute ( 'tabindex' , 0 ) ;
180181 }
181182
182183 this . focusedRow = row ;
@@ -239,15 +240,16 @@ export default class GridManager {
239240 ) {
240241 cell . focusableElements [ 0 ] . focus ( ) ;
241242 } else if ( this . rowNavigation ) {
242- event . target . parentNode . focus ( ) ;
243+ cell . rowElement ? .focus ( ) ;
243244 }
244245 this . onFocusCell ( cell , event ) ;
245246 }
246247 }
247248
248249 toggleEditMode = ( currentCell , enable ) => {
249250 this . editMode = ! ! enable ;
250- currentCell . element . setAttribute ( 'tabindex' , enable ? - 1 : 0 ) ;
251+ const elementProp = ! this . rowNavigation ? 'element' : 'rowElement' ;
252+ currentCell [ elementProp ] . setAttribute ( 'tabindex' , enable ? - 1 : 0 ) ;
251253 const focusableElements = this . getAllFocusableElements ( this . skipFirstColumnTabbing ) ;
252254 this . toggleTabbableElements ( enable , focusableElements ) ;
253255 if ( focusableElements . length > 0 ) {
@@ -257,12 +259,13 @@ export default class GridManager {
257259
258260 getAllFocusableElements = ( skipFirstColumn ) => {
259261 let focusableElements = [ ] ;
260- const cells = this . gridNode . querySelectorAll ( this . cellSelector ) ;
261- cells . forEach ( cell => {
262- const { col } = this . getCellCoordinates ( cell ) ;
263- if ( ! ( this . rowNavigation && skipFirstColumn && col === 0 ) ) {
264- focusableElements = [ ...focusableElements , ...cell . querySelectorAll ( GridSelector . FOCUSABLE ) ] ;
265- }
262+
263+ this . grid . forEach ( ( row ) => {
264+ row . forEach ( ( cell ) => {
265+ if ( ! ( this . rowNavigation && skipFirstColumn && cell ?. col === 0 ) ) {
266+ focusableElements = [ ...focusableElements , ...cell ?. focusableElements ] ;
267+ }
268+ } ) ;
266269 } ) ;
267270
268271 return focusableElements ;
@@ -277,53 +280,43 @@ export default class GridManager {
277280 }
278281
279282 handleKeyDown = ( event ) => {
280- this . syncFocusPointerToActiveElement ( event . target ) ;
281-
282283 const key = event . which || event . keyCode ;
283- const currentCell = this . getCurrentCellProperties ( ) ;
284+ const currentCell = this . grid [ this . focusedRow ] [ this . focusedCol ] ;
284285
285286 let nextCell = currentCell ;
286- let pressedArrowKey = false ;
287+ let pressedNavigationalKey = false ;
287288
288289 switch ( key ) {
289290 case keycode . codes . up :
290291 nextCell = this . getNextCell ( currentCell , 0 , - 1 ) ;
291- pressedArrowKey = true ;
292+ pressedNavigationalKey = true ;
292293 break ;
293294 case keycode . codes . down :
294295 nextCell = this . getNextCell ( currentCell , 0 , 1 ) ;
295- pressedArrowKey = true ;
296+ pressedNavigationalKey = true ;
296297 break ;
297298 case keycode . codes . left :
298299 if ( ! this . rowNavigation ) {
299300 nextCell = this . getNextCell ( currentCell , - 1 , 0 ) ;
300- pressedArrowKey = true ;
301+ pressedNavigationalKey = true ;
301302 }
302303 break ;
303304 case keycode . codes . right :
304305 if ( ! this . rowNavigation ) {
305306 nextCell = this . getNextCell ( currentCell , 1 , 0 ) ;
306- pressedArrowKey = true ;
307+ pressedNavigationalKey = true ;
307308 }
308309 break ;
309310 case keycode . codes . home :
310311 if ( ! this . rowNavigation ) {
311- nextCell = this . getNextCell (
312- this . getCellProperties (
313- this . grid [ this . focusedRow ] [ this . grid [ this . focusedRow ] . length ] ,
314- { row : this . focusedRow , col : - 1 }
315- ) , 1 , 0
316- ) ;
312+ nextCell = this . getNextCell ( { row : this . focusedRow , col : - 1 } , 1 , 0 ) ;
313+ pressedNavigationalKey = true ;
317314 }
318315 break ;
319316 case keycode . codes . end :
320317 if ( ! this . rowNavigation ) {
321- nextCell = this . getNextCell (
322- this . getCellProperties (
323- this . grid [ this . focusedRow ] [ this . grid [ this . focusedRow ] . length ] ,
324- { row : this . focusedRow , col : this . grid [ this . focusedRow ] . length }
325- ) , - 1 , 0
326- ) ;
318+ nextCell = this . getNextCell ( { row : this . focusedRow , col : this . grid [ this . focusedRow ] . length } , - 1 , 0 ) ;
319+ pressedNavigationalKey = true ;
327320 }
328321 break ;
329322 case keycode . codes . enter :
@@ -359,35 +352,23 @@ export default class GridManager {
359352 }
360353 return ;
361354 default :
362- break ;
355+ this . onKeyDownCell ( nextCell , event ) ;
356+ return ;
363357 }
364358
365359 if ( nextCell ) {
366360 this . focusCell ( nextCell , event ) ;
367361 this . onKeyDownCell ( nextCell , event ) ;
368362 }
369363
370- if ( ! this . editMode && pressedArrowKey ) {
364+ if ( ! this . editMode && pressedNavigationalKey ) {
371365 event . preventDefault ( ) ;
372366 }
373367 } ;
374368
375- syncFocusPointerToActiveElement = ( focusedTarget ) => {
376- const focusedCell = this . getCellProperties (
377- this . grid [ this . focusedRow ] [ this . focusedCol ] ,
378- { row : this . focusedRow , col : this . focusedCol }
379- ) . element ;
380-
381- if ( focusedCell === focusedTarget || focusedCell . contains ( focusedTarget ) ) {
382- return ;
383- }
384-
385- this . setFocusPointer ( focusedCell . row , focusedCell . col ) ;
386- } ;
387-
388369 handleClickCell = ( event ) => {
389370 // reset current edit state
390- const currentCell = this . getCurrentCellProperties ( ) ;
371+ const currentCell = this . grid [ this . focusedRow ] [ this . focusedCol ] ;
391372
392373 if ( this . isEditableCell ( currentCell ) && this . editMode ) {
393374 this . toggleEditMode ( currentCell , false ) ;
@@ -400,13 +381,7 @@ export default class GridManager {
400381 }
401382
402383 if ( clickedGridCell ) {
403- this . focusCell ( {
404- row : clickedGridCell . row ,
405- col : clickedGridCell . col ,
406- element : clickedGridCell . element ,
407- focusableElements : clickedGridCell . focusableElements ,
408- editableElement : clickedGridCell . editableElement
409- } , event ) ;
384+ this . focusCell ( clickedGridCell , event ) ;
410385 }
411386 } ;
412387
@@ -443,7 +418,7 @@ export default class GridManager {
443418 return null ;
444419 }
445420
446- let nextCellElement = currentCell ;
421+ let nextCell = currentCell ;
447422
448423 if ( directionX !== 0 ) { // horizontal
449424 let candidateRow = currentCell . row ;
@@ -474,14 +449,11 @@ export default class GridManager {
474449 }
475450 } while (
476451 ! this . isValidCell ( { row : candidateRow , col : candidateCol } ) ||
477- this . isDisabledCell ( this . grid [ candidateRow ] [ candidateCol ] ) ||
478- this . grid [ candidateRow ] [ candidateCol ] === currentCell . element
452+ this . isDisabledCell ( this . grid [ candidateRow ] [ candidateCol ] . element ) ||
453+ this . grid [ candidateRow ] [ candidateCol ] . element === currentCell . element
479454 ) ;
480455
481- nextCellElement = this . getCellProperties (
482- this . grid [ candidateRow ] [ candidateCol ] ,
483- { row : candidateRow , col : candidateCol }
484- ) ;
456+ nextCell = this . grid [ candidateRow ] [ candidateCol ] ;
485457 } else if ( directionY !== 0 ) { // vertical
486458 let candidateRow = currentCell . row ;
487459 let candidateCol = currentCell . col ;
@@ -507,23 +479,14 @@ export default class GridManager {
507479 }
508480 } while (
509481 ! this . isValidCell ( { row : candidateRow , col : candidateCol } ) ||
510- this . isDisabledCell ( this . grid [ candidateRow ] [ candidateCol ] ) ||
511- this . grid [ candidateRow ] [ candidateCol ] === currentCell . element
482+ this . isDisabledCell ( this . grid [ candidateRow ] [ candidateCol ] . element ) ||
483+ this . grid [ candidateRow ] [ candidateCol ] . element === currentCell . element
512484 ) ;
513485
514- nextCellElement = this . getCellProperties (
515- this . grid [ candidateRow ] [ candidateCol ] ,
516- { row : candidateRow , col : candidateCol }
517- ) ;
486+ nextCell = this . grid [ candidateRow ] [ candidateCol ] ;
518487 }
519488
520- return {
521- row : nextCellElement . row ,
522- col : nextCellElement . col ,
523- element : nextCellElement . element ,
524- focusableElements : nextCellElement . focusableElements ,
525- editableElement : nextCellElement . editableElement
526- } ;
489+ return nextCell ;
527490 } ;
528491
529492 getNextOutsideTabbableElement = ( shiftKey ) => {
0 commit comments