chore(Dashboard): Improve Table accessibility (#28059)
This commit is contained in:
parent
0e096e8001
commit
69a7bfc88d
|
|
@ -274,7 +274,7 @@ export default typedMemo(function DataTable<D extends object>({
|
||||||
prepareRow(row);
|
prepareRow(row);
|
||||||
const { key: rowKey, ...rowProps } = row.getRowProps();
|
const { key: rowKey, ...rowProps } = row.getRowProps();
|
||||||
return (
|
return (
|
||||||
<tr key={rowKey || row.id} {...rowProps}>
|
<tr key={rowKey || row.id} {...rowProps} role="row">
|
||||||
{row.cells.map(cell =>
|
{row.cells.map(cell =>
|
||||||
cell.render('Cell', { key: cell.column.id }),
|
cell.render('Cell', { key: cell.column.id }),
|
||||||
)}
|
)}
|
||||||
|
|
@ -295,7 +295,11 @@ export default typedMemo(function DataTable<D extends object>({
|
||||||
const { key: footerGroupKey, ...footerGroupProps } =
|
const { key: footerGroupKey, ...footerGroupProps } =
|
||||||
footerGroup.getHeaderGroupProps();
|
footerGroup.getHeaderGroupProps();
|
||||||
return (
|
return (
|
||||||
<tr key={footerGroupKey || footerGroup.id} {...footerGroupProps}>
|
<tr
|
||||||
|
key={footerGroupKey || footerGroup.id}
|
||||||
|
{...footerGroupProps}
|
||||||
|
role="row"
|
||||||
|
>
|
||||||
{footerGroup.headers.map(column =>
|
{footerGroup.headers.map(column =>
|
||||||
column.render('Footer', { key: column.id }),
|
column.render('Footer', { key: column.id }),
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,7 @@ function StickyWrap({
|
||||||
let headerTable: ReactElement | undefined;
|
let headerTable: ReactElement | undefined;
|
||||||
let footerTable: ReactElement | undefined;
|
let footerTable: ReactElement | undefined;
|
||||||
let bodyTable: ReactElement | undefined;
|
let bodyTable: ReactElement | undefined;
|
||||||
|
|
||||||
if (needSizer) {
|
if (needSizer) {
|
||||||
const theadWithRef = React.cloneElement(thead, { ref: theadRef });
|
const theadWithRef = React.cloneElement(thead, { ref: theadRef });
|
||||||
const tfootWithRef = tfoot && React.cloneElement(tfoot, { ref: tfootRef });
|
const tfootWithRef = tfoot && React.cloneElement(tfoot, { ref: tfootRef });
|
||||||
|
|
@ -228,8 +229,15 @@ function StickyWrap({
|
||||||
visibility: 'hidden',
|
visibility: 'hidden',
|
||||||
scrollbarGutter: 'stable',
|
scrollbarGutter: 'stable',
|
||||||
}}
|
}}
|
||||||
|
role="presentation"
|
||||||
>
|
>
|
||||||
{React.cloneElement(table, {}, theadWithRef, tbody, tfootWithRef)}
|
{React.cloneElement(
|
||||||
|
table,
|
||||||
|
{ role: 'presentation' },
|
||||||
|
theadWithRef,
|
||||||
|
tbody,
|
||||||
|
tfootWithRef,
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -255,9 +263,10 @@ function StickyWrap({
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
scrollbarGutter: 'stable',
|
scrollbarGutter: 'stable',
|
||||||
}}
|
}}
|
||||||
|
role="presentation"
|
||||||
>
|
>
|
||||||
{React.cloneElement(
|
{React.cloneElement(
|
||||||
table,
|
React.cloneElement(table, { role: 'presentation' }),
|
||||||
mergeStyleProp(table, fixedTableLayout),
|
mergeStyleProp(table, fixedTableLayout),
|
||||||
colgroup,
|
colgroup,
|
||||||
thead,
|
thead,
|
||||||
|
|
@ -274,9 +283,10 @@ function StickyWrap({
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
scrollbarGutter: 'stable',
|
scrollbarGutter: 'stable',
|
||||||
}}
|
}}
|
||||||
|
role="presentation"
|
||||||
>
|
>
|
||||||
{React.cloneElement(
|
{React.cloneElement(
|
||||||
table,
|
React.cloneElement(table, { role: 'presentation' }),
|
||||||
mergeStyleProp(table, fixedTableLayout),
|
mergeStyleProp(table, fixedTableLayout),
|
||||||
colgroup,
|
colgroup,
|
||||||
tfoot,
|
tfoot,
|
||||||
|
|
@ -303,9 +313,10 @@ function StickyWrap({
|
||||||
scrollbarGutter: 'stable',
|
scrollbarGutter: 'stable',
|
||||||
}}
|
}}
|
||||||
onScroll={sticky.hasHorizontalScroll ? onScroll : undefined}
|
onScroll={sticky.hasHorizontalScroll ? onScroll : undefined}
|
||||||
|
role="presentation"
|
||||||
>
|
>
|
||||||
{React.cloneElement(
|
{React.cloneElement(
|
||||||
table,
|
React.cloneElement(table, { role: 'presentation' }),
|
||||||
mergeStyleProp(table, fixedTableLayout),
|
mergeStyleProp(table, fixedTableLayout),
|
||||||
colgroup,
|
colgroup,
|
||||||
tbody,
|
tbody,
|
||||||
|
|
@ -321,6 +332,7 @@ function StickyWrap({
|
||||||
height: sticky.realHeight || maxHeight,
|
height: sticky.realHeight || maxHeight,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
}}
|
}}
|
||||||
|
role="table"
|
||||||
>
|
>
|
||||||
{headerTable}
|
{headerTable}
|
||||||
{bodyTable}
|
{bodyTable}
|
||||||
|
|
|
||||||
|
|
@ -519,6 +519,8 @@ export default function TableChart<D extends DataRecord = DataRecord>(
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const cellProps = {
|
const cellProps = {
|
||||||
|
'aria-labelledby': `header-${column.key}`,
|
||||||
|
role: 'cell',
|
||||||
// show raw number in title in case of numeric values
|
// show raw number in title in case of numeric values
|
||||||
title: typeof value === 'number' ? String(value) : undefined,
|
title: typeof value === 'number' ? String(value) : undefined,
|
||||||
onClick:
|
onClick:
|
||||||
|
|
@ -547,6 +549,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
|
||||||
value == null ? 'dt-is-null' : '',
|
value == null ? 'dt-is-null' : '',
|
||||||
isActiveFilterValue(key, value) ? ' dt-is-active-filter' : '',
|
isActiveFilterValue(key, value) ? ' dt-is-active-filter' : '',
|
||||||
].join(' '),
|
].join(' '),
|
||||||
|
tabIndex: 0,
|
||||||
};
|
};
|
||||||
if (html) {
|
if (html) {
|
||||||
if (truncateLongCells) {
|
if (truncateLongCells) {
|
||||||
|
|
@ -576,6 +579,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
|
||||||
value && value < 0 ? 'negative' : 'positive',
|
value && value < 0 ? 'negative' : 'positive',
|
||||||
)}
|
)}
|
||||||
css={cellBarStyles}
|
css={cellBarStyles}
|
||||||
|
role="presentation"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{truncateLongCells ? (
|
{truncateLongCells ? (
|
||||||
|
|
@ -593,13 +597,13 @@ export default function TableChart<D extends DataRecord = DataRecord>(
|
||||||
},
|
},
|
||||||
Header: ({ column: col, onClick, style, onDragStart, onDrop }) => (
|
Header: ({ column: col, onClick, style, onDragStart, onDrop }) => (
|
||||||
<th
|
<th
|
||||||
|
id={`header-${column.key}`}
|
||||||
title={t('Shift + Click to sort by multiple columns')}
|
title={t('Shift + Click to sort by multiple columns')}
|
||||||
className={[className, col.isSorted ? 'is-sorted' : ''].join(' ')}
|
className={[className, col.isSorted ? 'is-sorted' : ''].join(' ')}
|
||||||
style={{
|
style={{
|
||||||
...sharedStyle,
|
...sharedStyle,
|
||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
tabIndex={0}
|
|
||||||
onKeyDown={(e: React.KeyboardEvent<HTMLElement>) => {
|
onKeyDown={(e: React.KeyboardEvent<HTMLElement>) => {
|
||||||
// programatically sort column on keypress
|
// programatically sort column on keypress
|
||||||
if (Object.values(ACTION_KEYS).includes(e.key)) {
|
if (Object.values(ACTION_KEYS).includes(e.key)) {
|
||||||
|
|
@ -615,6 +619,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
|
||||||
onDragEnter: e => e.preventDefault(),
|
onDragEnter: e => e.preventDefault(),
|
||||||
onDrop,
|
onDrop,
|
||||||
})}
|
})}
|
||||||
|
tabIndex={0}
|
||||||
>
|
>
|
||||||
{/* can't use `columnWidth &&` because it may also be zero */}
|
{/* can't use `columnWidth &&` because it may also be zero */}
|
||||||
{config.columnWidth ? (
|
{config.columnWidth ? (
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue