From 9c6e7b4464c265b5c5105357d260ebef009df537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Wischer?= Date: Wed, 15 Jul 2026 22:07:33 +0200 Subject: [PATCH] Add Button role to clickable icons and text on login/onboarding screens Several clickable elements on the login and onboarding flows (the account provider list items, the search clear icon, the login clear icon, and the hidden dev-mode version tap) use plain Modifier.clickable without a semantics role. Screen readers announce these as generic elements instead of buttons, so users relying on TalkBack cannot tell they are interactive. Add role = Role.Button to each clickable modifier, and reuse the existing clear-icon content description as onClickLabel where one is available. --- .../accountprovider/AccountProviderOtherView.kt | 3 ++- .../impl/accountprovider/AccountProviderView.kt | 3 ++- .../screens/loginpassword/LoginPasswordView.kt | 14 ++++++++++---- .../impl/screens/onboarding/OnBoardingView.kt | 3 ++- .../SearchAccountProviderView.kt | 14 ++++++++++---- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderOtherView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderOtherView.kt index fd5c7b8019..8b9b22022e 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderOtherView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderOtherView.kt @@ -18,6 +18,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons @@ -40,7 +41,7 @@ fun AccountProviderOtherView( Column( modifier = modifier .fillMaxWidth() - .clickable { onClick() } + .clickable(role = Role.Button) { onClick() } ) { HorizontalDivider() Row( diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderView.kt index 5130bf1ad8..fcf4dac3b1 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderView.kt @@ -19,6 +19,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme @@ -45,7 +46,7 @@ fun AccountProviderView( Column( modifier = modifier .fillMaxWidth() - .clickable { onClick() } + .clickable(role = Role.Button) { onClick() } ) { HorizontalDivider() Column( diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt index feb1d3d53a..06a1641644 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.focus.FocusDirection import androidx.compose.ui.platform.LocalAutofillManager import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentType import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.input.ImeAction @@ -211,10 +212,15 @@ private fun LoginForm( singleLine = true, trailingIcon = if (loginFieldState.isNotEmpty()) { { - Box(Modifier.clickable { - loginFieldState = "" - eventSink(LoginPasswordEvents.SetLogin("")) - }) { + Box( + Modifier.clickable( + onClickLabel = stringResource(CommonStrings.action_clear), + role = Role.Button, + ) { + loginFieldState = "" + eventSink(LoginPasswordEvents.SetLogin("")) + } + ) { Icon( imageVector = CompoundIcons.Close(), contentDescription = stringResource(CommonStrings.action_clear), diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingView.kt index be86bbee9c..bf96b2dbe0 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingView.kt @@ -27,6 +27,7 @@ import androidx.compose.ui.BiasAlignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.Role import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp @@ -336,7 +337,7 @@ private fun OnBoardingButtons( } else { Text( modifier = Modifier - .clickable { + .clickable(role = Role.Button) { state.eventSink(OnBoardingEvents.OnVersionClick) } .padding(16.dp), diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt index 55c2c28f5b..8335dde112 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt @@ -34,6 +34,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusDirection import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.Role import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.tooling.preview.PreviewParameter @@ -125,10 +126,15 @@ fun SearchAccountProviderView( singleLine = true, trailingIcon = if (userInputState.isNotEmpty()) { { - Box(Modifier.clickable { - userInputState = "" - eventSink(SearchAccountProviderEvents.UserInput("")) - }) { + Box( + Modifier.clickable( + onClickLabel = stringResource(CommonStrings.action_clear), + role = Role.Button, + ) { + userInputState = "" + eventSink(SearchAccountProviderEvents.UserInput("")) + } + ) { Icon( imageVector = CompoundIcons.Close(), contentDescription = stringResource(CommonStrings.action_clear)