From 79f1423a30f365418d36273741a57d02f0a041c5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 1 Jul 2026 17:49:32 +0200 Subject: [PATCH 1/2] Fix accessibility: message composer label and 'Seen by' button (#6390, #6393) - MarkdownTextInput: set contentDescription on MarkdownEditText so TalkBack announces a persistent label even when the field has content (fixes #6390) - TimelineItemReadReceiptView: remove hideFromAccessibility() so the 'Seen by' button is exposed to TalkBack; use semantics (not clearAndSetSemantics) to preserve click action, and add Role.Button (fixes #6393) Co-Authored-By: Claude Sonnet 4.6 --- .../receipt/TimelineItemReadReceiptView.kt | 18 +++++++----------- .../components/markdown/MarkdownTextInput.kt | 2 ++ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt index 037d9ea45d..071594c6ac 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt @@ -25,9 +25,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.hideFromAccessibility +import androidx.compose.ui.semantics.role +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTag import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp @@ -57,18 +58,12 @@ fun TimelineItemReadReceiptView( modifier: Modifier = Modifier, ) { if (state.receipts.isNotEmpty()) { - ReadReceiptsRow( - modifier = modifier.clearAndSetSemantics { - hideFromAccessibility() - } - ) { + ReadReceiptsRow(modifier = modifier) { ReadReceiptsAvatars( receipts = state.receipts, modifier = Modifier .clip(RoundedCornerShape(4.dp)) - .clickable { - onReadReceiptsClick() - } + .clickable { onReadReceiptsClick() } .padding(2.dp) ) } @@ -137,9 +132,10 @@ private fun ReadReceiptsAvatars( val receiptDescription = computeReceiptDescription(receipts) Row( modifier = modifier - .clearAndSetSemantics { + .semantics { testTag = TestTags.messageReadReceipts.value contentDescription = receiptDescription + role = Role.Button }, horizontalArrangement = Arrangement.spacedBy(4.dp - avatarStrokeSize), verticalAlignment = Alignment.CenterVertically, diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/markdown/MarkdownTextInput.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/markdown/MarkdownTextInput.kt index bd6944d603..064ef03106 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/markdown/MarkdownTextInput.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/markdown/MarkdownTextInput.kt @@ -93,6 +93,7 @@ fun MarkdownTextInput( setText(text) setHint(placeholder) setHintTextColor(ColorStateList.valueOf(placeholderColor.toArgb())) + contentDescription = placeholder inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES or InputType.TYPE_TEXT_FLAG_MULTI_LINE or @@ -129,6 +130,7 @@ fun MarkdownTextInput( } }, update = { editText -> + editText.contentDescription = placeholder editText.applyStyleInCompose(richTextEditorStyle) val text = state.text.value() mentionSpanUpdater.updateMentionSpans(text) From 57ed76bd0334ef19c93b14ff5cc1ccddc096b99a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 2 Jul 2026 12:26:49 +0200 Subject: [PATCH 2/2] A11Y: Do not read the `+x` Text. --- .../components/receipt/TimelineItemReadReceiptView.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt index 071594c6ac..3ccf32d422 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt @@ -26,9 +26,9 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.role -import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTag import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp @@ -63,7 +63,7 @@ fun TimelineItemReadReceiptView( receipts = state.receipts, modifier = Modifier .clip(RoundedCornerShape(4.dp)) - .clickable { onReadReceiptsClick() } + .clickable(onClick = onReadReceiptsClick) .padding(2.dp) ) } @@ -132,7 +132,7 @@ private fun ReadReceiptsAvatars( val receiptDescription = computeReceiptDescription(receipts) Row( modifier = modifier - .semantics { + .clearAndSetSemantics { testTag = TestTags.messageReadReceipts.value contentDescription = receiptDescription role = Role.Button