From c3af26d83f5442452e00633918213521df2eaea8 Mon Sep 17 00:00:00 2001 From: David Perez Date: Thu, 10 Oct 2024 16:14:13 -0500 Subject: [PATCH] PM-13286: Update segmented control to match the TopAppBar (#4058) --- .../segment/BitwardenSegmentedButton.kt | 56 ++++++++++++++----- .../color/BitwardenSegmentedButtonColors.kt | 9 +-- .../platform/theme/shape/BitwardenShapes.kt | 1 + .../ui/platform/theme/shape/Shapes.kt | 2 + .../feature/send/addsend/AddSendContent.kt | 51 +++++++---------- .../feature/send/addsend/AddSendScreenTest.kt | 10 ---- 6 files changed, 69 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/segment/BitwardenSegmentedButton.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/segment/BitwardenSegmentedButton.kt index 44bfb3fd3..288779f28 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/segment/BitwardenSegmentedButton.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/segment/BitwardenSegmentedButton.kt @@ -1,14 +1,21 @@ package com.x8bit.bitwarden.ui.platform.components.segment +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.material3.SegmentedButton -import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTag +import androidx.compose.ui.unit.dp import com.x8bit.bitwarden.ui.platform.components.segment.color.bitwardenSegmentedButtonColors +import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme import kotlinx.collections.immutable.ImmutableList /** @@ -22,21 +29,40 @@ fun BitwardenSegmentedButton( options: ImmutableList, modifier: Modifier = Modifier, ) { - SingleChoiceSegmentedButtonRow( - modifier = modifier, + Box( + modifier = modifier + .background(color = BitwardenTheme.colorScheme.background.secondary) + .padding(top = 4.dp, bottom = 8.dp, start = 16.dp, end = 16.dp), ) { - options.forEachIndexed { index, option -> - SegmentedButton( - selected = option.isChecked, - onClick = option.onClick, - colors = bitwardenSegmentedButtonColors(), - shape = SegmentedButtonDefaults.itemShape( - index = index, - count = options.size, - ), - label = { Text(text = option.text) }, - modifier = Modifier.semantics { option.testTag?.let { testTag = it } }, - ) + SingleChoiceSegmentedButtonRow( + modifier = Modifier + .fillMaxWidth() + .background( + color = BitwardenTheme.colorScheme.background.primary, + shape = BitwardenTheme.shapes.segmentedControl, + ) + .padding(horizontal = 4.dp), + space = 0.dp, + ) { + options.forEachIndexed { index, option -> + SegmentedButton( + selected = option.isChecked, + onClick = option.onClick, + colors = bitwardenSegmentedButtonColors(), + shape = BitwardenTheme.shapes.segmentedControl, + border = BorderStroke(width = 0.dp, color = Color.Transparent), + label = { + Text( + text = option.text, + style = BitwardenTheme.typography.labelLarge, + ) + }, + icon = { + // No icon required + }, + modifier = Modifier.semantics { option.testTag?.let { testTag = it } }, + ) + } } } } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/segment/color/BitwardenSegmentedButtonColors.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/segment/color/BitwardenSegmentedButtonColors.kt index 00d1bddfd..491ee9469 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/segment/color/BitwardenSegmentedButtonColors.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/segment/color/BitwardenSegmentedButtonColors.kt @@ -2,6 +2,7 @@ package com.x8bit.bitwarden.ui.platform.components.segment.color import androidx.compose.material3.SegmentedButtonColors import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme /** @@ -11,14 +12,14 @@ import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme fun bitwardenSegmentedButtonColors(): SegmentedButtonColors = SegmentedButtonColors( activeContainerColor = BitwardenTheme.colorScheme.filledButton.backgroundReversed, activeContentColor = BitwardenTheme.colorScheme.filledButton.foregroundReversed, - activeBorderColor = BitwardenTheme.colorScheme.stroke.divider, + activeBorderColor = Color.Transparent, inactiveContainerColor = BitwardenTheme.colorScheme.background.primary, inactiveContentColor = BitwardenTheme.colorScheme.text.secondary, - inactiveBorderColor = BitwardenTheme.colorScheme.stroke.divider, + inactiveBorderColor = Color.Transparent, disabledActiveContainerColor = BitwardenTheme.colorScheme.background.primary, disabledActiveContentColor = BitwardenTheme.colorScheme.filledButton.foregroundDisabled, - disabledActiveBorderColor = BitwardenTheme.colorScheme.stroke.divider, + disabledActiveBorderColor = Color.Transparent, disabledInactiveContainerColor = BitwardenTheme.colorScheme.background.primary, disabledInactiveContentColor = BitwardenTheme.colorScheme.filledButton.foregroundDisabled, - disabledInactiveBorderColor = BitwardenTheme.colorScheme.stroke.divider, + disabledInactiveBorderColor = Color.Transparent, ) diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/theme/shape/BitwardenShapes.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/theme/shape/BitwardenShapes.kt index 52bfbaaba..82fae0385 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/theme/shape/BitwardenShapes.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/theme/shape/BitwardenShapes.kt @@ -16,5 +16,6 @@ data class BitwardenShapes( val dialog: CornerBasedShape, val infoCallout: CornerBasedShape, val menu: CornerBasedShape, + val segmentedControl: CornerBasedShape, val snackbar: CornerBasedShape, ) diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/theme/shape/Shapes.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/theme/shape/Shapes.kt index c7c75ce65..184630993 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/theme/shape/Shapes.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/theme/shape/Shapes.kt @@ -1,5 +1,6 @@ package com.x8bit.bitwarden.ui.platform.theme.shape +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.ui.unit.dp @@ -15,5 +16,6 @@ val bitwardenShapes: BitwardenShapes = BitwardenShapes( dialog = RoundedCornerShape(size = 28.dp), infoCallout = RoundedCornerShape(size = 8.dp), menu = RoundedCornerShape(size = 4.dp), + segmentedControl = CircleShape, snackbar = RoundedCornerShape(size = 8.dp), ) diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/send/addsend/AddSendContent.kt b/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/send/addsend/AddSendContent.kt index 97a9f6b36..52cc2cb96 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/send/addsend/AddSendContent.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/send/addsend/AddSendContent.kt @@ -72,6 +72,26 @@ fun AddSendContent( modifier = modifier .verticalScroll(rememberScrollState()), ) { + if (isAddMode && !isShared) { + BitwardenSegmentedButton( + modifier = Modifier.fillMaxWidth(), + options = persistentListOf( + SegmentedButtonState( + text = stringResource(id = R.string.file), + onClick = addSendHandlers.onFileTypeSelect, + isChecked = state.isFileType, + testTag = "SendFileButton", + ), + SegmentedButtonState( + text = stringResource(id = R.string.text), + onClick = addSendHandlers.onTextTypeSelect, + isChecked = state.isTextType, + testTag = "SendTextButton", + ), + ), + ) + } + if (policyDisablesSend) { BitwardenInfoCalloutCard( text = stringResource(id = R.string.send_disabled_warning), @@ -106,37 +126,6 @@ fun AddSendContent( onValueChange = addSendHandlers.onNamChange, ) - if (isAddMode && !isShared) { - Spacer(modifier = Modifier.height(16.dp)) - BitwardenListHeaderText( - label = stringResource(id = R.string.type), - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), - ) - - Spacer(modifier = Modifier.height(16.dp)) - BitwardenSegmentedButton( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), - options = persistentListOf( - SegmentedButtonState( - text = stringResource(id = R.string.file), - onClick = addSendHandlers.onFileTypeSelect, - isChecked = state.isFileType, - testTag = "SendFileButton", - ), - SegmentedButtonState( - text = stringResource(id = R.string.text), - onClick = addSendHandlers.onTextTypeSelect, - isChecked = state.isTextType, - testTag = "SendTextButton", - ), - ), - ) - } - Spacer(modifier = Modifier.height(8.dp)) when (val type = state.selectedType) { is AddSendState.ViewState.Content.SendType.File -> { diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/send/addsend/AddSendScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/send/addsend/AddSendScreenTest.kt index ad22465bf..36a49e733 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/send/addsend/AddSendScreenTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/send/addsend/AddSendScreenTest.kt @@ -358,9 +358,6 @@ class AddSendScreenTest : BaseComposeTest() { @Test fun `segmented buttons should appear based on state`() { mutableStateFlow.update { it.copy(isShared = true) } - composeTestRule - .onNodeWithText("Type") - .assertDoesNotExist() composeTestRule .onAllNodesWithText("File") .filterToOne(!isEditableText) @@ -376,10 +373,6 @@ class AddSendScreenTest : BaseComposeTest() { addSendType = AddSendType.AddItem, ) } - composeTestRule - .onNodeWithText("Type") - .performScrollTo() - .assertIsDisplayed() composeTestRule .onAllNodesWithText("File") .filterToOne(!isEditableText) @@ -395,9 +388,6 @@ class AddSendScreenTest : BaseComposeTest() { it.copy(addSendType = AddSendType.EditItem(sendItemId = "sendId")) } - composeTestRule - .onNodeWithText("Type") - .assertIsNotDisplayed() composeTestRule .onAllNodesWithText("File") .filterToOne(!isEditableText)