End subtext and end icon support to BitwardenGroupItem (#6349)

This commit is contained in:
David Perez
2026-01-13 09:27:32 -06:00
committed by GitHub
parent d12c546c9a
commit 66900f71df
4 changed files with 81 additions and 41 deletions

View File

@@ -1,21 +1,23 @@
package com.x8bit.bitwarden.ui.platform.components.listitem
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.bitwarden.ui.platform.base.util.cardStyle
import com.bitwarden.ui.platform.base.util.nullableTestTag
import com.bitwarden.ui.platform.components.icon.BitwardenIcon
import com.bitwarden.ui.platform.components.icon.model.IconData
import com.bitwarden.ui.platform.components.model.CardStyle
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.bitwarden.ui.platform.resource.BitwardenDrawable
import com.bitwarden.ui.platform.theme.BitwardenTheme
@@ -25,23 +27,25 @@ import com.bitwarden.ui.platform.theme.BitwardenTheme
*
* @param label The main text label to be displayed in the group item.
* @param supportingLabel The secondary supporting text label to be displayed beside the label.
* @param startIcon The [Painter] object used to draw the icon at the start of the group item.
* @param startIcon The [IconData] object used to draw the icon at the start of the group item.
* @param onClick A lambda function that is invoked when the group is clicked.
* @param cardStyle Indicates the type of card style to be applied.
* @param modifier The [Modifier] to be applied to the [Row] composable that holds the list item.
* @param subLabel The secondary text label to be displayed in the group item.
* @param endIcon The [IconData] object used to draw the icon at the end of the group item.
* @param showDivider Indicates whether the divider should be shown or not.
* @param startIconTestTag The optional test tag for the [startIcon].
*/
@Composable
fun BitwardenGroupItem(
label: String,
supportingLabel: String,
startIcon: Painter,
startIcon: IconData.Local,
onClick: () -> Unit,
cardStyle: CardStyle?,
modifier: Modifier = Modifier,
subLabel: String? = null,
endIcon: IconData.Local? = null,
showDivider: Boolean = true,
startIconTestTag: String? = null,
) {
Row(
modifier = modifier
@@ -54,28 +58,46 @@ fun BitwardenGroupItem(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp),
) {
Icon(
painter = startIcon,
contentDescription = null,
BitwardenIcon(
iconData = startIcon,
tint = BitwardenTheme.colorScheme.icon.primary,
modifier = Modifier
.defaultMinSize(minHeight = 36.dp)
.nullableTestTag(tag = startIconTestTag)
.size(size = 24.dp),
)
Text(
text = label,
style = BitwardenTheme.typography.bodyLarge,
color = BitwardenTheme.colorScheme.text.primary,
modifier = Modifier.weight(1f),
)
Column(modifier = Modifier.weight(weight = 1f)) {
Text(
text = label,
style = BitwardenTheme.typography.bodyLarge,
color = BitwardenTheme.colorScheme.text.primary,
modifier = Modifier.fillMaxWidth(),
)
subLabel?.let {
Spacer(modifier = Modifier.height(height = 2.dp))
Text(
text = it,
style = BitwardenTheme.typography.bodyMedium,
color = BitwardenTheme.colorScheme.text.secondary,
modifier = Modifier.fillMaxWidth(),
)
}
}
Text(
text = supportingLabel,
style = BitwardenTheme.typography.labelSmall,
color = BitwardenTheme.colorScheme.text.primary,
)
endIcon?.let {
BitwardenIcon(
iconData = it,
tint = BitwardenTheme.colorScheme.icon.primary,
modifier = Modifier
.defaultMinSize(minHeight = 36.dp)
.size(size = 24.dp),
)
}
}
}
@@ -86,9 +108,18 @@ private fun BitwardenGroupItem_preview() {
BitwardenGroupItem(
label = "Sample Label",
supportingLabel = "5",
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_file_text),
startIconTestTag = "Test Tag",
startIcon = IconData.Local(
iconRes = BitwardenDrawable.ic_file_text,
contentDescription = null,
testTag = "Test Tag 1",
),
endIcon = IconData.Local(
iconRes = BitwardenDrawable.ic_locked,
contentDescription = null,
testTag = "Test Tag 2",
),
onClick = {},
subLabel = "Sample Subtext",
cardStyle = CardStyle.Full,
)
}

View File

@@ -18,7 +18,6 @@ import com.bitwarden.ui.platform.components.card.BitwardenInfoCalloutCard
import com.bitwarden.ui.platform.components.header.BitwardenListHeaderText
import com.bitwarden.ui.platform.components.icon.model.IconData
import com.bitwarden.ui.platform.components.model.CardStyle
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.bitwarden.ui.platform.resource.BitwardenDrawable
import com.bitwarden.ui.platform.resource.BitwardenString
import com.x8bit.bitwarden.ui.platform.components.listitem.BitwardenGroupItem
@@ -70,7 +69,7 @@ fun SendContent(
BitwardenGroupItem(
label = stringResource(id = BitwardenString.type_text),
supportingLabel = state.textTypeCount.toString(),
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_file_text),
startIcon = IconData.Local(iconRes = BitwardenDrawable.ic_file_text),
onClick = sendHandlers.onTextTypeClick,
cardStyle = CardStyle.Top(dividerPadding = 56.dp),
modifier = Modifier
@@ -84,7 +83,7 @@ fun SendContent(
BitwardenGroupItem(
label = stringResource(id = BitwardenString.type_file),
supportingLabel = state.fileTypeCount.toString(),
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_file),
startIcon = IconData.Local(iconRes = BitwardenDrawable.ic_file),
onClick = sendHandlers.onFileTypeClick,
cardStyle = CardStyle.Bottom,
modifier = Modifier

View File

@@ -21,7 +21,7 @@ import com.bitwarden.ui.platform.base.util.toListItemCardStyle
import com.bitwarden.ui.platform.components.card.BitwardenInfoCalloutCard
import com.bitwarden.ui.platform.components.dialog.BitwardenTwoButtonDialog
import com.bitwarden.ui.platform.components.header.BitwardenListHeaderText
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.bitwarden.ui.platform.components.icon.model.IconData
import com.bitwarden.ui.platform.resource.BitwardenDrawable
import com.bitwarden.ui.platform.resource.BitwardenString
import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenMasterPasswordDialog
@@ -142,7 +142,7 @@ fun VaultItemListingContent(
itemsIndexed(state.displayCollectionList) { index, collection ->
BitwardenGroupItem(
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_collections),
startIcon = IconData.Local(iconRes = BitwardenDrawable.ic_collections),
label = collection.name,
supportingLabel = collection.count.toString(),
onClick = { collectionClick(collection.id) },
@@ -173,7 +173,7 @@ fun VaultItemListingContent(
itemsIndexed(state.displayFolderList) { index, folder ->
BitwardenGroupItem(
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_folder),
startIcon = IconData.Local(iconRes = BitwardenDrawable.ic_folder),
label = folder.name,
supportingLabel = folder.count.toString(),
onClick = { folderClick(folder.id) },

View File

@@ -19,8 +19,8 @@ import androidx.compose.ui.unit.dp
import com.bitwarden.ui.platform.base.util.standardHorizontalMargin
import com.bitwarden.ui.platform.base.util.toListItemCardStyle
import com.bitwarden.ui.platform.components.header.BitwardenListHeaderText
import com.bitwarden.ui.platform.components.icon.model.IconData
import com.bitwarden.ui.platform.components.model.CardStyle
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.bitwarden.ui.platform.resource.BitwardenDrawable
import com.bitwarden.ui.platform.resource.BitwardenString
import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenMasterPasswordDialog
@@ -89,7 +89,7 @@ fun VaultContent(
item {
BitwardenGroupItem(
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_clock),
startIcon = IconData.Local(iconRes = BitwardenDrawable.ic_clock),
label = stringResource(id = BitwardenString.verification_codes),
supportingLabel = state.totpItemsCount.toString(),
onClick = vaultHandlers.verificationCodesClick,
@@ -169,8 +169,10 @@ fun VaultContent(
item {
BitwardenGroupItem(
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_globe),
startIconTestTag = "LoginCipherIcon",
startIcon = IconData.Local(
iconRes = BitwardenDrawable.ic_globe,
testTag = "LoginCipherIcon",
),
label = stringResource(id = BitwardenString.type_login),
supportingLabel = state.loginItemsCount.toString(),
onClick = vaultHandlers.loginGroupClick,
@@ -186,8 +188,10 @@ fun VaultContent(
if (state.showCardGroup) {
item {
BitwardenGroupItem(
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_payment_card),
startIconTestTag = "CardCipherIcon",
startIcon = IconData.Local(
iconRes = BitwardenDrawable.ic_payment_card,
testTag = "CardCipherIcon",
),
label = stringResource(id = BitwardenString.type_card),
supportingLabel = state.cardItemsCount.toString(),
onClick = vaultHandlers.cardGroupClick,
@@ -203,8 +207,10 @@ fun VaultContent(
item {
BitwardenGroupItem(
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_id_card),
startIconTestTag = "IdentityCipherIcon",
startIcon = IconData.Local(
iconRes = BitwardenDrawable.ic_id_card,
testTag = "IdentityCipherIcon",
),
label = stringResource(id = BitwardenString.type_identity),
supportingLabel = state.identityItemsCount.toString(),
onClick = vaultHandlers.identityGroupClick,
@@ -219,8 +225,10 @@ fun VaultContent(
item {
BitwardenGroupItem(
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_note),
startIconTestTag = "SecureNoteCipherIcon",
startIcon = IconData.Local(
iconRes = BitwardenDrawable.ic_note,
testTag = "SecureNoteCipherIcon",
),
label = stringResource(id = BitwardenString.type_secure_note),
supportingLabel = state.secureNoteItemsCount.toString(),
onClick = vaultHandlers.secureNoteGroupClick,
@@ -235,8 +243,10 @@ fun VaultContent(
item {
BitwardenGroupItem(
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_ssh_key),
startIconTestTag = "SshKeyCipherIcon",
startIcon = IconData.Local(
iconRes = BitwardenDrawable.ic_ssh_key,
testTag = "SshKeyCipherIcon",
),
label = stringResource(id = BitwardenString.type_ssh_key),
supportingLabel = state.sshKeyItemsCount.toString(),
onClick = vaultHandlers.sshKeyGroupClick,
@@ -268,7 +278,7 @@ fun VaultContent(
itemsIndexed(state.folderItems) { index, folder ->
BitwardenGroupItem(
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_folder),
startIcon = IconData.Local(iconRes = BitwardenDrawable.ic_folder),
label = folder.name(),
supportingLabel = folder.itemCount.toString(),
onClick = { vaultHandlers.folderClick(folder) },
@@ -352,7 +362,7 @@ fun VaultContent(
itemsIndexed(state.collectionItems) { index, collection ->
BitwardenGroupItem(
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_collections),
startIcon = IconData.Local(iconRes = BitwardenDrawable.ic_collections),
label = collection.name,
supportingLabel = collection.itemCount.toString(),
onClick = { vaultHandlers.collectionClick(collection) },
@@ -385,7 +395,7 @@ fun VaultContent(
item {
BitwardenGroupItem(
startIcon = rememberVectorPainter(id = BitwardenDrawable.ic_trash),
startIcon = IconData.Local(iconRes = BitwardenDrawable.ic_trash),
label = stringResource(id = BitwardenString.trash),
supportingLabel = state.trashItemsCount.toString(),
onClick = vaultHandlers.trashClick,