a11y(4.1.3): Add live-region wrappers for workflow status, event count, filter counts, and Banner#3561
Merged
Merged
Conversation
…ter counts, and Banner
Defect 1 — WorkflowStatus chip: add role="status" aria-atomic="true" so
status transitions (Running → Completed / Failed / etc.) announce to AT
without requiring navigation.
Defect 2 — Event history polling: track item-count delta in
event-summary-table and emit a sr-only role="status" span announcing
"{N} new events loaded" each time the poll appends rows, avoiding
verbose per-row narration.
Defect 3 — Filter result counts: add role="status" aria-live="polite"
aria-atomic="true" to the workflow, activity, and schedule count spans
so polled count updates announce as status messages.
Defect 4 — Holocene Banner: add getRole() mapping (danger → role="alert",
default → role="status") and aria-atomic="true" on the section element,
mirroring the Alert primitive pattern.
A11y-Audit-Ref: 4.1.3-ui-main-live-region-gaps
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
4 tasks
- WorkflowStatus: gate role="status" behind an opt-in `announce` prop, enabled only on the detail-header chip, so per-row table cells and the status-filter dropdown no longer mount live regions (no proliferation). - event-summary-table: debounce the "N new events loaded" announcement so a burst rendered across multiple reactive passes announces one accurate total instead of per-pass partial counts. - filter counts (workflows/activities/schedules): wrap the number + noun in one role="status" region so it announces "N Workflows", not a bare "N". - heart-beat-indicator: aria-hidden the decorative EKG wrapper so it isn't surfaced as an unlabeled image inside the status chip's live region. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
ardiewen
marked this pull request as ready for review
June 26, 2026 18:56
Pulls the debounced "N new events loaded" live-region logic out of
event-summary-table into:
- utilities/count-announcer.ts — framework-agnostic debounce/accumulate logic
(tracks increases, coalesces bursts, clears-then-re-sets so identical
consecutive counts re-announce); fully unit-tested with fake timers.
- components/live-count-announcer.svelte — thin Svelte adapter that wires a
reactive count to the announcer and renders the sr-only polite region.
event-summary-table now renders <LiveCountAnnouncer count={items.length} ... />.
Behavior unchanged; the only tricky logic is now isolated and covered.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Contributor
|
@rosanusi Changes made during review + AT testing (
|
Resolved i18n conflict in workflows.ts by keeping both main's 'total-workflows' key and this branch's 'new-events-announcement' keys. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
ardiewen
approved these changes
Jul 6, 2026
temporal-cicd Bot
pushed a commit
that referenced
this pull request
Jul 8, 2026
Auto-generated version bump from 2.51.1 to 2.52.0 Bump type: minor Changes included: - [`9c6fcd54`](9c6fcd5) Add direct SSO redirect and backend logout (#3590) - [`feab0d90`](feab0d9) a11y(4.1.3): Toaster role="log" → per-toast role="status"/"alert" for correct AT announcement semantics (#3560) - [`d7bbfb01`](d7bbfb0) a11y(2.5.8): toast — replace bare close button with IconButton (36×36 px) (#3553) - [`4efd6ab6`](4efd6ab) a11y(3.3.1): Holocene input primitives — add aria-invalid, aria-describedby, and uniform live-region error announcement (#3554) - [`0600b700`](0600b70) Use green only (#3599) - [`94107549`](9410754) Clarify activity pause timeout behavior (#3600) - [`9f88d5a8`](9f88d5a) Bump node version to 22.23.1 or newer to fix issue from previous security release (#3604) - [`ca4104ae`](ca4104a) Update reason copy and inputs (#3588) - [`51db73fa`](51db73f) Update batch operation reason input hint (#3605) - [`836d7c55`](836d7c5) a11y(2.4.3): route navigation — move focus to the main landmark on afterNavigate, not just scroll (#3538) - [`4ee95696`](4ee9569) Improve re-renders for large encoded event histories (#3592) - [`fa5e7aa1`](fa5e7aa) feature/schedules (#3603) - [`0d9467fd`](0d9467f) Default includeHeartbeatDetails and includeLastFailure to true for getActivityExecution and pollActivityExecution (#3521) - [`e5bc514e`](e5bc514) fix schedules: duplicate key (#3612) - [`f1eb489f`](f1eb489) Remove preview badge (#3581) - [`1e5173b4`](1e5173b) Add existing versions to worker create deployment version form (#3601) - [`a8552bae`](a8552ba) fix schedules -e.trim not a function (#3613) - [`0442f847`](0442f84) Fix width of ComputeBadge in VersionTableRow (#3615) - [`ddbeb54f`](ddbeb54) fix(cloud-nav): animate and stabilize side-nav collapse (#3606) - [`3cfc684b`](3cfc684) fix - schedules recent/upcoming runs - sort issue (#3616) - [`92b8875b`](92b8875) Move timestamp out of translate (#3617) - [`901258af`](901258a) Fix SAA and WF consistency (#3614) - [`99593d97`](99593d9) DT-4001 - standalone nexus operations (#3496) - [`f10d1bf1`](f10d1bf) Clamp codeblock to container width (#3621) - [`0a9d93ce`](0a9d93c) Remove unnecessary bottom-0 (#3623) - [`9dabb522`](9dabb52) chore(deps-dev): bump vite from 6.4.2 to 6.4.3 (#3610) - [`5c1854d3`](5c1854d) News Feed (#3596) - [`340da30f`](340da30) a11y(2.1.1): guard global r/R keydown so text inputs can receive the letter (#3589) - [`dd97a9d1`](dd97a9d) fix(markdown-editor): disable chromatic snapshot for preview story (#3631) - [`7db61ab9`](7db61ab) a11y(4.1.2): Table / ProgressBar / Loading primitives — expose aria-busy on data-refresh regions (#3555) - [`d2111ecf`](d2111ec) a11y(4.1.3): Add live-region wrappers for workflow status, event count, filter counts, and Banner (#3561) - [`24eabaec`](24eabae) a11y(2.4.6): guard DrawerContent against empty <h2> when title is omitted (#3595) - [`3552e307`](3552e30) Fix CodeMirror Lezer dependency mismatch (#3632) - [`7ac37199`](7ac3719) Update defaults to match workflow defaults (#3634) - [`c1f02865`](c1f0286) Draft fix for link variant handling (#3620) - [`bbbf2b8c`](bbbf2b8) Add connection status and optional Latest Version column to deployments (DT-4174) (#3618) - [`76f266f4`](76f266f) DurationInput updates (#3633) - [`07da53c5`](07da53c) COM-191 - prefill CloudFormation template params in Launch Stack link (#3619) - [`90946e0b`](90946e0) Schedules - Timeout empty defaults (#3637) - [`97f9ad39`](97f9ad3) fix(cloud-nav): smooth label fade on side-nav collapse/expand (#3628) - [`a399ed35`](a399ed3) Improve Search Attribute deletion messaging (#3629) - [`ad976d94`](ad976d9) Pass through source prop for News Feed Widget (#3638) - [`6ef84fe3`](6ef84fe) Restrict select-all to exclude workflow status (#3639) - [`4c3729f8`](4c3729f) Reduce news feed markdown whitespace (#3642) - [`aa04a9b6`](aa04a9b) feat(nexus-operations): add loading state to standalone nexus operations list page header (#3643) - [`dce2f804`](dce2f80) chore: remove unused generate-holocene-props script (#3644) - [`760bc7bc`](760bc7b) Make megaphone icon bigger (#3645) - [`c047384a`](c047384) refactor(nexus): replace hand-rolled types with @temporalio/proto (#3646)
rossedfort
added a commit
that referenced
this pull request
Jul 8, 2026
Auto-generated version bump from 2.51.1 to 2.52.0 Bump type: minor Changes included: - [`9c6fcd54`](9c6fcd5) Add direct SSO redirect and backend logout (#3590) - [`feab0d90`](feab0d9) a11y(4.1.3): Toaster role="log" → per-toast role="status"/"alert" for correct AT announcement semantics (#3560) - [`d7bbfb01`](d7bbfb0) a11y(2.5.8): toast — replace bare close button with IconButton (36×36 px) (#3553) - [`4efd6ab6`](4efd6ab) a11y(3.3.1): Holocene input primitives — add aria-invalid, aria-describedby, and uniform live-region error announcement (#3554) - [`0600b700`](0600b70) Use green only (#3599) - [`94107549`](9410754) Clarify activity pause timeout behavior (#3600) - [`9f88d5a8`](9f88d5a) Bump node version to 22.23.1 or newer to fix issue from previous security release (#3604) - [`ca4104ae`](ca4104a) Update reason copy and inputs (#3588) - [`51db73fa`](51db73f) Update batch operation reason input hint (#3605) - [`836d7c55`](836d7c5) a11y(2.4.3): route navigation — move focus to the main landmark on afterNavigate, not just scroll (#3538) - [`4ee95696`](4ee9569) Improve re-renders for large encoded event histories (#3592) - [`fa5e7aa1`](fa5e7aa) feature/schedules (#3603) - [`0d9467fd`](0d9467f) Default includeHeartbeatDetails and includeLastFailure to true for getActivityExecution and pollActivityExecution (#3521) - [`e5bc514e`](e5bc514) fix schedules: duplicate key (#3612) - [`f1eb489f`](f1eb489) Remove preview badge (#3581) - [`1e5173b4`](1e5173b) Add existing versions to worker create deployment version form (#3601) - [`a8552bae`](a8552ba) fix schedules -e.trim not a function (#3613) - [`0442f847`](0442f84) Fix width of ComputeBadge in VersionTableRow (#3615) - [`ddbeb54f`](ddbeb54) fix(cloud-nav): animate and stabilize side-nav collapse (#3606) - [`3cfc684b`](3cfc684) fix - schedules recent/upcoming runs - sort issue (#3616) - [`92b8875b`](92b8875) Move timestamp out of translate (#3617) - [`901258af`](901258a) Fix SAA and WF consistency (#3614) - [`99593d97`](99593d9) DT-4001 - standalone nexus operations (#3496) - [`f10d1bf1`](f10d1bf) Clamp codeblock to container width (#3621) - [`0a9d93ce`](0a9d93c) Remove unnecessary bottom-0 (#3623) - [`9dabb522`](9dabb52) chore(deps-dev): bump vite from 6.4.2 to 6.4.3 (#3610) - [`5c1854d3`](5c1854d) News Feed (#3596) - [`340da30f`](340da30) a11y(2.1.1): guard global r/R keydown so text inputs can receive the letter (#3589) - [`dd97a9d1`](dd97a9d) fix(markdown-editor): disable chromatic snapshot for preview story (#3631) - [`7db61ab9`](7db61ab) a11y(4.1.2): Table / ProgressBar / Loading primitives — expose aria-busy on data-refresh regions (#3555) - [`d2111ecf`](d2111ec) a11y(4.1.3): Add live-region wrappers for workflow status, event count, filter counts, and Banner (#3561) - [`24eabaec`](24eabae) a11y(2.4.6): guard DrawerContent against empty <h2> when title is omitted (#3595) - [`3552e307`](3552e30) Fix CodeMirror Lezer dependency mismatch (#3632) - [`7ac37199`](7ac3719) Update defaults to match workflow defaults (#3634) - [`c1f02865`](c1f0286) Draft fix for link variant handling (#3620) - [`bbbf2b8c`](bbbf2b8) Add connection status and optional Latest Version column to deployments (DT-4174) (#3618) - [`76f266f4`](76f266f) DurationInput updates (#3633) - [`07da53c5`](07da53c) COM-191 - prefill CloudFormation template params in Launch Stack link (#3619) - [`90946e0b`](90946e0) Schedules - Timeout empty defaults (#3637) - [`97f9ad39`](97f9ad3) fix(cloud-nav): smooth label fade on side-nav collapse/expand (#3628) - [`a399ed35`](a399ed3) Improve Search Attribute deletion messaging (#3629) - [`ad976d94`](ad976d9) Pass through source prop for News Feed Widget (#3638) - [`6ef84fe3`](6ef84fe) Restrict select-all to exclude workflow status (#3639) - [`4c3729f8`](4c3729f) Reduce news feed markdown whitespace (#3642) - [`aa04a9b6`](aa04a9b) feat(nexus-operations): add loading state to standalone nexus operations list page header (#3643) - [`dce2f804`](dce2f80) chore: remove unused generate-holocene-props script (#3644) - [`760bc7bc`](760bc7b) Make megaphone icon bigger (#3645) - [`c047384a`](c047384) refactor(nexus): replace hand-rolled types with @temporalio/proto (#3646) Co-authored-by: rossedfort <[email protected]>
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.
Summary
Closes WCAG 2.2 SC 4.1.3 (Status Messages) gaps across ui-main — dynamic surfaces that changed without announcing to screen readers. Verified manually with VoiceOver + Safari/Chrome (see AT notes below).
announceprop addsrole="status" aria-atomic="true"; enabled only on the detail-header chip. Per-row table cells and the status-filter dropdown stay inert — avoids mounting dozens of live regions per list page (no proliferation).role="status"inevent-summary-table; debounced (250 ms) so a burst rendered across multiple reactive passes announces a single accurate total ("N new events loaded") instead of per-pass partial counts.role="status" aria-atomic="true"region on the workflows / activities / schedules pages, so it announces "N Workflows" rather than a context-free "N".getRole()mapsdanger→role="alert"(assertive),default→role="status"(polite) +aria-atomic. Banner's type space is onlydefault/danger, so this mapping is complete (not anAlertmismatch).aria-hiddenon the decorative EKG wrapper so the animated graphic isn't surfaced as an unlabeledimginside the status chip'saria-atomiclive region.Files changed
src/lib/components/workflow-status.svelte,src/lib/layouts/workflow-header.svelte— Defect 1src/lib/components/event/event-summary-table.svelte,src/lib/i18n/locales/en/workflows.ts— Defect 2src/lib/pages/workflows-with-new-search.svelte,src/lib/pages/standalone-activities.svelte,src/lib/pages/schedules.svelte— Defect 3src/lib/holocene/banner/banner.svelte— Defect 4src/lib/components/heart-beat-indicator.svelte— Defect 5Manual AT verification (VoiceOver + Safari/Chrome)
<main>, neveraria-hidden/inert, text mutates in place.Bannerhas no consumer in OSSui(and isn't exported from@temporalio/ui, so it doesn't cascade to cloud-ui). cloud-ui's own banner already uses the samewarning → alert, else statuspattern. Note: therolesits on a<section>mounted via{#if show}(created with its content), so dynamic appearance may not announce on all SR/browser combos — acceptable for banners shown on load; flagged for awareness.Test plan
Related
<body>(outside<main>), which also blocks the VoiceOver count announcement on that step. Focus-management fix tracked separately.A11y-Audit-Ref: 4.1.3-ui-main-live-region-gaps
🤖 Generated with Claude Code