Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/eui/changelogs/upcoming/8598.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**Accessibility**

- Fixed duplicate screen reader output on `EuiDataGrid` for single sorted header cells with actions
Original file line number Diff line number Diff line change
Expand Up @@ -56,42 +56,19 @@ describe('useColumnSorting', () => {
});

describe('when only the current column is being sorted', () => {
describe('when the header cell has no actions', () => {
it('renders aria-sort but not sortingScreenReaderText', () => {
const { ariaSort, sortingScreenReaderText } = renderHook(() =>
useColumnSorting({
...mockSortingArgs,
sorting: {
onSort,
columns: [{ id: columnId, direction: 'asc' }],
},
hasColumnActions: false,
})
).result.current;

expect(ariaSort).toEqual('ascending');
expect(getRender(sortingScreenReaderText)).toHaveTextContent('');
});
});

describe('when the header cell has actions', () => {
it('renders aria-sort and sortingScreenReaderText', () => {
const { ariaSort, sortingScreenReaderText } = renderHook(() =>
useColumnSorting({
...mockSortingArgs,
sorting: {
onSort,
columns: [{ id: columnId, direction: 'desc' }],
},
hasColumnActions: true,
})
).result.current;

expect(ariaSort).toEqual('descending');
expect(getRender(sortingScreenReaderText)).toHaveTextContent(
'Sorted descending.'
);
});
it('renders aria-sort but not sortingScreenReaderText', () => {
const { ariaSort, sortingScreenReaderText } = renderHook(() =>
useColumnSorting({
...mockSortingArgs,
sorting: {
onSort,
columns: [{ id: columnId, direction: 'asc' }],
},
})
).result.current;

expect(ariaSort).toEqual('ascending');
expect(getRender(sortingScreenReaderText)).toHaveTextContent('');
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@ import { EuiDataGridSorting } from '../../data_grid_types';
export const useColumnSorting = ({
sorting,
id,
hasColumnActions,
}: {
sorting?: EuiDataGridSorting;
id: string;
hasColumnActions: boolean;
}) => {
const sortedColumn = useMemo(
() => sorting?.columns.find((col) => col.id === id),
Expand All @@ -49,30 +47,32 @@ export const useColumnSorting = ({
}, [id, isColumnSorted, sortedColumn]);

/**
* aria-sort attribute - should only be used when a single column is being sorted
* `aria-sort` attribute - should only be used when a single column is being sorted
* @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-sort
* @see https://www.w3.org/WAI/ARIA/apg/example-index/table/sortable-table.html
* @see https://github.com/w3c/aria/issues/283 for potential future multi-column usage
*/
const ariaSort: AriaAttributes['aria-sort'] =
isColumnSorted && hasOnlyOneSort
? sorting.columns[0].direction === 'asc'
? 'ascending'
: 'descending'
: undefined;
const hasAriaSortOnly = isColumnSorted && hasOnlyOneSort;

// aria-describedby ID for when aria-sort isn't sufficient
const ariaSort: AriaAttributes['aria-sort'] = hasAriaSortOnly
? sorting.columns[0].direction === 'asc'
? 'ascending'
: 'descending'
: undefined;

/**
* `aria-describedby` ID for when `aria-sort` cannot be used
*/
const sortingAriaId = useGeneratedHtmlId({
prefix: 'euiDataGridCellHeader',
suffix: 'sorting',
});

/**
* Sorting status - screen reader text
* Screen-reader-only sorting status, an alternative to `aria-sort` for multi-column sorting
*/
const sortingScreenReaderText = useMemo(() => {
if (!isColumnSorted) return null;
if (!hasColumnActions && hasOnlyOneSort) return null; // in this scenario, the `aria-sort` attribute will be used by screen readers
if (!isColumnSorted || hasAriaSortOnly) return null;
return (
<p id={sortingAriaId} hidden>
{sorting?.columns?.map(({ id: columnId, direction }, index) => {
Expand Down Expand Up @@ -141,10 +141,10 @@ export const useColumnSorting = ({
);
}, [
isColumnSorted,
hasColumnActions,
hasOnlyOneSort,
sorting,
hasAriaSortOnly,
sortingAriaId,
sorting?.columns,
hasOnlyOneSort,
]);

return { sortingArrow, ariaSort, sortingAriaId, sortingScreenReaderText };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ export const EuiDataGridHeaderCell: FunctionComponent<EuiDataGridHeaderCellProps
useColumnSorting({
sorting,
id,
hasColumnActions,
});

const columnResizer = useMemo(() => {
Expand Down