Improve poll vote row TalkBack accessibility#6461
Conversation
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
|
@CodeRabbit review |
✅ Actions performedReview triggered.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThis PR refactors poll option interactions in ChangesPoll Accessibility and Interaction Improvements
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
SDK Size Comparison 📏
|
|
|
🚀 Available in v7.2.0 |



AND-1180
Goal
A11y audit of the poll message item (the poll bubble in the message list) surfaced three gaps:
LinearProgressIndicatorannounced redundant "X percent" on every option, duplicating the vote-count Text. Two options at 0 votes both announced "0 percent" — flagged repeatedly by Accessibility Scanner.This PR addresses all three.
Implementation
Row-level focusable + merged content.
PollOptionItemRowgetsModifier.semantics(mergeDescendants = true) {}in all cases. The row becomes a single TalkBack focus stop with the option text, vote count, and voter avatars merged into one announcement.!poll.closed), the row also getsModifier.toggleable(value = checked, role = toggleRole, onValueChange = onToggle). The role isRole.RadioButtonwhenpoll.maxVotesAllowed == 1(mutual-exclusion semantics),Role.Checkboxotherwise (multi-vote or unlimited). The previousonCheckedChangelambda is extracted intoonToggleand shared between the row'stoggleableand the innerRadioCheck'sonCheckedChange, so sighted taps on either the row or the radio circle fire the same logic.RadioCheckinside the row getsModifier.semantics { hideFromAccessibility() }since the row now owns the toggle action. The visual RadioCheck still responds to taps for sighted users.mergeDescendants = true, so TalkBack users can navigate option by option to read the final tallies.Hide redundant progress percentage.
LinearProgressIndicatormodifier gains.clearAndSetSemantics {}. Compose Material3 announces the indicator as "X percent" by default; the vote-count Text on the same row already conveys the count more precisely.Announce vote count with units.
Textgets acontentDescriptionfrom the existingstream_compose_poll_vote_countsplural (e.g. "5 votes" / "1 vote" / "0 votes"). Visible text stays compact ("5") so the visual layout is unchanged.🎨 UI Changes
No UI changes. All changes are accessibility-tree only.
Testing
Enable TalkBack on a physical device. Run the Compose sample, create a poll in a 1:1 or group channel.
maxVotesAllowed = 1and one with multi-vote (or unlimited). The TalkBack role should be "radio button" for the single-vote poll, "checkbox" for the multi-vote one.Summary by CodeRabbit
Bug Fixes
Accessibility