Announce expanded/collapsed state on the timeline group header (#7226)

* Announce expanded/collapsed state on the timeline group header

GroupHeaderView (the accordion-style header used for grouped state
events in the timeline) uses toggleable() combined with
clearAndSetSemantics { contentDescription = text }. The
clearAndSetSemantics block discards the state information that
toggleable() would otherwise expose, so TalkBack never announces
whether the group is currently expanded or collapsed.

Add an explicit stateDescription (two new a11y_state_expanded /
a11y_state_collapsed strings in temporary.xml) alongside the existing
contentDescription so the expanded/collapsed state is communicated to
assistive technology.

Internal note: this single-file/single-root-cause fix addresses three
separate BITV findings raised in the same accessibility audit against
this component's toggle semantics.

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
Jürgen Wischer
2026-07-20 08:50:51 +02:00
committed by GitHub
parent 4a9fd056eb
commit 3cef8c2796
3 changed files with 10 additions and 2 deletions
@@ -26,9 +26,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
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.stateDescription
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons
@@ -37,6 +39,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Surface
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.ui.strings.CommonStrings
private val CORNER_RADIUS = 8.dp
@@ -52,6 +55,8 @@ fun GroupHeaderView(
val backgroundColor = Color.Transparent
val shape = RoundedCornerShape(CORNER_RADIUS)
val expandedStateDescription = stringResource(CommonStrings.a11y_state_expanded)
val collapsedStateDescription = stringResource(CommonStrings.a11y_state_collapsed)
Box(
modifier = modifier
.fillMaxWidth()
@@ -62,6 +67,7 @@ fun GroupHeaderView(
)
.clearAndSetSemantics {
contentDescription = text
stateDescription = if (isExpanded) expandedStateDescription else collapsedStateDescription
},
contentAlignment = Alignment.Center
) {
@@ -8,6 +8,8 @@
<resources>
<string name="action_mark_as_read">"Mark as read"</string>
<string name="a11y_jump_to_unread_messages">"Jump to first unread message"</string>
<string name="a11y_state_expanded">"Expanded"</string>
<string name="a11y_state_collapsed">"Collapsed"</string>
<string name="screen_local_network_opt_in_title">Allow access to local network</string>
<string name="screen_local_network_opt_in_subtitle">Your homeserver is on your local network. To connect, Element needs permission to reach other devices on this network.</string>
<string name="a11y_active">Active</string>
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:02c4892eaa7d27c867266c428374b64e5915ec50ddcdf8b1d532e1cbc6f56462
size 130436
oid sha256:5823ae9a382421609200d569799505706180b94c6923f315caa81f8767ac58f8
size 131340