See #2173 for the most up-to-date expected behavior of keyboard navigation that this PR implements. (Direct link to updated HLD)
The KeyboardNavigationManager class does the bulk of the work:
Tracks what is currently focused / should be focused (via properties focusType, and row/column/cellContent/headerActionIndex)
Note: If the user clicks in the table away from the current keyboard focus, the focus state would end up out-of-date. There's code in handleFocus() to handle this (see additional comments there)
Listens for table keypresses to handle arrow key navigation, Tab/Shift-Tab, PgUp/PgDn/etc key presses
If the user unfocuses and refocuses the table, re-focuses the appropriate elements in the table (handleFocus() again)
Tab/Shift-Tab behavior should match the HLD / expectations for ARIA treegrid. (Basically, Tab/Shift-Tab go through the tabbable elements of the header row / current row, not including cells/column headers, until the end is reached, then the table blurs and elements before/after it will be focused with additional Tab presses.)
The overall approach of only setting tabindex=0 on the single element in the table we want focused is called roving tabindex.
To ensure that we control what elements in the table should get focused, this PR updates tabindex on many elements in the table:
The table itself is tabindex=0 to ensure that it can be focused via Tab
Elements that are focusable by default such as buttons/anchors, are explicitly set to tabindex=-1 to start with, until the keyboard navigation code wants to focus them (then they're set to tabindex=0 just before being focused).
🧪 Testing
Manual testing (mostly Chrome, some Firefox).
Earlier builds had some Safari testing, but we should explicitly re-test there before submission.
@atmgrifter00 added you as the initial buddy for these changes. @jattasNI added you so you can begin reviewing it if you have time/ suggestions now, otherwise you can wait until I add owners.
Pull Request
🤨 Rationale
Resolves #1137
👩💻 Implementation
See #2173 for the most up-to-date expected behavior of keyboard navigation that this PR implements. (Direct link to updated HLD)
The
KeyboardNavigationManager
class does the bulk of the work:focusType
, androw/column/cellContent/headerActionIndex
)handleFocus()
to handle this (see additional comments there)handleFocus()
again)The overall approach of only setting
tabindex=0
on the single element in the table we want focused is called roving tabindex.To ensure that we control what elements in the table should get focused, this PR updates
tabindex
on many elements in the table:tabindex=0
to ensure that it can be focused viaTab
tabindex=-1
to start with, until the keyboard navigation code wants to focus them (then they're set totabindex=0
just before being focused).🧪 Testing
Keyboard navigation can be used on any/all of the existing table Storybook pages, once the table is focused.
✅ Checklist