a11y(polls): associate voter list with its answer for screen readers
CI / Build & Quality Checks (push) Successful in 10m46s
CI / Trigger Desktop Build (push) Successful in 6s

From review: the per-answer voter line sat inside the radiogroup with no
association, so a screen-reader user on the radio didn't hear who voted. Add
aria-describedby from each answer to its voter line (id poll-voters-<eventId>-
<answerId>) and prefix the line with "Voted by" for a clearer announcement.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 22:00:27 -04:00
co-authored by Claude Opus 4.8
parent 1aaea09fc9
commit 360e72f73c
@@ -339,6 +339,11 @@ export function PollContent({
aria-checked={selected}
aria-disabled={!canVote}
aria-label={isWinner ? `${text}, winning answer` : undefined}
aria-describedby={
showVoters && canShowVoters && (voters.get(id)?.length ?? 0) > 0
? `poll-voters-${eventId}-${id}`
: undefined
}
tabIndex={tabIndex}
onClick={canVote ? () => handleVote(id) : undefined}
style={{
@@ -428,11 +433,12 @@ export function PollContent({
</button>
{showVoters && canShowVoters && (voters.get(id)?.length ?? 0) > 0 && (
<Text
id={`poll-voters-${eventId}-${id}`}
size="T200"
priority="300"
style={{ padding: `0 ${config.space.S300} ${config.space.S100}` }}
>
{(voters.get(id) ?? []).map((s) => getMemberName(room, s)).join(', ')}
{`Voted by ${(voters.get(id) ?? []).map((s) => getMemberName(room, s)).join(', ')}`}
</Text>
)}
</React.Fragment>