fix(a11y): announce the incoming-call overlay (role=alertdialog + name)
CI / Build & Quality Checks (push) Successful in 2m8s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 8s
CI / Trigger Desktop Build (push) Canceled after 0s
CI / Playwright smoke (e2e) (push) Canceled after 0s

The full-screen incoming-call overlay (shown when you're not already in a
call — the common case) had no role or accessible name on any ancestor of
its buttons, so a screen reader landed on an unlabelled button with no
hint that a call was ringing. The in-call banner variant already had
role="alert" + a label. The overlay's Dialog is now role="alertdialog",
aria-modal, labelled "Incoming voice|video call from <caller>".

Found while verifying #187 DP6 (decline still dismisses when the decline
send fails — it does).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
Lotus CI
2026-09-24 11:56:51 -04:00
co-authored by Claude Opus 5.5
parent f62c5d5778
commit ed87b700d9
+9 -1
View File
@@ -180,7 +180,15 @@ function IncomingCall({ dm, info, onIgnore, onAnswer, onReject }: IncomingCallPr
escapeDeactivates: false,
}}
>
<Dialog style={{ maxWidth: toRem(324) }}>
<Dialog
style={{ maxWidth: toRem(324) }}
// #187: the overlay had no role or name, so a screen reader landed
// on an unlabelled button with no hint that a call was ringing.
// Match the in-call banner (role="alert" + label).
role="alertdialog"
aria-modal="true"
aria-label={`Incoming ${info.intent === 'video' ? 'video' : 'voice'} call from ${getMemberName(info.room, info.sender) ?? info.sender}`}
>
<Box style={{ padding: config.space.S400 }} direction="Column" gap="700">
<Text size="T200" align="Center">
{getMemberName(info.room, info.sender)}