The docs for a Simple Table say:
For accessibility, the first column is set to be a <th> element, with a scope of "col". This enables screen readers to identify a cell's value by it's row and column name.
The screen reader behavior referred to in the docs is no longer working in the Simple Table example, at least not using VoiceOver.
I believe this is because the cells are now being given a role="cell".
https://github.com/mui-org/material-ui/pull/20475 introduced the concept of a default role when passing a component to the TableCell via props. It definitely makes sense to add a role for accessibility when passing custom components, but probably not in cases where the component we are passing has native roles already (like a "th" tag)?
If that's not possible, as a user I'd at least like to have some sort of override, by passing a role directly or some other prop flag perhaps.
The following:
<TableCell component="th" scope="row">Cell content</TableCell>
Renders:
<th class="..." role="cell" scope="row">Cell content</th>
Should render:
<th class="..." scope="row">Cell content</th>
Simple Table documentation can be used to verify the issue
I'm using a nearly identical approach in my application, and after upgrading to v4.10.1 I have failing unit tests because cells that used to be recognized by their "rowheader" role are no longer recognized. Screen reader behavior that reads row titles when navigating the table is also broken in my application.
| Tech | Version |
| ----------- | ------- |
| Material-UI | v4.10.1 |
| React | v16.13.0 |
| Browser | Chrome Version 83.0.4103.61 (Official Build) (64-bit) |
I agree that we just shouldn't add the role and let users fix this on their own. I would argue this for any component usage since we can't reliably reason about it.
Almost all cases I see are invalid anyway (abuses styles without semantics, inaccessible regardless etc).
The original motivation in #20431 can be easily fixed with <TableCell component="div" role="cell" /> which is better anyway. It makes it clear that, despite not using semantic HTML you still want the accessible semantics. I would expect that <TableCell component="div" /> wants to work around cell semantics.
So this issue is now about removing the behaviour to set the role?
Anyway, I've looked into it really quickly and came up with this
diff --git a/packages/material-ui/src/TableCell/TableCell.js b/packages/material-ui/src/TableCell/TableCell.js
index d2d044720..6178f9b71 100644
--- a/packages/material-ui/src/TableCell/TableCell.js
+++ b/packages/material-ui/src/TableCell/TableCell.js
@@ -123,19 +123,27 @@ const TableCell = React.forwardRef(function TableCell(props, ref) {
const tablelvl2 = React.useContext(Tablelvl2Context);
const isHeadCell = tablelvl2 && tablelvl2.variant === 'head';
- let role;
let Component;
if (component) {
Component = component;
- role = isHeadCell ? 'columnheader' : 'cell';
} else {
Component = isHeadCell ? 'th' : 'td';
}
-
+
let scope = scopeProp;
if (!scope && isHeadCell) {
scope = 'col';
}
+
+ let role;
+ if (isHeadCell) {
+ role = 'columnheader';
+ } else if (scope === 'row') {
+ role = 'row';
+ } else {
+ role = 'cell';
+ }
+
const padding = paddingProp || (table && table.padding ? table.padding : 'default');
const size = sizeProp || (table && table.size ? table.size : 'medium');
const variant = variantProp || (tablelvl2 && tablelvl2.variant);
I'd just revert #20431 and add some regression test that illustrate why we the approach wasn't viable e.g. <TableCell component={CustomeTableHead} scope="row" /> renders a role colgroup.
Most helpful comment
I agree that we just shouldn't add the role and let users fix this on their own. I would argue this for any
componentusage since we can't reliably reason about it.Almost all cases I see are invalid anyway (abuses styles without semantics, inaccessible regardless etc).
The original motivation in #20431 can be easily fixed with
<TableCell component="div" role="cell" />which is better anyway. It makes it clear that, despite not using semantic HTML you still want the accessible semantics. I would expect that<TableCell component="div" />wants to work around cell semantics.