From 5a6b3ccd98b502b76e9cbc2c5d7fda99a2a3ee03 Mon Sep 17 00:00:00 2001 From: afc163 Date: Wed, 27 Apr 2022 16:27:13 +0800 Subject: [PATCH] fix: Table columns sorter a11y experience (#35269) * Make table sortable columns focusable and keyboard accessible. * Fix typo. * Change focus style for sortable table column header from broken outline to color text. * Update snapshots. * Change order to fix lint error. * Add unit test to test sorting with keypress. * Update components/table/hooks/useSorter.tsx * chore: improve code style * style: use focus-visible * fix: test case * test: update snapshot Co-authored-by: Katsiaryna Pustakhod --- .../__snapshots__/components.test.js.snap | 6 +++++ .../table/__tests__/Table.sorter.test.js | 12 ++++++++++ .../__snapshots__/Table.sorter.test.js.snap | 2 ++ .../__snapshots__/demo-extend.test.ts.snap | 16 +++++++++++++ .../__tests__/__snapshots__/demo.test.js.snap | 16 +++++++++++++ components/table/hooks/useSorter.tsx | 23 ++++++++++++++----- components/table/style/index.less | 5 ++++ 7 files changed, 74 insertions(+), 6 deletions(-) diff --git a/components/config-provider/__tests__/__snapshots__/components.test.js.snap b/components/config-provider/__tests__/__snapshots__/components.test.js.snap index ab443c6ce974..8e6e60db561f 100644 --- a/components/config-provider/__tests__/__snapshots__/components.test.js.snap +++ b/components/config-provider/__tests__/__snapshots__/components.test.js.snap @@ -22867,6 +22867,7 @@ exports[`ConfigProvider components Table configProvider 1`] = `
{ expect(getNameColumn().prop('aria-sort')).toEqual('descending'); }); + it('sort records with keydown', () => { + const wrapper = mount(createTable()); + + // ascend + wrapper.find('.ant-table-column-sorters').simulate('keydown', { keyCode: 13 }); + expect(renderedNames(wrapper)).toEqual(['Jack', 'Jerry', 'Lucy', 'Tom']); + + // descend + wrapper.find('.ant-table-column-sorters').simulate('keydown', { keyCode: 13 }); + expect(renderedNames(wrapper)).toEqual(['Tom', 'Lucy', 'Jack', 'Jerry']); + }); + describe('can be controlled by sortOrder', () => { it('single', () => { const wrapper = mount( diff --git a/components/table/__tests__/__snapshots__/Table.sorter.test.js.snap b/components/table/__tests__/__snapshots__/Table.sorter.test.js.snap index 08c4f730c006..f8dead93cb12 100644 --- a/components/table/__tests__/__snapshots__/Table.sorter.test.js.snap +++ b/components/table/__tests__/__snapshots__/Table.sorter.test.js.snap @@ -7,6 +7,7 @@ exports[`Table.sorter renders sorter icon correctly 1`] = `
( function injectSorter( prefixCls: string, columns: ColumnsType, - sorterSates: SortState[], + sorterStates: SortState[], triggerSorter: (sorterSates: SortState) => void, defaultSortDirections: SortOrder[], tableLocale?: TableLocale, @@ -122,7 +123,7 @@ function injectSorter( ? tableShowSorterTooltip : newColumn.showSorterTooltip; const columnKey = getColumnKey(newColumn, columnPos); - const sorterState = sorterSates.find(({ key }) => key === columnKey); + const sorterState = sorterStates.find(({ key }) => key === columnKey); const sorterOrder = sorterState ? sorterState.sortOrder : null; const nextSortOrder = nextSortDirection(sortDirections, sorterOrder); const upNode: React.ReactNode = sortDirections.includes(ASCEND) && ( @@ -179,6 +180,7 @@ function injectSorter( const cell: React.HTMLAttributes = (column.onHeaderCell && column.onHeaderCell(col)) || {}; const originOnClick = cell.onClick; + const originOKeyDown = cell.onKeyDown; cell.onClick = (event: React.MouseEvent) => { triggerSorter({ column, @@ -186,9 +188,17 @@ function injectSorter( sortOrder: nextSortOrder, multiplePriority: getMultiplePriority(column), }); - - if (originOnClick) { - originOnClick(event); + originOnClick?.(event); + }; + cell.onKeyDown = (event: React.KeyboardEvent) => { + if (event.keyCode === KeyCode.ENTER) { + triggerSorter({ + column, + key: columnKey, + sortOrder: nextSortOrder, + multiplePriority: getMultiplePriority(column), + }); + originOKeyDown?.(event); } }; @@ -202,6 +212,7 @@ function injectSorter( } cell.className = classNames(cell.className, `${prefixCls}-column-has-sorters`); + cell.tabIndex = 0; return cell; }, @@ -214,7 +225,7 @@ function injectSorter( children: injectSorter( prefixCls, newColumn.children, - sorterSates, + sorterStates, triggerSorter, defaultSortDirections, tableLocale, diff --git a/components/table/style/index.less b/components/table/style/index.less index cf49f1d4c2f8..cc26a5953305 100644 --- a/components/table/style/index.less +++ b/components/table/style/index.less @@ -216,6 +216,7 @@ // ============================ Sorter ============================ &-thead th.@{table-prefix-cls}-column-has-sorters { + outline: none; cursor: pointer; transition: all 0.3s; @@ -227,6 +228,10 @@ } } + &:focus-visible { + color: @primary-color; + } + // https://github.com/ant-design/ant-design/issues/30969 &.@{table-prefix-cls}-cell-fix-left:hover, &.@{table-prefix-cls}-cell-fix-right:hover {