fix(canvas): WCAG critical — ARIA live toasts, dialog focus trap, keyboard nav - #131
Merged
Merged
Conversation
…board nav Addresses the three release-blocking WCAG violations from the UX audit (3rd consecutive cycle) and the new ChatTab ARIA gap from Audit #2. Changes: - Toaster: split into polite (success/info) + assertive (error) live regions, both always in DOM so screen readers register them before any toast fires. Adds x dismiss button on every toast. Errors no longer auto-expire after 4s — persist until explicitly dismissed. - ConfirmDialog: on open, requestAnimationFrame focuses the first button inside the dialog. Tab/Shift-Tab is now trapped inside the dialog while open. Added role="dialog" aria-modal="true" and aria-labelledby pointing to the title h3. - WorkspaceNode: outer div gains role="button", tabIndex={0}, aria-label, aria-pressed, and onKeyDown (Enter/Space => selectNode, ContextMenu key => openContextMenu). Keyboard-only users can now reach and activate workspace nodes. - ChatTab sub-tab bar: role="tablist" on wrapper, role="tab" + aria-selected + aria-controls on each button, matching role="tabpanel" + id on each panel div. Textarea gets aria-label="Message to agent". 453/453 Vitest tests pass. Production build clean (Next.js 15). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
fix(canvas): WCAG critical — ARIA live toasts, dialog focus trap, keyboard nav
This was referenced Apr 27, 2026
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Apr 30, 2026
publish-runtime.yml had a broad smoke (AgentCard call-shape, well-known
mount alignment, new_text_message) inline as a heredoc. runtime-prbuild-
compat.yml had a narrow inline smoke (just `from main import main_sync`).
Result: a PR could introduce SDK shape regressions that pass at PR time
and only fail at publish time, post-merge.
Extract the broad smoke into scripts/wheel_smoke.py and invoke it from
both workflows. PR-time gate now matches publish-time gate — same script,
same assertions. Eliminates the drift hazard of two heredocs that have
to be kept in lockstep manually.
Verified locally:
* Built wheel from workspace/ source, installed in venv, ran smoke → pass
* Simulated AgentCard kwarg-rename regression → smoke catches it as
`ValueError: Protocol message AgentCard has no "supported_interfaces"
field` (the exact failure mode of #2179 / supported_protocols incident)
Path filter for runtime-prbuild-compat extended to include
scripts/wheel_smoke.py so smoke-only edits get PR-validated. publish-
runtime path filter intentionally NOT extended — smoke-only edits should
not auto-trigger a PyPI version bump.
Subset of #131 (the broader "invoke main() against stub config" goal
remains pending — main() needs a config dir + stub platform server).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Three release-blocking WCAG violations (flagged across 3 consecutive UX audits) plus the new ChatTab ARIA gap from Audit #2. Implemented directly by Dev Lead due to engineering team workspace isolation since 08:15 restart.
Toaster.tsx): Two persistent ARIA live regions (polite for success/info, assertive for errors) always in the DOM. Dismiss×button on every toast. Errors no longer auto-expire — they persist until dismissed.ConfirmDialog.tsx):role="dialog" aria-modal="true"on container.aria-labelledbywired to titleh3. Focus moves to first button viarequestAnimationFrameon open. Tab/Shift-Tab trapped within dialog while open.WorkspaceNode.tsx):role="button" tabIndex={0}on outer div.aria-labelwith name + status.aria-pressedreflects selection state.onKeyDown: Enter/Space → selectNode, ContextMenu key → openContextMenu at element center.tabs/ChatTab.tsx):role="tablist"on sub-tab wrapper. Each button getsrole="tab",aria-selected,aria-controls. Each panel getsrole="tabpanel"+ matchingid. Textarea getsaria-label="Message to agent".Test plan
npm run build— clean compile, zero TypeScript errors (Next.js 15)npm test -- --run— 453/453 Vitest tests passhover:bg-white/10→hover:bg-zinc-700/50)Related audits
Resolves UX Audit #1 Batch A items 1–3 (Toaster, ConfirmDialog, WorkspaceNode).
Resolves UX Audit #2 ChatTab ARIA items A + B.
Note for UX Designer: PRs #122 and #123 are already merged — remote main is at
4a65c72. Pleasegit pullbefore next audit.🤖 Generated with Claude Code