fix(site): add aria-label to icon-only Back navigation links#26222
fix(site): add aria-label to icon-only Back navigation links#26222tracyjohnsonux wants to merge 3 commits into
Conversation
Two icon-only Back navigation links in WorkspaceTopbar and TemplateVersionEditor had no accessible name. Their visible tooltip text is wired via aria-describedby, which provides a description, not an accessible name, so screen readers announce them as just "link". Add aria-label matching the tooltip text to satisfy: - WCAG 2.1 SC 4.1.2 Name, Role, Value (Level A) - WCAG 2.1 SC 2.4.4 Link Purpose (In Context) (Level A)
|
/coder-agents-review |
|
Chat: Review in progress | View chat deep-review v0.7.1 | Round 2 | Last posted: Round 2, 2 findings (2 P3), APPROVE. Review Finding inventoryFindings
Round logRound 1Panel (11 reviewers). Netero clean. 2 P3 from panel (both Bisky). 9 reviewers reported no findings. Reviewed against a26c46a..f36ba10. Round 2Panel (4 reviewers: Bisky, Mafuuu, Mafu-san, Razor). Netero clean, verified CRF-1 and CRF-2 fixes. All 4 panel reviewers confirmed fixes. No new code findings. Reviewed against a26c46a..6dbd0e5. About deep-reviewCRF = Coder Review Finding (P0-P4, Nit, Note)
|
There was a problem hiding this comment.
Clean, well-scoped accessibility fix. Both aria-label values match their TooltipContent text exactly, satisfying WCAG 2.5.3 (Label in Name). The PR correctly identifies the only two icon-only TopbarIconButton links in the codebase and fixes both; all other ChevronLeftIcon usages include visible text and already have accessible names. The WCAG analysis in the PR description is accurate and the fix follows existing aria-label conventions in both files.
Severity: 2 P3.
"I tried to build a case against this change and couldn't."
🤖 This review was automatically generated with Coder Agents.
| <TooltipTrigger asChild> | ||
| <TopbarIconButton asChild> | ||
| <RouterLink to="/workspaces"> | ||
| <RouterLink to="/workspaces" aria-label="Back to workspaces"> |
There was a problem hiding this comment.
P3 [CRF-1] No story asserts this link's accessible name. WorkspaceTopbar.stories.tsx already has play functions for other stories, but the Example story has no assertion verifying getByRole('link', { name: 'Back to workspaces' }). A one-line check would prove the fix works and catch the exact regression this PR exists to prevent. The pattern is established elsewhere (AgentsPageView.stories.tsx, SecretsPageView.stories.tsx).
Sketch:
export const Example: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(canvas.getByRole("link", { name: "Back to workspaces" })).toBeVisible();
},
};🤖
| <RouterLink to={templateLink}> | ||
| <RouterLink | ||
| to={templateLink} | ||
| aria-label="Back to the template" |
There was a problem hiding this comment.
P3 [CRF-2] Same gap: the Example story in TemplateVersionEditor.stories.tsx renders this back link but has no play function asserting getByRole('link', { name: 'Back to the template' }). This file has zero play functions across all stories, but this would be the natural place to start; it directly tests the fix.
Sketch:
export const Example: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(canvas.getByRole("link", { name: "Back to the template" })).toBeVisible();
},
};🤖
Add play function assertions to the Example stories for WorkspaceTopbar and TemplateVersionEditor that verify the icon-only Back links are reachable by their accessible name, locking in the WCAG 4.1.2 fix. Addresses CRF-1 and CRF-2 from coder-agents-review on #26222.
|
Addressed CRF-1 and CRF-2: added /coder-agents-review |
There was a problem hiding this comment.
Both R1 findings addressed. CRF-1 and CRF-2 verified fixed: each Example story now asserts getByRole("link", { name: "..." }) with the exact aria-label text. The assertions are non-vacuous (they would fail without the aria-label) and follow the project's Storybook testing conventions.
All 4 R2 panel reviewers and Netero independently confirmed the fixes. All PR claims re-verified against the code: aria-labels match tooltip text exactly, the two links are the only icon-only TopbarIconButton instances in the codebase, and the WCAG analysis is accurate.
Process note: the initial submission omitted story assertions for an accessibility change despite site/AGENTS.md requiring Storybook stories for accessibility behavior. The correction was swift, complete, and used the right pattern.
🤖 This review was automatically generated with Coder Agents.
| const canvas = within(canvasElement); | ||
| await expect( | ||
| canvas.getByRole("link", { name: "Back to the template" }), | ||
| ).toBeVisible(); |
There was a problem hiding this comment.
Check attribute too:
await expect(backLink).toHaveAttribute(
"aria-label",
"Back to the template",
);
| const canvas = within(canvasElement); | ||
| await expect( | ||
| canvas.getByRole("link", { name: "Back to workspaces" }), | ||
| ).toBeVisible(); |
There was a problem hiding this comment.
Same as above, check the attribute too
Summary
Two icon-only "Back" navigation links in the topbars have no accessible name. The visible tooltip text is wired via Radix's
aria-describedby, which provides a description, not an accessible name, so screen readers announce them as just "link" with no purpose.This adds an
aria-labelto each link matching the visible tooltip text, following the existingaria-labelconvention already used in these same files (e.g.aria-label="Create File",aria-label="Daily usage").WCAG 2.1 criteria addressed
Changes
site/src/pages/WorkspacePage/WorkspaceTopbar.tsxaria-label="Back to workspaces"site/src/pages/TemplateVersionEditorPage/TemplateVersionEditor.tsxaria-label="Back to the template"No visual change. No behavior change for sighted users.
aria-labelis safe here because the elements have no visible text content (only an icon), so it is not overriding a visible name.Why not rely on the existing Tooltip?
Radix UI's
Tooltipwiresaria-describedbyfrom the trigger to the tooltip content.aria-describedbyprovides an accessible description, not an accessible name. WCAG 4.1.2 requires interactive controls to have a programmatically determinable name, and screen readers do not consistently announce descriptions, especially when no name is present. Addingaria-labelgives the link a stable, programmatic name that exactly matches the visible tooltip text.Created by Coder Agents on behalf of @tracyjohnsonux.