Skip to content

a11y(4.1.2): Table / ProgressBar / Loading primitives — expose aria-busy on data-refresh regions#3555

Open
rosanusi wants to merge 1 commit into
mainfrom
wcag/4.1.2-aria-busy-loading-regions
Open

a11y(4.1.2): Table / ProgressBar / Loading primitives — expose aria-busy on data-refresh regions#3555
rosanusi wants to merge 1 commit into
mainfrom
wcag/4.1.2-aria-busy-loading-regions

Conversation

@rosanusi

@rosanusi rosanusi commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Sets aria-busy on regions that are actively loading or refreshing data, so AT users have a programmatic signal distinguishing "data is current" from "data is being updated."

Before: grep -r aria-busy src/ returned zero matches. Screen-reader users had no signal when tables refreshed, skeleton loaders appeared, or polling intervals fired.
After: Three primitives carry permanent or reactive aria-busy, and three polling consumers wire a reactive isPolling/isChecking flag.

Changes

Foundation primitives

  • table.sveltearia-busy={updating ? 'true' : undefined} on <table>. The updating prop already drives the visual <ProgressBar> in <thead>; this surfaces the same state programmatically.
  • progress-bar.svelterole="progressbar" + aria-busy="true" on the meter div. The bar's presence always implies busy; the role and attribute make it machine-readable.
  • loading.sveltearia-busy="true" + aria-live="polite" on the skeleton container. The aria-live lets AT announce load completion when the skeleton unmounts and real content renders.

Consumer wiring

  • workflow-run-layout.svelteisPolling state flips true at the start of the 10 s poll interval, resets via queueMicrotask after throttleRefresh(). The event-history slot wrapper carries aria-busy={isPolling}.
  • status-counts.sveltearia-busy={countPoller.loading} on the status-count container. countPoller.loading is already tracked by createCountPoller; no new state needed.
  • worker-details.svelteisCheckingHeartbeat state flips around the 10 s heartbeat staleness check interval via the same queueMicrotask pattern. The <section aria-label="worker-details"> carries aria-busy={isCheckingHeartbeat}.

Test plan

  • Workflows list: set updating={true} on a Table consumer and inspect DOM — confirm <table aria-busy="true">; confirm aria-busy disappears when updating={false}
  • Skeleton/Loading: confirm data-testid="loading" container has aria-busy="true" and aria-live="polite" while visible; no stale aria-busy after unmount
  • Workflow detail page: wait for the 10 s poll cycle; confirm the event-history wrapper alternates aria-busy="true" (during poll) → no attribute (after poll)
  • Worker detail page: wait for the 10 s heartbeat check interval; confirm <section> briefly carries aria-busy="true"
  • Workflow list status counts: confirm aria-busy={countPoller.loading} is true during the initial fetch and polling refetch
  • axe-core: zero new violations on a page with a busy table
  • Regression: visual <ProgressBar> inside Table <thead> renders unchanged

References

🤖 Generated with Claude Code

A11y-Audit-Ref: 4.1.2-aria-busy-loading-regions

…essBar, Loading, and three polling consumers

Foundation primitives:
- Table: aria-busy="true" on the <table> element when the updating prop is true
- ProgressBar: role="progressbar" + aria-busy="true" on the meter div (the bar's
  presence already implies busy; the role and aria-busy make it programmatic)
- Loading: aria-busy="true" + aria-live="polite" on the skeleton container so AT
  announces the end of loading when the skeleton unmounts

Consumer wiring:
- workflow-run-layout: isPolling state flips true/false around the 10 s poll
  interval via queueMicrotask; the event-history slot wrapper carries aria-busy
- status-counts: aria-busy bound directly to countPoller.loading (already tracked)
- worker-details: isCheckingHeartbeat state flips around the staleness check
  interval; the worker-details section carries aria-busy

A11y-Audit-Ref: 4.1.2-aria-busy-loading-regions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
holocene Ready Ready Preview, Comment Jun 12, 2026 2:03pm

Request Review

@github-actions github-actions Bot added a11y Accessibility audit PR a11y:no-fix-doc No A11y-Audit-Ref line; audit team triage labels Jun 12, 2026
@rosanusi rosanusi marked this pull request as ready for review June 12, 2026 14:20
@rosanusi rosanusi requested a review from a team as a code owner June 12, 2026 14:20
@github-actions github-actions Bot added a11y:bucket-3 Bucket 3: engineer required a11y:sc-4.1.2 and removed a11y:no-fix-doc No A11y-Audit-Ref line; audit team triage labels Jun 16, 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-4.1.2 a11y Accessibility audit PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant