[react-interactions] FocusTable key press bound propgataion (#16895)
Dominic Gannaway committed
Sep 25, 2019 at 21:12 UTC
4bb0e96b4b0dd5db4bb349cd27425e5594970eb3
2 files changed
+76
-4
packages/react-interactions/accessibility/src/FocusTable.js
+7
-4
@@ -101,6 +101,7 @@ function getRows(currentCell: ReactScopeMethods) {
101
function triggerNavigateOut(
102
currentCell: ReactScopeMethods,
103
direction: 'left' | 'right' | 'up' | 'down',
104
+ event,
105
): void {
106
const row = currentCell.getParent();
107
if (row !== null && row.getProps().type === 'row') {
@@ -122,9 +123,11 @@ function triggerNavigateOut(
123
}
124
};
125
onKeyboardOut(direction, focusTableByID);
126
+ return;
127
}
128
}
129
}
130
+ event.continuePropagation();
131
}
132
133
export function createFocusTable(scope: ReactScope): Array<React.Component> {
@@ -162,7 +165,7 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
165
focusCellByIndex(row, cellIndex);
166
event.preventDefault();
167
} else if (rowIndex === 0) {
165
- triggerNavigateOut(currentCell, 'up');
168
+ triggerNavigateOut(currentCell, 'up', event);
169
}
170
}
171
}
@@ -175,7 +178,7 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
178
if (rows !== null) {
179
if (rowIndex !== -1) {
180
if (rowIndex === rows.length - 1) {
178
- triggerNavigateOut(currentCell, 'down');
181
+ triggerNavigateOut(currentCell, 'down', event);
182
} else {
183
const row = rows[rowIndex + 1];
184
focusCellByIndex(row, cellIndex);
@@ -193,7 +196,7 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
196
focusCell(cells[rowIndex - 1]);
197
event.preventDefault();
198
} else if (rowIndex === 0) {
196
- triggerNavigateOut(currentCell, 'left');
199
+ triggerNavigateOut(currentCell, 'left', event);
200
}
201
}
202
return;
@@ -203,7 +206,7 @@ export function createFocusTable(scope: ReactScope): Array<React.Component> {
206
if (cells !== null) {
207
if (rowIndex !== -1) {
208
if (rowIndex === cells.length - 1) {
206
- triggerNavigateOut(currentCell, 'right');
209
+ triggerNavigateOut(currentCell, 'right', event);
210
} else {
211
focusCell(cells[rowIndex + 1]);
212
event.preventDefault();
packages/react-interactions/accessibility/src/__tests__/FocusTable-test.internal.js
+69
@@ -257,5 +257,74 @@ describe('FocusTable', () => {
257
});
258
expect(document.activeElement.textContent).toBe('A3');
259
});
260
+
261
+ it('handles nested tables correctly', () => {
262
+ const CustomScope = React.unstable_createScope((type, props) => {
263
+ return type === 'input';
264
+ });
265
+ const [FocusTable, FocusRow, FocusCell] = createFocusTable(CustomScope);
266
+ const firstRef = React.createRef();
267
+
268
+ function Test() {
269
+ return (
270
+ <FocusTable>
271
+ <div>
272
+ <FocusRow>
273
+ <FocusCell>
274
+ <FocusTable>
275
+ <FocusRow>
276
+ <FocusCell>
277
+ <input
278
+ placeholder="Nested A1"
279
+ tabIndex={0}
280
+ ref={firstRef}
281
+ />
282
+ </FocusCell>
283
+ <FocusCell>
284
+ <input placeholder="Nested B1" tabIndex={0} />
285
+ </FocusCell>
286
+ </FocusRow>
287
+ </FocusTable>
288
+ </FocusCell>
289
+ <FocusCell>
290
+ <input placeholder="B1" tabIndex={-1} />
291
+ </FocusCell>
292
+ <FocusCell>
293
+ <input placeholder="C1" tabIndex={-1} />
294
+ </FocusCell>
295
+ </FocusRow>
296
+ </div>
297
+ <div>
298
+ <FocusRow>
299
+ <FocusCell>
300
+ <input placeholder="A2" tabIndex={-1} />
301
+ </FocusCell>
302
+ <FocusCell>
303
+ <input placeholder="B2" tabIndex={-1} />
304
+ </FocusCell>
305
+ <FocusCell>
306
+ <input placeholder="C1" tabIndex={-1} />
307
+ </FocusCell>
308
+ </FocusRow>
309
+ </div>
310
+ </FocusTable>
311
+ );
312
+ }
313
+
314
+ ReactDOM.render(<Test />, container);
315
+ firstRef.current.focus();
316
+
317
+ const nestedA1 = createEventTarget(document.activeElement);
318
+ nestedA1.keydown({
319
+ key: 'ArrowRight',
320
+ });
321
+ expect(document.activeElement.placeholder).toBe('Nested B1');
322
+
323
+ const nestedB1 = createEventTarget(document.activeElement);
324
+ nestedB1.keydown({
325
+ key: 'ArrowRight',
326
+ });
327
+ expect(document.activeElement.placeholder).toBe('B1');
328
+ });
329
});
330
});