Accessibility changes in composer for talkback

ET-5554
This commit is contained in:
Seren
2025-12-05 15:48:26 +01:00
committed by Niccolò Forlini
parent b50bd772a2
commit c7c55a2093
7 changed files with 41 additions and 30 deletions
@@ -43,7 +43,6 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusEvent
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.viewinterop.AndroidView
import ch.protonmail.android.mailcommon.presentation.ConsumableLaunchedEffect
import ch.protonmail.android.mailcommon.presentation.Effect
@@ -78,7 +77,6 @@ fun EditableMessageBodyWebView(
) {
val isSystemInDarkTheme = isSystemInDarkTheme()
val localDensity = LocalDensity.current
var webView by remember { mutableStateOf<WebView?>(null) }
var currentCursorPosition by remember { mutableStateOf(CursorPosition(0f, 0f)) }
@@ -25,8 +25,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material3.Icon
@@ -37,9 +35,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import ch.protonmail.android.design.compose.theme.ProtonDimens
import ch.protonmail.android.design.compose.theme.ProtonTheme
import ch.protonmail.android.design.compose.theme.bodyMediumNorm
@@ -73,23 +70,24 @@ internal fun SenderEmailWithSelector(
Spacer(modifier = Modifier.size(ProtonDimens.Spacing.Standard))
BasicTextField(
value = TextFieldValue(selectedEmail),
onValueChange = { },
Text(
text = selectedEmail,
modifier = Modifier
.testTag(SenderEmailWithSelectorTestTags.TextField)
.align(Alignment.CenterVertically)
.weight(1f),
readOnly = true,
textStyle = ProtonTheme.typography.bodyMediumNorm,
singleLine = true,
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Next,
keyboardType = KeyboardType.Email
)
style = ProtonTheme.typography.bodyMediumNorm
)
ChangeSenderButton(Modifier.align(Alignment.CenterVertically), onChangeSender)
val composerSenderAddressContentDescription = stringResource(R.string.composer_sender_address_description)
ChangeSenderButton(
Modifier
.semantics {
contentDescription = composerSenderAddressContentDescription
}
.align(Alignment.CenterVertically),
onChangeSender
)
}
}
@@ -51,6 +51,7 @@ import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.platform.toClipEntry
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import ch.protonmail.android.design.compose.component.ProtonModalBottomSheetLayout
@@ -59,6 +60,7 @@ import ch.protonmail.android.design.compose.theme.ProtonTheme
import ch.protonmail.android.mailcommon.presentation.ConsumableLaunchedEffect
import ch.protonmail.android.mailcommon.presentation.ConsumableTextEffect
import ch.protonmail.android.mailcommon.presentation.model.string
import ch.protonmail.android.mailcomposer.presentation.R
import ch.protonmail.android.mailcomposer.presentation.model.ContactSuggestionUiModel
import ch.protonmail.android.mailcomposer.presentation.ui.RecipientChipActionsBottomSheetContent
import ch.protonmail.android.mailcomposer.presentation.ui.suggestions.ContactSuggestionState
@@ -247,6 +249,7 @@ private fun ChipsListContent(
style = ProtonTheme.typography.bodyMedium
)
val contentDesc = stringResource(R.string.composer_enter_recipient_content_description)
ChipsListTextField(
modifier = Modifier
.fillMaxWidth()
@@ -262,7 +265,8 @@ private fun ChipsListContent(
state = listState,
focusRequester = focusRequester,
nextFocusRequester = nextFocusRequester,
actions = chipsListActions
actions = chipsListActions,
enterTextForChipContentDescription = contentDesc
)
chevronIconContent()
@@ -172,4 +172,6 @@
<string name="composer_error_send_draft_too_many_attachments">Unable to send draft - Attachment limit reached</string>
<string name="composer_error_send_draft_attachments_crypto_error">Unable to send draft - Attachment encryption failed.</string>
<string name="composer_expiration_time_learn_more">Learn more</string>
<string name="composer_enter_recipient_content_description">Enter a recipient</string>
<string name="composer_sender_address_description">Choose Sender Address</string>
</resources>
@@ -26,7 +26,7 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.widthIn
import androidx.compose.material3.InputChip
import androidx.compose.material3.AssistChip
import androidx.compose.material3.SuggestionChip
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -38,6 +38,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.scale
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
@@ -47,8 +49,8 @@ import ch.protonmail.android.design.compose.theme.ProtonDimens
import ch.protonmail.android.design.compose.theme.ProtonTheme
import ch.protonmail.android.uicomponents.chips.icons.LeadingChipIcon
import ch.protonmail.android.uicomponents.chips.item.ChipItem
import ch.protonmail.android.uicomponents.chips.item.assistChipColor
import ch.protonmail.android.uicomponents.chips.item.inputChipBorder
import ch.protonmail.android.uicomponents.chips.item.inputChipColor
import ch.protonmail.android.uicomponents.chips.item.suggestionChipColor
import ch.protonmail.android.uicomponents.chips.item.suggestionsTextStyle
import ch.protonmail.android.uicomponents.chips.item.textStyle
@@ -64,16 +66,18 @@ internal fun FocusedChipsList(
chipItems.forEachIndexed { index, chipItem ->
val scale by remember { mutableStateOf(Animatable(0F)) }
val alpha by remember { mutableStateOf(Animatable(0F)) }
InputChip(
AssistChip(
modifier = Modifier
.testTag("${ChipsTestTags.InputChip}$index")
.semantics { isValidField = chipItem !is ChipItem.Invalid }
.semantics {
isValidField = chipItem !is ChipItem.Invalid
role = Role.Button
}
.padding(horizontal = 4.dp)
.thenIf(animateChipsCreation) {
scale(scale.value)
alpha(alpha.value)
},
selected = false,
onClick = { onClickItem(index) },
label = {
Text(
@@ -87,7 +91,7 @@ internal fun FocusedChipsList(
},
shape = ProtonTheme.shapes.huge,
colors = inputChipColor(),
colors = assistChipColor(),
border = inputChipBorder(chipItem),
leadingIcon = { LeadingChipIcon(chipItem) }
@@ -35,6 +35,8 @@ import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
@@ -57,7 +59,8 @@ fun ChipsListTextField(
cursorColor: Color = ProtonTheme.colors.iconAccent,
textStyle: TextStyle = ProtonTheme.typography.bodyMediumNorm,
animateChipsCreation: Boolean = false,
actions: ChipsListTextField.Actions
actions: ChipsListTextField.Actions,
enterTextForChipContentDescription: String
) {
val focusManager = LocalFocusManager.current
val localDensity = LocalDensity.current
@@ -105,6 +108,9 @@ fun ChipsListTextField(
.fillMaxWidth()
.weight(1f)
.align(Alignment.CenterVertically)
.semantics {
contentDescription = enterTextForChipContentDescription
}
.testTag(ChipsTestTags.BasicTextField)
.focusRequester(focusRequester)
.focusProperties { next = nextFocusRequester }
@@ -19,9 +19,8 @@
package ch.protonmail.android.uicomponents.chips.item
import androidx.compose.foundation.BorderStroke
import androidx.compose.material3.AssistChipDefaults
import androidx.compose.material3.ChipColors
import androidx.compose.material3.InputChipDefaults
import androidx.compose.material3.SelectableChipColors
import androidx.compose.material3.SuggestionChipDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.TextStyle
@@ -42,8 +41,8 @@ internal fun ChipItem.textStyle(): TextStyle = when (this) {
internal fun ChipItem.suggestionsTextStyle() = ProtonTheme.typography.bodyMediumNorm
@Composable
internal fun inputChipColor(): SelectableChipColors {
return InputChipDefaults.inputChipColors()
internal fun assistChipColor(): ChipColors {
return AssistChipDefaults.assistChipColors()
.copy(containerColor = ProtonTheme.colors.backgroundNorm)
}