From 19c62ac40e32ef8d81235e49f24e62267702bc4e Mon Sep 17 00:00:00 2001 From: Charles McDonald Date: Thu, 25 Apr 2024 08:46:15 -0500 Subject: [PATCH] [terra-data-grid] Improve auto scroll for data grid components --- packages/terra-data-grid/CHANGELOG.md | 3 ++ packages/terra-data-grid/src/DataGrid.jsx | 8 ++- .../jest/__snapshots__/DataGrid.test.jsx.snap | 9 ++-- .../WorklistDataGrid.test.jsx.snap | 54 +++++++------------ packages/terra-table/CHANGELOG.md | 3 ++ .../src/subcomponents/ColumnHeaderCell.jsx | 19 +++++-- 6 files changed, 44 insertions(+), 52 deletions(-) diff --git a/packages/terra-data-grid/CHANGELOG.md b/packages/terra-data-grid/CHANGELOG.md index 1517745e94..01b9b9b3f0 100644 --- a/packages/terra-data-grid/CHANGELOG.md +++ b/packages/terra-data-grid/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Changed + * Limit scrolling on focus by moving the tab index to the first column header cell. + ## 1.29.0 - (April 18, 2024) * Changed diff --git a/packages/terra-data-grid/src/DataGrid.jsx b/packages/terra-data-grid/src/DataGrid.jsx index dba99b66e7..a3c4fd9211 100644 --- a/packages/terra-data-grid/src/DataGrid.jsx +++ b/packages/terra-data-grid/src/DataGrid.jsx @@ -375,9 +375,9 @@ const DataGrid = forwardRef((props, ref) => { */ const moveFocusFromGrid = (moveForward) => { // add all elements we want to include in our selection - const focusableElementSelector = 'a[href]:not([tabindex=\'-1\']), area[href]:not([tabindex=\'-1\']), input:not([disabled]):not([tabindex=\'-1\']), ' - + "select:not([disabled]):not([tabindex='-1']), textarea:not([disabled]):not([tabindex='-1']), button:not([disabled]):not([tabindex='-1']), " - + "iframe:not([tabindex='-1']), [tabindex]:not([tabindex='-1']), [contentEditable=true]:not([tabindex='-1'])"; + const focusableElementSelector = `#${id}, a[href]:not([tabindex='-1']), area[href]:not([tabindex='-1']), input:not([disabled]):not([tabindex='-1']), ` + + 'select:not([disabled]):not([tabindex=\'-1\']), textarea:not([disabled]):not([tabindex=\'-1\']), button:not([disabled]):not([tabindex=\'-1\']), ' + + 'iframe:not([tabindex=\'-1\']), [tabindex]:not([tabindex=\'-1\']), [contentEditable=true]:not([tabindex=\'-1\'])'; const focusableElements = [...document.body.querySelectorAll(`${focusableElementSelector}`)].filter( element => !element.hasAttribute('disabled') @@ -617,8 +617,6 @@ const DataGrid = forwardRef((props, ref) => { return ( // eslint-disable-next-line jsx-a11y/no-static-element-interactions
{ // For tables, we want elements to be tabbable when selectable, but not anytime else. let buttonTabIndex = isSelectable ? 0 : undefined; - if (isGridContext) { - // For grids, we only want 1 tab stop. We then define the focus behavior in DataGrid. - buttonTabIndex = isSelectable && displayName ? -1 : undefined; - } // Determine if button element is required for column header const hasButtonElement = (isSelectable && displayName) || (isActionCell && action); + let cellTabIndex; + + if (isGridContext) { + if (columnIndex === 0 && !isActionCell) { + buttonTabIndex = isSelectable && displayName ? 0 : undefined; + cellTabIndex = !hasButtonElement ? 0 : undefined; + } else { + // For grids, we only want 1 tab stop. We then define the focus behavior in DataGrid. + buttonTabIndex = isSelectable && displayName ? -1 : undefined; + cellTabIndex = !hasButtonElement ? -1 : undefined; + } + } + // Format header description for screenreader let headerDescription = displayName; headerDescription += errorIcon ? `, ${intl.formatMessage({ id: 'Terra.table.columnError' })}` : ''; @@ -421,7 +430,7 @@ const ColumnHeaderCell = (props) => { pinned: isPinnedColumn, 'last-pinned-column': columnIndex === columnContext.pinnedColumnHeaderOffsets.length - 1, })} - tabIndex={isGridContext && !hasButtonElement ? -1 : undefined} + tabIndex={cellTabIndex} role={!isActionCell ? 'columnheader' : undefined} scope={!isActionCell ? 'col' : undefined} // action Cell has to own a corresponding resize handle to avoid a double announcement on handle focus