@@ -17,6 +17,7 @@ import setElementCanTab from './shared/setElementCanTab';
1717type FocusCellProps = {
1818 children ?: React . Node ,
1919 onKeyDown ?: KeyboardEvent => void ,
20+ colSpan ? : number ,
2021} ;
2122
2223type FocusRowProps = {
@@ -25,12 +26,12 @@ type FocusRowProps = {
2526
2627type FocusTableProps = { |
2728 children : React . Node ,
28- id ?: string ,
2929 onKeyboardOut ?: (
3030 direction : 'left' | 'right' | 'up' | 'down' ,
31- focusTableByID : ( id : string ) => void ,
31+ event : KeyboardEvent ,
3232 ) => void ,
33- wrap ? : boolean ,
33+ wrapX ?: boolean ,
34+ wrapY ?: boolean ,
3435 tabScope ?: ReactScope ,
3536 allowModifiers ?: boolean ,
3637| } ;
@@ -69,30 +70,59 @@ function focusScope(cell: ReactScopeMethods, event?: KeyboardEvent): void {
6970 }
7071}
7172
72- function focusCellByIndex (
73+ // This takes into account colSpan
74+ function focusCellByColumnIndex (
7375 row : ReactScopeMethods ,
74- cellIndex : number ,
76+ columnIndex : number ,
7577 event ?: KeyboardEvent ,
7678) : void {
7779 const cells = row . getChildren ( ) ;
7880 if ( cells !== null ) {
79- const cell = cells [ cellIndex ] ;
80- if ( cell ) {
81- focusScope ( cell , event ) ;
81+ let colSize = 0 ;
82+ for ( let i = 0 ; i < cells . length ; i ++ ) {
83+ const cell = cells [ i ] ;
84+ if ( cell ) {
85+ colSize += cell . getProps ( ) . colSpan || 1 ;
86+ if ( colSize > columnIndex ) {
87+ focusScope ( cell , event ) ;
88+ return ;
89+ }
90+ }
8291 }
8392 }
8493}
8594
95+ function getCellIndexes (
96+ cells : Array < ReactScopeMethods > ,
97+ currentCell : ReactScopeMethods ,
98+ ) : [ number , number ] {
99+ let totalColSpan = 0 ;
100+ for ( let i = 0 ; i < cells . length ; i ++ ) {
101+ const cell = cells [ i ] ;
102+ if ( cell === currentCell ) {
103+ return [ i , i + totalColSpan ] ;
104+ }
105+ const colSpan = cell . getProps ( ) . colSpan ;
106+ if ( colSpan ) {
107+ totalColSpan += colSpan - 1 ;
108+ }
109+ }
110+ return [ - 1 , - 1 ] ;
111+ }
112+
86113function getRowCells ( currentCell : ReactScopeMethods ) {
87114 const row = currentCell . getParent ( ) ;
88115 if ( row !== null && row . getProps ( ) . type === 'row' ) {
89116 const cells = row . getChildren ( ) ;
90117 if ( cells !== null ) {
91- const rowIndex = cells . indexOf ( currentCell ) ;
92- return [ cells , rowIndex ] ;
118+ const [ rowIndex , rowIndexWithColSpan ] = getCellIndexes (
119+ cells ,
120+ currentCell ,
121+ ) ;
122+ return [ cells , rowIndex , rowIndexWithColSpan ] ;
93123 }
94124 }
95- return [ null , 0 ] ;
125+ return [ null , - 1 , - 1 ] ;
96126}
97127
98128function getRows ( currentCell : ReactScopeMethods ) {
@@ -107,7 +137,7 @@ function getRows(currentCell: ReactScopeMethods) {
107137 }
108138 }
109139 }
110- return [ null , 0 ] ;
140+ return [ null , - 1 , - 1 ] ;
111141}
112142
113143function triggerNavigateOut (
@@ -122,19 +152,7 @@ function triggerNavigateOut(
122152 const props = table . getProps ( ) ;
123153 const onKeyboardOut = props . onKeyboardOut ;
124154 if ( props . type === 'table' && typeof onKeyboardOut === 'function' ) {
125- const focusTableByID = ( id : string ) = > {
126- const topLevelTables = table . getChildrenFromRoot ( ) ;
127- if ( topLevelTables !== null ) {
128- for ( let i = 0 ; i < topLevelTables . length ; i ++ ) {
129- const topLevelTable = topLevelTables [ i ] ;
130- if ( topLevelTable . getProps ( ) . id === id ) {
131- focusFirstCellOnTable ( topLevelTable ) ;
132- return ;
133- }
134- }
135- }
136- } ;
137- onKeyboardOut ( direction , focusTableByID ) ;
155+ onKeyboardOut ( direction , event ) ;
138156 return ;
139157 }
140158 }
@@ -166,8 +184,8 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
166184 function Table ( {
167185 children,
168186 onKeyboardOut,
169- id ,
170- wrap ,
187+ wrapX ,
188+ wrapY ,
171189 tabScope : TabScope ,
172190 allowModifiers,
173191 } ) : FocusTableProps {
@@ -176,8 +194,8 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
176194 < TableScope
177195 type = "table"
178196 onKeyboardOut = { onKeyboardOut }
179- id = { id }
180- wrap = { wrap }
197+ wrapX = { wrapX }
198+ wrapY = { wrapY }
181199 tabScopeRef = { tabScopeRef }
182200 allowModifiers = { allowModifiers } >
183201 { TabScope ? (
@@ -193,7 +211,7 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
193211 return < TableScope type = "row" > { children} < / T a b l e S c o p e > ;
194212 }
195213
196- function Cell ( { children, onKeyDown} ) : FocusCellProps {
214+ function Cell ( { children, onKeyDown, colSpan } ) : FocusCellProps {
197215 const scopeRef = useRef ( null ) ;
198216 const keyboard = useKeyboard ( {
199217 onKeyDown ( event : KeyboardEvent ) : void {
@@ -232,18 +250,18 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
232250 }
233251 switch ( key ) {
234252 case 'ArrowUp' : {
235- const [ cells , cellIndex ] = getRowCells ( currentCell ) ;
253+ const [ cells , , cellIndexWithColSpan ] = getRowCells ( currentCell ) ;
236254 if ( cells !== null ) {
237255 const [ rows , rowIndex ] = getRows ( currentCell ) ;
238256 if ( rows !== null ) {
239257 if ( rowIndex > 0 ) {
240258 const row = rows [ rowIndex - 1 ] ;
241- focusCellByIndex ( row , cellIndex , event ) ;
259+ focusCellByColumnIndex ( row , cellIndexWithColSpan , event ) ;
242260 } else if ( rowIndex === 0 ) {
243- const wrap = getTableProps ( currentCell ) . wrap ;
244- if ( wrap ) {
261+ const wrapY = getTableProps ( currentCell ) . wrapY ;
262+ if ( wrapY ) {
245263 const row = rows [ rows . length - 1 ] ;
246- focusCellByIndex ( row , cellIndex , event ) ;
264+ focusCellByColumnIndex ( row , cellIndexWithColSpan , event ) ;
247265 } else {
248266 triggerNavigateOut ( currentCell , 'up' , event ) ;
249267 }
@@ -253,22 +271,22 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
253271 return ;
254272 }
255273 case 'ArrowDown' : {
256- const [ cells , cellIndex ] = getRowCells ( currentCell ) ;
274+ const [ cells , , cellIndexWithColSpan ] = getRowCells ( currentCell ) ;
257275 if ( cells !== null ) {
258276 const [ rows , rowIndex ] = getRows ( currentCell ) ;
259277 if ( rows !== null ) {
260278 if ( rowIndex !== - 1 ) {
261279 if ( rowIndex === rows . length - 1 ) {
262- const wrap = getTableProps ( currentCell ) . wrap ;
263- if ( wrap ) {
280+ const wrapY = getTableProps ( currentCell ) . wrapY ;
281+ if ( wrapY ) {
264282 const row = rows [ 0 ] ;
265- focusCellByIndex ( row , cellIndex , event ) ;
283+ focusCellByColumnIndex ( row , cellIndexWithColSpan , event ) ;
266284 } else {
267285 triggerNavigateOut ( currentCell , 'down' , event ) ;
268286 }
269287 } else {
270288 const row = rows [ rowIndex + 1 ] ;
271- focusCellByIndex ( row , cellIndex , event ) ;
289+ focusCellByColumnIndex ( row , cellIndexWithColSpan , event ) ;
272290 }
273291 }
274292 }
@@ -282,8 +300,8 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
282300 focusScope ( cells [ rowIndex - 1 ] ) ;
283301 event . preventDefault ( ) ;
284302 } else if ( rowIndex === 0 ) {
285- const wrap = getTableProps ( currentCell ) . wrap ;
286- if ( wrap ) {
303+ const wrapX = getTableProps ( currentCell ) . wrapX ;
304+ if ( wrapX ) {
287305 focusScope ( cells [ cells . length - 1 ] , event ) ;
288306 } else {
289307 triggerNavigateOut ( currentCell , 'left' , event ) ;
@@ -297,8 +315,8 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
297315 if ( cells !== null ) {
298316 if ( rowIndex !== - 1 ) {
299317 if ( rowIndex === cells . length - 1 ) {
300- const wrap = getTableProps ( currentCell ) . wrap ;
301- if ( wrap ) {
318+ const wrapX = getTableProps ( currentCell ) . wrapX ;
319+ if ( wrapX ) {
302320 focusScope ( cells [ 0 ] , event ) ;
303321 } else {
304322 triggerNavigateOut ( currentCell , 'right' , event ) ;
@@ -317,7 +335,11 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
317335 } ,
318336 } ) ;
319337 return (
320- < TableScope listeners = { keyboard } ref = { scopeRef } type = "cell" >
338+ < TableScope
339+ listeners = { keyboard }
340+ ref = { scopeRef }
341+ type = "cell"
342+ colSpan = { colSpan } >
321343 { children }
322344 </ TableScope >
323345 ) ;
0 commit comments