Skip to content

fix(a11y): announce workflow / event status on timeline graph nodes (WCAG 1.4.1)#3443

Open
bilal-karim wants to merge 4 commits into
mainfrom
a11y/1.4.1-timeline-graph-aria-labels
Open

fix(a11y): announce workflow / event status on timeline graph nodes (WCAG 1.4.1)#3443
bilal-karim wants to merge 4 commits into
mainfrom
a11y/1.4.1-timeline-graph-aria-labels

Conversation

@bilal-karim
Copy link
Copy Markdown
Member

@bilal-karim bilal-karim commented May 22, 2026

Summary

Adds aria-label to each SVG <g role="button"> wrapper on the timeline-graph nodes so screen readers announce the workflow's id and status (or the event's type and classification) instead of bare "button".

 <g
   role="button"
   tabindex="0"
+  aria-label={translate('workflows.row-accessible-name', {
+    workflowId: workflow.id,
+    status: statusLabel,
+  })}
   class="relative cursor-pointer"
   {height}
 >

Previously, terminal statuses on the timeline graph (Completed, Failed, Canceled, TimedOut, Fired, Signaled) were distinguishable only by node color. The legend that decodes those colors lives inside a <Tooltip> — keyboard- and AT-reachable since PR #3429, but still requires the user to leave the graph, decode the color in the legend, and come back to identify each node. This change makes the graph self-describing at the node level.

Audit context

  • WCAG 2.2 SC 1.4.1 Use of Color (Level A) — Serious. Affects every workflow timeline view, which is the most-trafficked product surface for workflow investigation.
  • Issue file: audit-output/issues/1.4.1-timeline-graph-status.md (this is Option A — the recommended fix).
  • The sibling 1.4.1 fix (label required indicator) shipped in PR fix(a11y): non-color signal for Label required indicator (WCAG 1.4.1) #3439.

Cross-cutting wins

  • Closes the SC 4.1.2 Name, Role, Value missing-accessible-name defect on the same <g role="button"> widgets.
  • Closes the SC 1.3.1 Info and Relationships matrix-row item d (deferred to the Robust wave).

New i18n keys

  • workflows.row-accessible-name: "Workflow {{workflowId}}: {{status}}"
  • events.row-accessible-name: "Event {{eventType}}: {{classification}}"

Test plan

  • Open a workflow with failed/completed children. Tab into the timeline graph; with VoiceOver/NVDA, confirm each node announces "Workflow {id}: {status}, button" instead of just "button".
  • On the event history graph: tab to each dot; AT announces "Event {eventType}: {classification}, button".
  • Right-click → Inspect a node to confirm the <g> has the expected aria-label attribute.
  • axe-core svg-img-alt rule should no longer flag the timeline graph rows.
  • Zero visual change for sighted users.

🤖 Generated with Claude Code

A11y-Audit-Ref: 1.4.1-timeline-graph-status

…WCAG 1.4.1)

Adds aria-label to the SVG <g role="button"> wrapper on each
timeline-graph node so screen readers announce the workflow id
and status (or event type and classification) instead of bare
"button".

Previously, terminal statuses on the timeline graph (Completed,
Failed, Canceled, TimedOut, Fired, Signaled) were distinguishable
only by node color. The color legend lives inside a Tooltip --
keyboard- and AT-reachable since PR #3429, but still requires the
user to leave the graph, decode the color, and come back to
identify each node. This change makes the graph self-describing.

Cross-cutting wins:
- Closes the SC 4.1.2 missing-accessible-name defect on the same
  <g role="button"> widgets.
- Closes the SC 1.3.1 matrix-row item d deferred to the Robust
  wave.

New i18n keys:
- workflows.row-accessible-name = "Workflow {{workflowId}}: {{status}}"
- events.row-accessible-name = "Event {{eventType}}: {{classification}}"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bilal-karim bilal-karim requested a review from a team as a code owner May 22, 2026 16:40
@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
holocene Ready Ready Preview, Comment May 22, 2026 4:57pm

Request Review

@temporal-cicd
Copy link
Copy Markdown
Contributor

temporal-cicd Bot commented May 22, 2026

Warnings
⚠️

📊 Strict Mode: 2 errors in 1 file (0.2% of 914 total)

src/lib/components/lines-and-dots/svg/workflow-row.svelte (2)
  • L66:26: Type 'WorkflowStatus' is not assignable to type 'string | undefined'.
  • L76:24: Type 'WorkflowStatus' is not assignable to type 'string | undefined'.

Generated by 🚫 dangerJS against dc05e9a

CI's check-types caught two TS errors in the timeline-graph
aria-label additions:

1. translate(\`workflows.\${workflowStatusKey(status)}\`) -- the
   helper's return type widened to plain string, which doesn't
   satisfy the strongly-typed translation-key union.
2. translate(\`events.event-classification.\${classification.toLowerCase()}\`)
   -- same shape; toLowerCase() returns plain string.
3. event.eventType -- doesn't exist on PendingActivity (a union
   member of WorkflowEventWithPending).

Replaced both dynamic template-literal lookups with `as const`
record literals keyed by the literal-union enum values, so
TypeScript can narrow to the exact translation-key union. Added
an `in` operator narrowing for the eventType access.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
EventClassification union doesn't include 'Retrying' -- only the
i18n key exists. The lookup entry was unreachable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously the aria-label for a pending activity always said
"Pending" regardless of attempt count. The timeline already
communicates retry state visually (line styling), in the legend
("Retry" entry), and in the group-details row text -- but the
per-event aria-label missed it.

Check group.pendingActivity.attempt > 1 (matching the existing
group-details-row.svelte logic) and surface "Retrying" in the
aria-label when applicable. The events.event-classification.retrying
translation key already existed for this purpose.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added a11y Accessibility audit PR a11y:no-fix-doc No A11y-Audit-Ref line; audit team triage a11y:bucket-3 Bucket 3: engineer required a11y:sc-1.4.1 and removed a11y:no-fix-doc No A11y-Audit-Ref line; audit team triage labels May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a11y:bucket-3 Bucket 3: engineer required a11y:sc-1.4.1 a11y Accessibility audit PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant