Table: rows with @select become keyboard-inert buttons (role="row" lost, no key handler, nested-interactive)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6.9k
- Forks
- 1.1k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 57
Description
Package
v4.x (present on v4 head — Table.vue lines 552–553)
Description
When @select is bound, each <tr> is rendered with:
:role="props.onSelect ? 'button' : undefined"
:tabindex="props.onSelect ? 0 : undefined"
and no keydown/keyup handler is bound anywhere in the component (0 occurrences in the file) — only @click. Three consequences, all measured with axe + manual keyboard testing on a populated table:
- Keyboard-inert focus stops (WCAG 2.1.1). Every row is focusable and announces as a button, but pressing Enter/Space does nothing — verified by focusing a row and pressing Enter: no navigation. Keyboard users can tab into hundreds of rows that lead nowhere (see also #6710 for the tab-order half of this).
role="row"is lost. With the role overridden tobutton,[role="row"]matches nothing on a populated grid; the table's semantics are gone for AT (and for test selectors).- nested-interactive (axe, serious, once per row). With
selectable+ row selection checkboxes, each "Select row" checkbox is now a control inside a button.
Suggested fix
Either bind a real key handler and keep an ARIA-correct pattern, or drop both attributes: @click still fires for pointer users, and keyboard access to the record is conventionally provided by a real link in the primary cell (the standard data-grid pattern, with native focus, native Enter, and open-in-new-tab). We have been running with both attributes removed, plus a link in the primary cell, across ~194 entity list pages gated by axe in CI: 0 violations, keyboard access works.
Reproduction
Docs example as-is: https://ui.nuxt.com/docs/components/table#with-row-select-event — bind @select, focus a row, press Enter (nothing happens); run axe with a selection column (nested-interactive per row); query [role="row"] (no matches on body rows).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/runtime/components/Table.vue at lines 552–553 and reproduce the documented row-select behavior using the Table docs example. Check keyboard activation, [role="row"] queries, and axe results with a selection column; done means the chosen pattern preserves keyboard access and removes the reported accessibility violations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nuxt, typescript
- Domain
- accessibility, frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100