Skip to content

[Improvement]: A11y — aria-live regions for chat streaming, updater and git feedback#172

Open
matiaspalmac wants to merge 2 commits intoTrixtyAI:mainfrom
matiaspalmac:improvements/a11y-aria-live
Open

[Improvement]: A11y — aria-live regions for chat streaming, updater and git feedback#172
matiaspalmac wants to merge 2 commits intoTrixtyAI:mainfrom
matiaspalmac:improvements/a11y-aria-live

Conversation

@matiaspalmac
Copy link
Copy Markdown
Contributor

Description

Screen readers were silent on four dynamic UI surfaces that signal completion or error state. This PR adds the missing ARIA live regions so assistive technologies can hear what sighted users see.

Change

  • AiChatComponent — the chat transcript scroll container is now role="log" / aria-live="polite" with aria-relevant="additions text" and aria-busy={isTyping}. Streaming replies, warnings, and tool-run status are finally announced.
  • UpdaterDialog — the toast is role="status" / aria-live="polite" during normal phases and escalates to role="alert" / aria-live="assertive" when the updater reports an error, matching user urgency.
  • GitExplorerComponent:
    • The gitFeedback flash banner is now a persistent role="status" region toggled via sr-only instead of being conditionally mounted — live regions must stay in the DOM before their text changes or the update is missed.
    • The merge-conflict banner is role="alert" + aria-live="assertive" so conflicts surface immediately rather than waiting for the user to land focus on that region.
  • Added ai.chat_log_label i18n key (EN + ES).

Related Issue

Closes #105

Trade-offs

  • The git feedback live region is always present in the DOM (as sr-only when empty). That trades a few bytes of markup for reliable screen-reader announcements — keeping the conditional mount would have defeated the purpose of the change for most AT implementations.
  • The updater's role flips between status and alert based on phase. Some screen readers announce a role change as a new element, which is the intended effect here (errors should interrupt).

Verification

  • pnpm --filter @trixty/desktop lint passes clean.
  • npx tsc --noEmit passes clean.
  • Manually traced every touched region against the WAI-ARIA 1.2 live-region authoring practices.
  • OS: Windows 11
  • Version: v1.0.10

Checklist

  • I have followed the project's coding guidelines.
  • Documentation has been updated (if applicable).
  • My changes generate no new warnings or errors.
  • This change is a minor improvement (for major new features use the Feature template).

…back

Screen readers were silent on four dynamic UI surfaces that announce
completion or error state:

- `AiChatComponent`: the chat transcript had no live region, so
  streaming assistant replies and tool-run status never reached AT.
  Marked the scroll container as `role=log` / `aria-live=polite` and
  toggle `aria-busy` while a response is in flight.
- `UpdaterDialog`: the toast is `role=status` / `aria-live=polite`
  normally and escalates to `role=alert` / `aria-live=assertive`
  when the updater reports an error.
- `GitExplorerComponent`:
  - `gitFeedback` flash banner is now a persistent `role=status`
    region (toggled via `sr-only`) instead of being conditionally
    mounted, so transient commit/push/stash messages are actually
    announced when they appear.
  - Merge-conflict banner is `role=alert` so the conflict is
    surfaced immediately rather than waiting for focus.

Closes TrixtyAI#105
Copilot AI review requested due to automatic review settings April 21, 2026 04:33
@github-actions github-actions bot added documentation Improvements or additions to documentation enhancement New feature or request labels Apr 21, 2026
@github-actions
Copy link
Copy Markdown

Thanks for the contribution! I'll review it as soon as possible. If you have still changes, please mark this PR as draft and all reviews will be cancelled. Tests reviews will be re-run only when the PR is marked as ready for review.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds missing ARIA live regions across key dynamic UI surfaces so screen readers announce chat output, updater status changes, and git feedback/conflict warnings (per issue #105).

Changes:

  • Adds role/aria-live semantics to the updater toast and git feedback/conflict banners.
  • Makes the chat transcript container a role="log" live region with aria-busy during typing.
  • Adds a new i18n label (ai.chat_log_label) in EN/ES for the chat transcript.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
apps/desktop/src/components/UpdaterDialog.tsx Wraps updater toast in a live region that escalates to alert semantics on error.
apps/desktop/src/addons/builtin.git-explorer/GitExplorerComponent.tsx Keeps git feedback live region mounted and marks merge conflicts as an assertive alert.
apps/desktop/src/addons/builtin.ai-assistant/AiChatComponent.tsx Marks chat transcript as a polite live log with a localized label and busy state.
apps/desktop/src/api/builtin.l10n.ts Adds ai.chat_log_label translations for EN/ES.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/desktop/src/components/UpdaterDialog.tsx Outdated
Copilot review on TrixtyAI#172 pointed out that wrapping the whole updater
toast in role=status + aria-atomic=true means screen readers
re-announce the entire toast (title, buttons, body) every time
`progress` ticks — and `updater-progress` fires on every downloaded
chunk during install, which can be dozens of events per second.

Replaced the toast-wide live region with a single `sr-only` span
that carries a pre-formatted phase string (title + status, without
the raw progress percentage). Sighted users see the same toast;
screen readers now get one announcement per phase change instead
of a flood during download, and the role still escalates to `alert`
on error.
@matiaspalmac
Copy link
Copy Markdown
Contributor Author

Addressed Copilot review: the previous implementation wrapped the whole toast in role=status aria-atomic=true, so updater-progress (which fires on every downloaded chunk — dozens/sec) would re-announce the entire toast including the buttons.

Replaced the toast-wide live region with a single sr-only <span> carrying a pre-formatted phase string (title + status, without the raw progress percentage). One announcement per phase change; still escalates to role=alert on error. Sighted users see no change. (65bdc7c)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Improvement]: A11y — aria-live regions for chat streaming, toasts, updater and git feedback

2 participants