Skip to content

address wrongful output of screen readers when interacting with KeyValue component - #18457

Open
aalves08 wants to merge 2 commits into
rancher:masterfrom
aalves08:14439
Open

address wrongful output of screen readers when interacting with KeyValue component#18457
aalves08 wants to merge 2 commits into
rancher:masterfrom
aalves08:14439

Conversation

@aalves08

Copy link
Copy Markdown
Member

Summary

Fixes #14439

Occurred changes and/or fixed issues

  • Fix aria-colcount on the KeyValue grid to include the remove column when it is present
  • Fix aria-rowcount to include the header row in the total count
  • Add missing role="rowgroup" and role="row" to the grouping divs so screen readers can build the correct grid ownership chain (grid → rowgroup → row → columnheader/gridcell)
  • Add aria-rowindex and aria-colindex to all header columnheader cells
  • Offset data-row aria-rowindex from i+1 to i+2 to account for the header row being row 1
  • Fix the no-data placeholder cells in view mode to include aria-rowindex and aria-colindex

Technical notes summary

The KeyValue component renders a CSS grid with role="grid" but was missing the required ARIA ownership chain. Without role="rowgroup" and role="row" on the intermediate wrapper divs, VoiceOver ignored the declared aria-colcount and computed the column count from all visible cells combined, producing incorrect announcements like "6 columns, 2 rows" for a 3-column grid. The fix adds the missing roles and corrects all row/column index attributes throughout the header, data, and empty-state rows.

Areas or cases that should be tested

  • Use VoiceOver (macOS) or NVDA (Windows) on a KeyValue component with one or more rows in edit mode — the screen reader should announce the correct column and row counts
  • Verify with the Selectors tab on a Service edit page (local cluster)
  • Verify with the Labels & Annotations section on any resource edit page
  • Verify the empty/view-only state (no rows, view mode) announces "2 rows, 2 columns"
  • Verify with extraColumns (e.g. environment variable editor) that the column count adjusts correctly
  • Tested locally with VoiceOver on Chrome

Areas which could experience regressions

  • Any page that renders the KeyValue component: Labels & Annotations, Selectors, ConfigMaps, Secrets, environment variables
  • Extensions or third-party plugins that rely on the KeyValue component slot name="remove" in the header (that slot was replaced with a plain div with role="columnheader")

Screenshot/Video

Checklist

  • The PR is linked to an issue and the linked issue has a Milestone, or no issue is needed
  • The PR has a Milestone
  • The PR template has been filled out
  • The PR has been self reviewed
  • The PR has a reviewer assigned
  • The PR has automated tests or clear instructions for manual tests and the linked issue has appropriate QA labels, or tests are not needed
  • The PR has reviewed with UX and tested in light and dark mode, or there are no UX changes
  • The PR has been reviewed in terms of Accessibility
  • The PR has considered, and if applicable tested with, the three Global Roles Admin, Standard User and User Base

@aalves08 aalves08 added this to the v2.16.0 milestone Jul 22, 2026
@aalves08
aalves08 requested a review from rak-phillip July 22, 2026 16:34
@aalves08 aalves08 self-assigned this Jul 22, 2026

@rak-phillip rak-phillip left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm noticing a discrepancy with the announcements from the screen reader. I have the following setup to test this change:

Image

This will read the following:

Foo1 Row2 Key Column1 Key for Row1 Edit Foo1

We are now announcing both "Row2" and "Row1" for the first input - this is still very confusing to navigate. I think that we need to fix the index for each of the inputs so that they match the row. We would need to update each of the possible input variants. It looks like CodeMirror only used index: i, while all others use index: i+1.

Comment thread shell/components/form/KeyValue.vue Outdated
@aalves08

Copy link
Copy Markdown
Member Author

I'm noticing a discrepancy with the announcements from the screen reader. I have the following setup to test this change:

Image This will read the following:

Foo1 Row2 Key Column1 Key for Row1 Edit Foo1

We are now announcing both "Row2" and "Row1" for the first input - this is still very confusing to navigate. I think that we need to fix the index for each of the inputs so that they match the row. We would need to update each of the possible input variants. It looks like CodeMirror only used index: i, while all others use index: i+1.

Screenshot 2026-07-27 at 11 43 55

The output of VoiceOver was:

Screenshot 2026-07-27 at 11 43 37

So there wasn't a problem for my environment. I am assuming that you are on a windows/linux env, which should be using a different screen reader.

Nevertheless, I've tweaked the indexes to make sure the rows are fine and the current output (after commit) in VoiceOver looks fine as well. Have a go in your env and see if it acts fine 🙏

@github-actions

Copy link
Copy Markdown
Contributor

🔄 Auto-Retry Failed Run

The Tests workflow run 30262245871 failed and has been automatically retried.

Follow up on the retried run here if needed: https://github.com/rancher/dashboard/actions/runs/30262245871

@aalves08
aalves08 requested a review from rak-phillip July 27, 2026 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

a11y: Column and row counts on the KeyValue are incorrect when they are interpreted with a screen reader

2 participants