1
0
Fork 0
mirror of https://github.com/bitwarden/android.git synced 2025-02-22 08:39:01 +03:00
This commit is contained in:
Dave Severns 2025-01-02 11:54:46 -05:00
parent a35ec8cf3c
commit 0cdcfab32a

View file

@ -2,14 +2,18 @@ package com.x8bit.bitwarden.ui.platform.components.content
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.Switch
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -19,8 +23,11 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
@ -28,6 +35,7 @@ import androidx.compose.ui.unit.dp
import com.x8bit.bitwarden.R import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.base.util.bottomDivider import com.x8bit.bitwarden.ui.platform.base.util.bottomDivider
import com.x8bit.bitwarden.ui.platform.components.model.ContentBlockData import com.x8bit.bitwarden.ui.platform.components.model.ContentBlockData
import com.x8bit.bitwarden.ui.platform.components.toggle.color.bitwardenSwitchColors
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
@ -43,6 +51,9 @@ fun BitwardenContentBlock(
subtitleTextStyle: TextStyle = BitwardenTheme.typography.bodyMedium, subtitleTextStyle: TextStyle = BitwardenTheme.typography.bodyMedium,
backgroundColor: Color = BitwardenTheme.colorScheme.background.secondary, backgroundColor: Color = BitwardenTheme.colorScheme.background.secondary,
showDivider: Boolean = true, showDivider: Boolean = true,
shape: ContentBlockShape = ContentBlockShape.Default,
onContentClick: (() -> Unit)? = null,
trailingContent: (@Composable () -> Unit)? = null,
) { ) {
BitwardenContentBlock( BitwardenContentBlock(
headerText = data.headerText, headerText = data.headerText,
@ -53,6 +64,9 @@ fun BitwardenContentBlock(
iconVectorResource = data.iconVectorResource, iconVectorResource = data.iconVectorResource,
backgroundColor = backgroundColor, backgroundColor = backgroundColor,
showDivider = showDivider, showDivider = showDivider,
shape = shape,
onContentClick = onContentClick,
trailingContent = trailingContent,
) )
} }
@ -70,6 +84,9 @@ private fun BitwardenContentBlock(
showDivider: Boolean = true, showDivider: Boolean = true,
@DrawableRes iconVectorResource: Int? = null, @DrawableRes iconVectorResource: Int? = null,
backgroundColor: Color = BitwardenTheme.colorScheme.background.secondary, backgroundColor: Color = BitwardenTheme.colorScheme.background.secondary,
shape: ContentBlockShape = ContentBlockShape.Default,
onContentClick: (() -> Unit)? = null,
trailingContent: (@Composable () -> Unit)? = null,
) { ) {
var dividerStartPadding by remember { mutableStateOf(0.dp) } var dividerStartPadding by remember { mutableStateOf(0.dp) }
val localDensity = LocalDensity.current val localDensity = LocalDensity.current
@ -77,9 +94,15 @@ private fun BitwardenContentBlock(
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.background(backgroundColor) .background(
color = backgroundColor,
shape = shape(),
)
.clickable(enabled = onContentClick != null) {
onContentClick?.invoke()
}
.bottomDivider( .bottomDivider(
enabled = showDivider, enabled = showDivider && (shape !is ContentBlockShape.Bottom),
paddingStart = dividerStartPadding, paddingStart = dividerStartPadding,
) )
.then(modifier), .then(modifier),
@ -107,7 +130,7 @@ private fun BitwardenContentBlock(
?: Spacer(Modifier.width(16.dp)) ?: Spacer(Modifier.width(16.dp))
} }
Column(modifier = Modifier.weight(weight = 1f, fill = false)) { Column(modifier = Modifier.weight(weight = 1f, fill = true)) {
Spacer(Modifier.height(12.dp)) Spacer(Modifier.height(12.dp))
Text( Text(
text = headerText, text = headerText,
@ -123,16 +146,68 @@ private fun BitwardenContentBlock(
} }
Spacer(Modifier.height(12.dp)) Spacer(Modifier.height(12.dp))
} }
trailingContent?.let {
Spacer(Modifier.width(16.dp))
it()
}
Spacer(Modifier.width(16.dp)) Spacer(Modifier.width(16.dp))
} }
} }
/**
* Sealed interface representing the shape of a [BitwardenContentBlock] background.
*/
sealed interface ContentBlockShape {
/**
* Returns the [Shape] defined by this [ContentBlockShape].
*/
operator fun invoke(): Shape
/**
* The default [ContentBlockShape] implementation. A rectangle shape.
*/
data object Default : ContentBlockShape {
override fun invoke(): Shape = RectangleShape
}
/**
* The shape of a [BitwardenContentBlock] with rounded corners at the top.
*/
data object Top : ContentBlockShape {
override fun invoke(): Shape = RoundedCornerShape(
topStart = 8.dp,
topEnd = 8.dp,
)
}
/**
* The shape of a [BitwardenContentBlock] with rounded corners at the bottom.
*/
data object Bottom : ContentBlockShape {
override fun invoke(): Shape = RoundedCornerShape(
bottomStart = 8.dp,
bottomEnd = 8.dp,
)
}
/**
* The shape of a [BitwardenContentBlock] with rounded corners on all sides.
*/
data object Rounded : ContentBlockShape {
override fun invoke(): Shape = RoundedCornerShape(
size = 8.dp,
)
}
}
@Preview @Preview
@Composable @Composable
private fun BitwardenContentBlock_preview() { private fun BitwardenContentBlock_preview() {
BitwardenTheme { BitwardenTheme {
Column( Column(
modifier = Modifier.background(color = BitwardenTheme.colorScheme.background.primary), modifier = Modifier
.background(color = BitwardenTheme.colorScheme.background.primary)
.padding(16.dp),
) { ) {
BitwardenContentBlock( BitwardenContentBlock(
data = ContentBlockData( data = ContentBlockData(
@ -140,6 +215,7 @@ private fun BitwardenContentBlock_preview() {
subtitleText = "Subtitle", subtitleText = "Subtitle",
iconVectorResource = null, iconVectorResource = null,
), ),
shape = ContentBlockShape.Top,
) )
BitwardenContentBlock( BitwardenContentBlock(
data = ContentBlockData( data = ContentBlockData(
@ -155,6 +231,17 @@ private fun BitwardenContentBlock_preview() {
iconVectorResource = null, iconVectorResource = null,
), ),
showDivider = false, showDivider = false,
trailingContent = {
Switch(
modifier = Modifier
.height(height = 56.dp)
.testTag(tag = "SwitchToggle"),
enabled = false,
checked = false,
onCheckedChange = null,
colors = bitwardenSwitchColors(),
)
},
) )
BitwardenContentBlock( BitwardenContentBlock(
data = ContentBlockData( data = ContentBlockData(
@ -162,6 +249,7 @@ private fun BitwardenContentBlock_preview() {
subtitleText = "Subtitle", subtitleText = "Subtitle",
iconVectorResource = null, iconVectorResource = null,
), ),
shape = ContentBlockShape.Bottom,
) )
} }
} }