Repository navigation
fix(a11y): improve screen reader and keyboard access - #328
Merged
Merged
Conversation
- Page shells have a main landmark, the menus are nav landmarks and active links mark the current page. A skip control moves focus to the content. The page language follows the locale. - Dialogs are named by their heading through a new appDialogTitle directive, which works like mat-dialog-title without its styles. - simple-table and the upload library expose rows, column headers, cells and sort state, with row numbers for virtual scrolling. - Settings toggles are one checkbox, not a checkbox in a button. Module status, badges, filters, loaders and icon tooltips have names. Error toasts are announced at once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
[High impact] The PR appears safe to merge; the previous language-fallback issue is fixed. SummaryThis PR improves screen reader and keyboard access across page shells, dialogs, tables, loaders, and controls.
Reviews (3) · Last reviewed commit: "fix(a11y): set page language from the lo..." · Reviewed by Greptile |
- The item tabs control a real tab panel that holds the page content, not an empty hidden one. - Spinners and progress bars without a name are named "Loading". Idle progress bars use visibility instead of opacity, so screen readers no longer find them. - Table rows that can be dragged also move with the up and down arrow keys on the handle. Focus follows the moved row. - Columns with a blank header get a name for screen readers through the new hide_name option. Trigger and edge status dots get text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The page language was set before the translations loaded. A locale without a translation file, e.g. fr-FR, shows the English fallback, but the page stayed marked as French, so screen readers used the wrong voice. Set it once loading ends, from the translations in use. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Deployment failed for project backoffice with the following error: Learn More: https://vercel.com/placeos?upgradeToPro=build-rate-limit |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Screen reader and keyboard users had several blockers in Backoffice:
simple-table(32 uses) and the upload library hadrole="table"with no rows, column headers or cells. 31 columns had blank headers.An axe-core scan of the main routes found 226 "content not in a landmark" items, plus table, button-name, label, progress-bar and nested-control errors.
Solution
<main id="main-content">. The menu and item list are<nav>landmarks, and active links havearia-current="page". A "Skip to main content" control comes first in the menu and right after the item search, which has focus on load.<html lang>follows the locale.appDialogTitledirective names the dialog by its heading, likemat-dialog-titlewithout its styles.aria-sort, witharia-rowcount/aria-rowindexfor virtual scrolling. A newhide_namecolumn option gives blank headers a name that only screen readers hear.mat-tab-nav-panel, and the item tabs control it.LoadingLabelDirectivenames unnamed spinners and bars "Loading". Idle bars useinvisibleinstead ofopacity-0, so they keep their space but leave the accessibility tree.role="checkbox"button. Status dots have text, e.g. "Connection status: Connected". Badges, the filter, the debug checkbox and the edge link have names. Error toasts are assertive, the offline banner is an alert, and icons with their own tooltip are named by it.The only visible change is the skip control, which shows only when it has keyboard focus.
After the change, axe reports 0 violations on the scanned routes, including all system tabs. Lint, build, unit tests (1077) and the mock e2e suite (150) pass.
Not in this PR: a single-pointer alternative to dragging rows (WCAG 2.5.7). Keyboard moves are added, pointer buttons are not.
Reviewed with sol-loop: 4 rounds with gpt-6.1-sol on high (2 per commit).
Changes made by Claude Opus 5.5 (
claude-opus-5-5) in Claude Code, running in T3 Code.🤖 Generated with Claude Code