[docs][Table] Fix wrong number of rows reported to screen readers - #47653
[docs][Table] Fix wrong number of rows reported to screen readers#47653seomsoo wants to merge 4 commits into
Conversation
Netlify deploy previewhttps://deploy-preview-47653--material-ui.netlify.app/ Bundle size report
|
|
Looks solid to me! |
|
@siriwatknp @seomsoo I could not repro the issue. What am I missing? Here I'm using VO navigation with VO + Arrow Right / Left. I'm not skipping any row. Screen.Recording.2026-08-12.at.17.09.59.mov |
|
@silviuaavram You're not missing anything. I retested and I think this has changed since the issue was filed. The demo source hasn't changed since #46381 was opened (the only commit since is #48557, a CSS selector swap for visual regression). But I can't reproduce the row skipping either. I tested the production docs with VoiceOver in Safari and Chrome, and every row is announced and navigation is smooth. It seems to have been fixed on the browser side. One thing still holds. While collapsed, the table is exposed as 11 rows when there are only 6 (header + 5 desserts), so row indices don't match what's visible. Same in both browsers:
(VoiceOver is set to Korean in the first screenshot.) But that's a much smaller problem than the original "unusable", and I'm not sure it justifies the change on its own. The Happy to trim the PR to just that, or close it with the issue if you prefer. |
|
I will close the referenced issue and we can create another one, pointing specifically at the rows issue. Then we can change the PR to close that new issue instead. |
Deploy previewBundle size
Check out the code infra dashboard for more information about this PR. |
|
Updated to close #48960. Verified on the deploy preview: the table is now announced as 6 rows while
(VoiceOver is set to Korean in the screenshot.) |
|
Taking a look. There are some more possible fixes to be done. Will list them all. |
silviuaavram
left a comment
There was a problem hiding this comment.
I just realized that I commented on the js file, but feel free to apply the comments to the tsx. Overall looks good, we should be ready once the comments are addressed. Thanks!
| function Row(props) { | ||
| const { row } = props; | ||
| const [open, setOpen] = React.useState(false); | ||
| const [exited, setExited] = React.useState(true); |
There was a problem hiding this comment.
I'm OK if we just use open for aria-hidden. We can consider that while the animation is collapsing, the row is considered hidden for screen readers.
| <TableRow sx={{ '& > .MuiTableCell-root': { borderBottom: 'unset' } }}> | ||
| <TableCell> | ||
| <IconButton | ||
| aria-label="expand row" |
There was a problem hiding this comment.
let's also change this aria-label, depending on open, to narrate expand / collapse
| <TableCell> | ||
| <IconButton | ||
| aria-label="expand row" | ||
| aria-expanded={open} |
There was a problem hiding this comment.
let's also add aria-controls pointing to the row element which is controlled by this button.
| <TableCell align="right">{row.protein}</TableCell> | ||
| </TableRow> | ||
| <TableRow> | ||
| <TableRow aria-hidden={!open && exited ? true : undefined}> |
There was a problem hiding this comment.
feel free to add an id here with React.useId or add an id field to the data object and use that, so it can be linked to the button aria-controls
| in={open} | ||
| timeout="auto" | ||
| unmountOnExit | ||
| onEnter={() => setExited(false)} |


While collapsed, the demo still renders an empty
<TableRow>per dessert to hostthe collapsible detail. Those rows remain in the accessibility tree, so the table
is exposed as 11 rows when only 6 exist (header + 5 desserts), and row indices
don't match what is visible.
This marks the detail row as
aria-hiddenonce the collapse transition hasfinished, so it is only exposed while it actually has content. The
exitedstatekeeps the row exposed during the animation, and
aria-hiddenis never appliedwhile the row contains focusable content.
Verified with VoiceOver in Safari and Chrome: the table is announced as 6 rows
while collapsed.
Original recording (row skipping, no longer reproducible)
https://github.com/user-attachments/assets/cd2af7e6-6290-4aac-aa1e5-040ec8b2695d
Fixes #48960