PM-43353, PM-43354: bug: Update accessibility roles for improved TalkBack support (#7378)

This commit is contained in:
David Perez authored and GitHub committed 2026-09-11 14:09:57 +00:00
1 parent 8cc022daf5
commit 65bab9f27a
22 files changed
+119 -75

No files matched your search

@@ -12,6 +12,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.bitwarden.ui.platform.base.util.cardStyle
@@ -51,6 +52,7 @@ fun BitwardenGroupItem(
.cardStyle(
cardStyle = cardStyle,
onClick = onClick,
role = Role.Button,
paddingHorizontal = 16.dp,
),
verticalAlignment = Alignment.CenterVertically,
@@ -18,6 +18,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow
@@ -84,6 +85,7 @@ fun BitwardenListItem(
.cardStyle(
cardStyle = cardStyle,
onClick = onClick,
role = Role.Button,
paddingStart = 16.dp,
paddingEnd = 4.dp,
),
@@ -4,12 +4,13 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
@@ -32,6 +33,10 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.selected
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
@@ -724,16 +729,16 @@ private fun FolderSelectionBottomSheetContent(
Row(
modifier = Modifier
.fillMaxWidth()
.defaultMinSize(minHeight = 60.dp)
.cardStyle(
cardStyle = if (index == 0) {
CardStyle.Top()
} else {
CardStyle.Middle()
},
onClick = {
onOptionSelected(option)
},
),
cardStyle = if (index == 0) CardStyle.Top() else CardStyle.Middle(),
paddingHorizontal = 16.dp,
onClick = { onOptionSelected(option) },
)
.semantics(mergeDescendants = true) {
this.selected = selectedOption == option
this.role = Role.RadioButton
},
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
@@ -741,15 +746,12 @@ private fun FolderSelectionBottomSheetContent(
text = option,
color = BitwardenTheme.colorScheme.text.primary,
style = BitwardenTheme.typography.bodyLarge,
modifier = Modifier
.weight(1f)
.padding(horizontal = 16.dp),
modifier = Modifier.weight(weight = 1f),
)
Spacer(modifier = Modifier.width(width = 16.dp))
BitwardenRadioButton(
isSelected = selectedOption == option,
onClick = {
onOptionSelected(option)
},
onClick = null,
)
}
}
@@ -866,12 +868,16 @@ private fun OwnerSelectionBottomSheetContent(
Row(
modifier = Modifier
.fillMaxWidth()
.defaultMinSize(minHeight = 60.dp)
.cardStyle(
cardStyle = options.toListItemCardStyle(index = index),
onClick = {
onOptionSelected(option)
},
),
paddingHorizontal = 16.dp,
onClick = { onOptionSelected(option) },
)
.semantics(mergeDescendants = true) {
this.selected = selectedOwner == option
this.role = Role.RadioButton
},
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
@@ -879,15 +885,12 @@ private fun OwnerSelectionBottomSheetContent(
text = option.name(),
color = BitwardenTheme.colorScheme.text.primary,
style = BitwardenTheme.typography.bodyLarge,
modifier = Modifier
.weight(weight = 1f)
.padding(horizontal = 16.dp),
modifier = Modifier.weight(weight = 1f),
)
Spacer(modifier = Modifier.width(width = 16.dp))
BitwardenRadioButton(
isSelected = selectedOwner == option,
onClick = {
onOptionSelected(option)
},
onClick = null,
)
}
}
@@ -302,7 +302,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
.onNodeWithText("Minimum numbers")
.assertTextEquals("Minimum numbers", "1")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Minimum numbers"))
.performScrollTo()
.assertIsDisplayed()
@@ -310,7 +310,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
.onNodeWithText("Minimum numbers")
.assertTextEquals("Minimum numbers", "1")
.onChildren()
.filterToOne(hasContentDescription("+"))
.filterToOne(hasContentDescription("Increase Minimum numbers"))
.performScrollTo()
.assertIsDisplayed()
@@ -433,7 +433,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Minimum numbers")
.assertTextEquals("Minimum numbers", "1")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Minimum numbers"))
.performScrollTo()
.performClick()
@@ -454,7 +454,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Minimum numbers")
.assertTextEquals("Minimum numbers", "1")
.onChildren()
.filterToOne(hasContentDescription("+"))
.filterToOne(hasContentDescription("Increase Minimum numbers"))
.performScrollTo()
.performClick()
@@ -479,7 +479,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Minimum numbers")
.assertTextEquals("Minimum numbers", "$initialMinNumbers")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Minimum numbers"))
.performScrollTo()
.performClick()
@@ -499,7 +499,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Minimum numbers")
.assertTextEquals("Minimum numbers", "$initialMinNumbers")
.onChildren()
.filterToOne(hasContentDescription("+"))
.filterToOne(hasContentDescription("Increase Minimum numbers"))
.performScrollTo()
.performClick()
@@ -515,7 +515,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Minimum special")
.assertTextEquals("Minimum special", "1")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Minimum special"))
.performScrollTo()
.performClick()
@@ -536,7 +536,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Minimum special")
.assertTextEquals("Minimum special", "1")
.onChildren()
.filterToOne(hasContentDescription("+"))
.filterToOne(hasContentDescription("Increase Minimum special"))
.performScrollTo()
.performClick()
@@ -562,7 +562,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Minimum special")
.assertTextEquals("Minimum special", "$initialSpecialChars")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Minimum special"))
.performScrollTo()
.performClick()
verify(exactly = 1) { viewModel.trySendAction(GeneratorAction.LifecycleResume) }
@@ -571,7 +571,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
@Suppress("MaxLineLength")
@Test
fun `in Password state, decrementing the minimum special characters above 9 should do nothing`() {
fun `in Password state, incrementing the minimum special characters above 9 should do nothing`() {
val initialSpecialChars = 9
updateState(
DEFAULT_STATE.copy(
@@ -582,7 +582,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Minimum special")
.assertTextEquals("Minimum special", "$initialSpecialChars")
.onChildren()
.filterToOne(hasContentDescription("+"))
.filterToOne(hasContentDescription("Increase Minimum special"))
.performScrollTo()
.performClick()
verify(exactly = 1) { viewModel.trySendAction(GeneratorAction.LifecycleResume) }
@@ -675,7 +675,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Minimum numbers")
.assertTextEquals("Minimum numbers", "5")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Minimum numbers"))
.performScrollTo()
.performClick()
@@ -706,7 +706,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
.onNodeWithText("Minimum numbers")
.assertTextEquals("Minimum numbers", "7")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Minimum numbers"))
.performScrollTo()
.assertIsDisplayed()
}
@@ -726,7 +726,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Minimum special")
.assertTextEquals("Minimum special", "5")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Minimum special"))
.performScrollTo()
.performClick()
@@ -756,7 +756,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Minimum special")
.assertTextEquals("Minimum special", "7")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Minimum special"))
.performScrollTo()
.performClick()
}
@@ -806,7 +806,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
composeTestRule.onNodeWithText("Number of words")
.assertTextEquals("Number of words", "5")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Number of words"))
.performScrollTo()
.performClick()
@@ -836,7 +836,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
.onNodeWithText("Number of words")
.assertTextEquals("Number of words", "$initialNumWords")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Number of words"))
.performScrollTo()
.performClick()
@@ -863,7 +863,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
.onNodeWithText("Number of words")
.assertTextEquals("Number of words", "$initialNumWords")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Number of words"))
.performScrollTo()
.performClick()
verify(exactly = 1) { viewModel.trySendAction(GeneratorAction.LifecycleResume) }
@@ -884,7 +884,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
.onNodeWithText("Number of words")
.assertTextEquals("Number of words", "$initialNumWords")
.onChildren()
.filterToOne(hasContentDescription("+"))
.filterToOne(hasContentDescription("Increase Number of words"))
.performScrollTo()
.performClick()
verify(exactly = 1) { viewModel.trySendAction(GeneratorAction.LifecycleResume) }
@@ -905,7 +905,7 @@ class GeneratorScreenTest : BitwardenComposeTest() {
.onNodeWithText("Number of words")
.assertTextEquals("Number of words", "3")
.onChildren()
.filterToOne(hasContentDescription("+"))
.filterToOne(hasContentDescription("Increase Number of words"))
.performScrollTo()
.performClick()
@@ -758,7 +758,7 @@ class AddEditSendScreenTest : BitwardenComposeTest() {
.performClick()
composeTestRule
.onNodeWithContentDescription("\u2212")
.onNodeWithContentDescription("Decrease Maximum access count")
.performScrollTo()
.performClick()
}
@@ -779,7 +779,7 @@ class AddEditSendScreenTest : BitwardenComposeTest() {
.performClick()
composeTestRule
.onNodeWithContentDescription("\u2212")
.onNodeWithContentDescription("Decrease Maximum access count")
.performScrollTo()
.performClick()
verify { viewModel.trySendAction(AddEditSendAction.MaxAccessCountChange(2)) }
@@ -794,7 +794,7 @@ class AddEditSendScreenTest : BitwardenComposeTest() {
.performClick()
composeTestRule
.onNodeWithContentDescription("+")
.onNodeWithContentDescription("Increase Maximum access count")
.performScrollTo()
.performClick()
verify { viewModel.trySendAction(AddEditSendAction.MaxAccessCountChange(1)) }
@@ -164,7 +164,7 @@ fun ItemListingScreen(
label = BitwardenString.scan_a_qr_code.asText(),
icon = IconData.Local(
iconRes = BitwardenDrawable.ic_camera_small,
contentDescription = BitwardenString.scan_a_qr_code.asText(),
contentDescription = null,
testTag = "ScanQRCodeButton",
),
onFabOptionClick = { launcher.launch(Manifest.permission.CAMERA) },
@@ -173,7 +173,7 @@ fun ItemListingScreen(
label = BitwardenString.enter_key_manually.asText(),
icon = IconData.Local(
iconRes = BitwardenDrawable.ic_lock_encrypted_small,
contentDescription = BitwardenString.enter_key_manually.asText(),
contentDescription = null,
testTag = "EnterSetupKeyButton",
),
onFabOptionClick = {
@@ -16,6 +16,7 @@ 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.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextDirection
@@ -116,6 +117,7 @@ fun VaultVerificationCodeItem(
.cardStyle(
cardStyle = cardStyle,
onClick = onItemClick,
role = Role.Button,
paddingStart = 16.dp,
paddingEnd = 4.dp,
),
@@ -357,7 +357,7 @@ class EditItemScreenTest : AuthenticatorComposeTest() {
composeTestRule
.onNodeWithTextAfterScroll(text = "Number of digits")
.onChildren()
.filterToOne(hasContentDescription("+"))
.filterToOne(hasContentDescription("Increase Number of digits"))
.performClick()
verify(exactly = 1) {
@@ -373,7 +373,7 @@ class EditItemScreenTest : AuthenticatorComposeTest() {
composeTestRule
.onNodeWithTextAfterScroll(text = "Number of digits")
.onChildren()
.filterToOne(hasContentDescription("\u2212"))
.filterToOne(hasContentDescription("Decrease Number of digits"))
.performClick()
verify(exactly = 1) {
@@ -44,6 +44,7 @@ import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
@@ -145,6 +146,7 @@ fun Modifier.nullableClickable(
indicationColor: Color = BitwardenTheme.colorScheme.background.pressed,
enabled: Boolean = true,
onClick: (() -> Unit)?,
role: Role? = null,
): Modifier =
onClick
?.let {
@@ -153,6 +155,7 @@ fun Modifier.nullableClickable(
indication = ripple(color = indicationColor),
onClick = it,
enabled = enabled,
role = role,
)
}
?: this
@@ -394,6 +397,7 @@ private data class StandardHorizontalMarginElement(
fun Modifier.cardStyle(
cardStyle: CardStyle?,
onClick: (() -> Unit)? = null,
role: Role? = null,
clickEnabled: Boolean = true,
paddingHorizontal: Dp = 0.dp,
paddingVertical: Dp = 12.dp,
@@ -403,6 +407,7 @@ fun Modifier.cardStyle(
this.cardStyle(
cardStyle = cardStyle,
onClick = onClick,
role = role,
clickEnabled = clickEnabled,
padding = PaddingValues(
horizontal = paddingHorizontal,
@@ -421,6 +426,7 @@ fun Modifier.cardStyle(
fun Modifier.cardStyle(
cardStyle: CardStyle?,
onClick: (() -> Unit)? = null,
role: Role? = null,
clickEnabled: Boolean = true,
paddingStart: Dp = 0.dp,
paddingTop: Dp = 12.dp,
@@ -432,6 +438,7 @@ fun Modifier.cardStyle(
this.cardStyle(
cardStyle = cardStyle,
onClick = onClick,
role = role,
clickEnabled = clickEnabled,
padding = PaddingValues(
start = paddingStart,
@@ -452,6 +459,7 @@ fun Modifier.cardStyle(
fun Modifier.cardStyle(
cardStyle: CardStyle?,
onClick: (() -> Unit)? = null,
role: Role? = null,
clickEnabled: Boolean = true,
padding: PaddingValues = PaddingValues(horizontal = 0.dp, vertical = 12.dp),
containerColor: Color = BitwardenTheme.colorScheme.background.secondary,
@@ -466,6 +474,7 @@ fun Modifier.cardStyle(
onClick = onClick,
enabled = clickEnabled,
indicationColor = indicationColor,
role = role,
)
.cardPadding(
cardStyle = cardStyle,
@@ -44,6 +44,7 @@ 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.semantics.Role
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
@@ -294,6 +295,7 @@ private fun AccountSummaryItem(
),
onClick = { onSwitchAccountClick(accountSummary) },
onLongClick = { onSwitchAccountLongClick(accountSummary) },
role = Role.Button,
)
.padding(vertical = 8.dp)
.then(modifier),
@@ -422,6 +424,7 @@ private fun AddAccountItem(
color = BitwardenTheme.colorScheme.background.pressed,
),
onClick = onClick,
role = Role.Button,
)
.padding(vertical = 8.dp)
.then(modifier),
@@ -17,8 +17,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
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.testTagsAsResourceId
import androidx.compose.ui.tooling.preview.Preview
@@ -109,7 +111,8 @@ private fun BitwardenDropdownMenuItem(
DropdownMenuItem(
modifier = modifier
.semantics(mergeDescendants = true) {
contentDescription = contentDescriptionText
this.contentDescription = contentDescriptionText
this.role = Role.Button
}
.testTag(tag = "FloatingOptionsItem"),
colors = bitwardenMenuItemColors(
@@ -21,6 +21,9 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.VectorPainter
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.bitwarden.ui.platform.components.card.color.bitwardenCardColors
@@ -45,10 +48,10 @@ fun BitwardenActionCardSmall(
Card(
onClick = onCardClicked,
shape = BitwardenTheme.shapes.actionCard,
modifier = modifier,
colors = colors,
elevation = CardDefaults.elevatedCardElevation(),
border = BorderStroke(width = 1.dp, color = BitwardenTheme.colorScheme.stroke.border),
modifier = modifier.semantics { this.role = Role.Button },
) {
Row(
modifier = Modifier
@@ -10,6 +10,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import com.bitwarden.ui.platform.components.dialog.BitwardenSelectionDialog
import com.bitwarden.ui.platform.theme.BitwardenTheme
@@ -38,6 +39,7 @@ fun BitwardenBasicDialogRow(
color = BitwardenTheme.colorScheme.background.pressed,
),
onClick = onClick,
role = Role.Button,
)
.padding(
vertical = 16.dp,
@@ -1,19 +1,15 @@
package com.bitwarden.ui.platform.components.dialog.row
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.selection.selectable
import androidx.compose.material3.Text
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.selected
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import com.bitwarden.ui.platform.components.radio.BitwardenRadioButton
import com.bitwarden.ui.platform.theme.BitwardenTheme
@@ -37,16 +33,11 @@ fun BitwardenSelectionRow(
modifier = modifier
.fillMaxWidth()
.testTag("AlertRadioButtonOption")
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = ripple(
color = BitwardenTheme.colorScheme.background.pressed,
),
.selectable(
selected = isSelected,
onClick = onClick,
)
.semantics(mergeDescendants = true) {
selected = isSelected
},
role = Role.RadioButton,
),
verticalAlignment = Alignment.CenterVertically,
) {
BitwardenRadioButton(
@@ -389,7 +389,10 @@ fun BitwardenTextField(
visualTransformation = visualTransformation,
modifier = Modifier
.nullableTestTag(tag = textFieldTestTag)
.menuAnchor(type = ExposedDropdownMenuAnchorType.PrimaryEditable)
.menuAnchor(
type = ExposedDropdownMenuAnchorType.PrimaryEditable,
enabled = false,
)
.fillMaxWidth()
.focusRequester(focusRequester)
.onFocusChanged { focusState ->
@@ -18,6 +18,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
@@ -57,6 +58,7 @@ fun BitwardenExpandingHeader(
},
),
onClick = onClick,
role = Role.Button,
)
.minimumInteractiveComponentSize()
.padding(horizontal = 16.dp)
@@ -13,6 +13,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.bitwarden.ui.platform.base.util.cardStyle
@@ -53,6 +54,7 @@ fun BitwardenPushRow(
.cardStyle(
cardStyle = cardStyle,
onClick = onClick,
role = Role.Button,
paddingStart = leadingIcon?.let { 12.dp } ?: 16.dp,
paddingEnd = 20.dp,
paddingTop = 6.dp,
@@ -16,6 +16,7 @@ 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.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.AnnotatedString
@@ -75,6 +76,7 @@ fun BitwardenTextRow(
cardStyle = cardStyle,
onClick = onClick,
clickEnabled = clickable,
role = Role.Button,
paddingHorizontal = 16.dp,
)
.semantics(mergeDescendants = true) { },
@@ -7,6 +7,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import com.bitwarden.ui.platform.base.util.orNullIfBlank
@@ -15,6 +16,7 @@ import com.bitwarden.ui.platform.components.field.BitwardenTextField
import com.bitwarden.ui.platform.components.field.color.bitwardenTextFieldColors
import com.bitwarden.ui.platform.components.model.CardStyle
import com.bitwarden.ui.platform.resource.BitwardenDrawable
import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.platform.theme.BitwardenTheme
/**
@@ -88,7 +90,7 @@ fun BitwardenStepper(
* @param textFieldReadOnly whether the text field should be read only. The stepper
* increment and decrement buttons function regardless of this value.
*/
@Suppress("CyclomaticComplexMethod")
@Suppress("CyclomaticComplexMethod", "LongMethod")
@Composable
fun BitwardenStepper(
label: String?,
@@ -116,7 +118,10 @@ fun BitwardenStepper(
actions = {
BitwardenFilledIconButton(
vectorIconRes = BitwardenDrawable.ic_minus,
contentDescription = "\u2212",
contentDescription = stringResource(
id = BitwardenString.stepper_decrement_format,
formatArgs = arrayOf(label ?: stringResource(id = BitwardenString.value)),
),
onClick = {
val decrementedValue = ((clampedValue ?: 0) - 1).coerceIn(range)
if (decrementedValue != clampedValue) {
@@ -128,7 +133,10 @@ fun BitwardenStepper(
)
BitwardenFilledIconButton(
vectorIconRes = BitwardenDrawable.ic_plus,
contentDescription = "+",
contentDescription = stringResource(
id = BitwardenString.stepper_increment_format,
formatArgs = arrayOf(label ?: stringResource(id = BitwardenString.value)),
),
onClick = {
val incrementedValue = ((clampedValue ?: 0) + 1).coerceIn(range)
if (incrementedValue != clampedValue) {
@@ -21,6 +21,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.hideFromAccessibility
import androidx.compose.ui.semantics.semantics
@@ -72,6 +73,7 @@ fun BitwardenClickableText(
interactionSource = remember { MutableInteractionSource() },
enabled = isEnabled,
onClick = onClick,
role = Role.Button,
)
.padding(paddingValues = innerPadding)
.semantics(mergeDescendants = true) {
@@ -19,8 +19,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
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.toggleableState
import androidx.compose.ui.state.ToggleableState
@@ -262,8 +264,9 @@ fun BitwardenSwitch(
paddingBottom = 0.dp,
)
.semantics(mergeDescendants = true) {
toggleableState = ToggleableState(isChecked)
this.contentDescription = contentDescription ?: label.text
this.role = Role.Switch
this.toggleableState = ToggleableState(value = isChecked)
},
) {
Row(
+2
View File
@@ -1441,4 +1441,6 @@ Do you want to switch to this account?</string>
<string name="receive_24_7_priority_support">Receive 24/7 priority support</string>
<string name="account_creation_restricted">Account creation restricted</string>
<string name="only_allows_invited_users_to_create_accounts">%1$s only allows invited users to create accounts.</string>
<string name="stepper_decrement_format" comment="Used to announce the value that will be decremented when a button is pressed">Decrease %1$s</string>
<string name="stepper_increment_format" comment="Used to announce the value that will be incremented when a button is pressed">Increase %1$s</string>
</resources>