Skip to content

Improve channel header TalkBack accessibility#6464

Open
andremion wants to merge 5 commits into
developfrom
fix/compose-channel-header-avatar-talkback-focus
Open

Improve channel header TalkBack accessibility#6464
andremion wants to merge 5 commits into
developfrom
fix/compose-channel-header-avatar-talkback-focus

Conversation

@andremion
Copy link
Copy Markdown
Contributor

@andremion andremion commented May 21, 2026

AND-1180

Goal

The channel header has three accessibility gaps that prevent TalkBack users from interacting with it:

  1. The trailing avatar and the title Column are clickable with Role.Button but expose no readable name. TalkBack treats them as malformed buttons and skips them during swipe navigation.
  2. The channel name announces only when focus lands on it. There is no heading semantic, so TalkBack heading-navigation can't jump to it.
  3. On group channels with overflow members, the avatar's +N CountBadge and the channel formatter's +N more text both announce — TalkBack hears the count twice.

Implementation

  • Name the trailing avatar. Add Modifier.semantics(mergeDescendants = true) { contentDescription = avatarLabel } on the clickable, where avatarLabel comes from ChatTheme.channelNameFormatter.formatChannelName(channel, currentUser) — the same source the header title uses. TalkBack announces the avatar as "<channel name>, button. Double-tap to <onClickLabel>.".
  • Name the title Column when clickable. Add Modifier.semantics(mergeDescendants = true) {} after the clickable. The merge folds the title + subtitle Text content into the button's label, so TalkBack announces the column as one node.
  • Mark the title as a heading. Add Modifier.semantics { heading() } to the channel-name Text. TalkBack heading-navigation can now jump to the channel name.
  • Hide the overflow count badge. Add Modifier.semantics { hideFromAccessibility() } to the +N CountBadge inside StackedGroupAvatar. The badge is visual emphasis; the formatter's +N more text already conveys the count to TalkBack.

🎨 UI Changes

None. All changes live in the accessibility tree only.

Testing

Enable TalkBack on a physical device. Run the Compose sample.

  1. 1:1 DM — Open a 1:1 channel (e.g. the Padmé Amidala DM) and swipe through the header:
    • Back button: "Back".
    • Title: "<channel name>, heading". Heading-navigation jumps to it.
    • Avatar: "<channel name>, button. Double-tap to open conversation info." (the verb comes from onChannelAvatarClickLabel).
  2. Double-tap the avatar — the conversation info screen opens.
  3. Group with overflow — Open a group channel with 5+ members so the avatar renders the +N overflow badge. Confirm the avatar's announcement includes +N more once, not twice.
  4. Group with image — Open a group channel with a channel.image set (uses SimpleGroupAvatar, no CountBadge). Avatar still names itself correctly.
  5. Title click — If a downstream integration wires onHeaderTitleClick + onHeaderTitleClickLabel, TalkBack focuses the title Column as one node and announces "<title>. <subtitle>. Button. Double-tap to <label>.".

Summary by CodeRabbit

  • Accessibility
    • Enhanced screen reader support in channel headers with improved semantic descriptions
    • Better accessibility labels for channel avatars to help users navigate more effectively

Review Change Stack

@andremion andremion requested a review from a team as a code owner May 21, 2026 15:32
@andremion andremion added the pr:improvement Improvement label May 21, 2026
@andremion
Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled, or the PR is bot-authored.
  • An issue is linked (Linear ticket or GitHub issue), or the PR is bot-authored.

🎉 Great job! This PR is ready for review.

@andremion andremion enabled auto-merge (squash) May 21, 2026 15:33
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2ddda4d5-7fd7-4a99-a8e9-471163167375

📥 Commits

Reviewing files that changed from the base of the PR and between acf931d and 0ac0fa7.

📒 Files selected for processing (2)
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/avatar/ChannelAvatar.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/header/ChannelHeader.kt

Walkthrough

This pull request improves accessibility in Stream Chat's Compose UI by adding semantic metadata to two components: the ChannelAvatar hides its overflow count badge from screen readers, and the ChannelHeader marks its title as a heading and adds content descriptions for the avatar.

Changes

Accessibility Semantics for Chat Components

Layer / File(s) Summary
ChannelAvatar overflow badge accessibility
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/avatar/ChannelAvatar.kt
Adds Compose semantics imports and applies hideFromAccessibility() to the stacked-avatar overflow count badge so it is excluded from accessibility tree traversal.
ChannelHeader heading and avatar semantics
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/header/ChannelHeader.kt
Adds semantics imports, marks the title Text as a heading using semantics { heading() }, configures merge-descendants after clickable behavior, computes an avatarLabel from channel and user context, and applies merged semantics with contentDescription to the avatar for screen reader descriptions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • gpunto

Poem

🐰 With semantics we align,
Badges hidden, headings shine,
Screen readers now see the way,
Accessibility saves the day!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Improve channel header TalkBack accessibility' directly and clearly describes the main focus of the changeset, which adds accessibility improvements specifically to the channel header component for TalkBack users.
Description check ✅ Passed The description comprehensively covers the Goal, Implementation, and Testing sections with clear details about the accessibility gaps and solutions, though UI Changes section lacks the template's visual comparison structure and the Contributor/Reviewer Checklists are not addressed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/compose-channel-header-avatar-talkback-focus

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.82 MB 5.82 MB 0.00 MB 🟢
stream-chat-android-ui-components 11.02 MB 11.02 MB 0.00 MB 🟢
stream-chat-android-compose 12.42 MB 12.42 MB 0.00 MB 🟢

@sonarqubecloud
Copy link
Copy Markdown

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

Labels

pr:improvement Improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant