Skip to content

Table: rows with @select become keyboard-inert buttons (role="row" lost, no key handler, nested-interactive) #6837

Description

@mikec-chi

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:

  1. 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 Allow customizing or disabling the row tabindex for clickable rows #6710 for the tab-order half of this).
  2. role="row" is lost. With the role overridden to button, [role="row"] matches nothing on a populated grid; the table's semantics are gone for AT (and for test selectors).
  3. 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions