Loading packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/card/CardPageProvider.kt +9 −11 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import androidx.compose.material.icons.outlined.Error import androidx.compose.material.icons.outlined.PowerOff import androidx.compose.material.icons.outlined.Shield import androidx.compose.material.icons.outlined.WarningAmber import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue Loading Loading @@ -78,24 +79,19 @@ object CardPageProvider : SettingsPageProvider { imageVector = Icons.Outlined.WarningAmber, buttons = listOf( CardButton(text = "Action") {}, CardButton(text = "Action", isMain = true) {}, ) ), tintColor = MaterialTheme.colorScheme.error, containerColor = MaterialTheme.colorScheme.errorContainer, ) ) } @Composable private fun SettingsCardWithoutIcon() { var isVisible by rememberSaveable { mutableStateOf(true) } SettingsCard( CardModel( title = stringResource(R.string.sample_title), text = stringResource(R.string.sample_text), isVisible = { isVisible }, onDismiss = { isVisible = false }, buttons = listOf( CardButton(text = "Action") {}, ), ) ) } Loading @@ -104,6 +100,7 @@ object CardPageProvider : SettingsPageProvider { fun SampleSettingsCollapsibleCard() { val context = LocalContext.current var isVisible0 by rememberSaveable { mutableStateOf(true) } var isVisible1 by rememberSaveable { mutableStateOf(true) } val cards = remember { mutableStateListOf( CardModel( Loading @@ -114,16 +111,17 @@ object CardPageProvider : SettingsPageProvider { onDismiss = { isVisible0 = false }, buttons = listOf( CardButton(text = "Action") {}, ) ), ), CardModel( title = context.getString(R.string.sample_title), text = context.getString(R.string.sample_text), imageVector = Icons.Outlined.Shield, isVisible = { isVisible1 }, onDismiss = { isVisible1 = false }, buttons = listOf( CardButton(text = "Action") {}, CardButton(text = "Main action", isMain = true) {}, ) ), ) ) } Loading packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt +0 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ object SettingsDimension { val itemPaddingAround = 8.dp val itemDividerHeight = 32.dp val iconSmall = 16.dp val iconLarge = 48.dp /** The size when app icon is displayed in list. */ Loading packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/CardModel.kt +7 −1 Original line number Diff line number Diff line Loading @@ -16,11 +16,11 @@ package com.android.settingslib.spa.widget.card import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector data class CardButton( val text: String, val isMain: Boolean = false, val onClick: () -> Unit, ) Loading @@ -38,4 +38,10 @@ data class CardModel( val onDismiss: (() -> Unit)? = null, val buttons: List<CardButton> = emptyList(), /** If specified, this color will be used to tint the icon and the buttons. */ val tintColor: Color = Color.Unspecified, /** If specified, this color will be used to tint the icon and the buttons. */ val containerColor: Color = Color.Unspecified, ) packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCard.kt +31 −40 Original line number Diff line number Diff line Loading @@ -23,26 +23,26 @@ import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Close import androidx.compose.material.icons.outlined.WarningAmber import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.takeOrElse import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp Loading Loading @@ -72,11 +72,14 @@ fun SettingsCard(content: @Composable ColumnScope.() -> Unit) { } @Composable fun SettingsCardContent(content: @Composable ColumnScope.() -> Unit) { fun SettingsCardContent( containerColor: Color = Color.Unspecified, content: @Composable ColumnScope.() -> Unit, ) { Card( shape = CornerExtraSmall, colors = CardDefaults.cardColors( containerColor = SettingsTheme.colorScheme.surface, containerColor = containerColor.takeOrElse { SettingsTheme.colorScheme.surface }, ), modifier = Modifier .fillMaxWidth() Loading @@ -95,37 +98,43 @@ fun SettingsCard(model: CardModel) { @Composable internal fun SettingsCardImpl(model: CardModel) { AnimatedVisibility(visible = model.isVisible()) { SettingsCardContent { SettingsCardContent(containerColor = model.containerColor) { Column( modifier = Modifier.padding(SettingsDimension.itemPaddingStart), modifier = Modifier.padding( horizontal = SettingsDimension.dialogItemPaddingHorizontal, vertical = SettingsDimension.itemPaddingAround, ), verticalArrangement = Arrangement.spacedBy(SettingsDimension.itemPaddingAround) ) { CardHeader(model.imageVector, model.onDismiss) CardHeader(model.imageVector, model.tintColor, model.onDismiss) SettingsTitle(model.title) SettingsBody(model.text) Buttons(model.buttons) Buttons(model.buttons, model.tintColor) } } } } @Composable fun CardHeader(imageVector: ImageVector?, onDismiss: (() -> Unit)? = null) { fun CardHeader(imageVector: ImageVector?, iconColor: Color, onDismiss: (() -> Unit)? = null) { if (imageVector != null || onDismiss != null) { Spacer(Modifier.height(SettingsDimension.buttonPaddingVertical)) } Row(Modifier.fillMaxWidth()) { CardIcon(imageVector) CardIcon(imageVector, iconColor) Spacer(modifier = Modifier.weight(1f)) DismissButton(onDismiss) } } @Composable private fun CardIcon(imageVector: ImageVector?) { private fun CardIcon(imageVector: ImageVector?, color: Color) { if (imageVector != null) { Icon( imageVector = imageVector, contentDescription = null, modifier = Modifier.size(SettingsDimension.itemIconSize), tint = MaterialTheme.colorScheme.primary, tint = color.takeOrElse { MaterialTheme.colorScheme.primary }, ) } } Loading @@ -146,52 +155,35 @@ private fun DismissButton(onDismiss: (() -> Unit)?) { contentDescription = stringResource( androidx.compose.material3.R.string.m3c_snackbar_dismiss ), modifier = Modifier.size(SettingsDimension.iconSmall), modifier = Modifier.padding(SettingsDimension.paddingSmall), ) } } } @Composable private fun Buttons(buttons: List<CardButton>) { private fun Buttons(buttons: List<CardButton>, color: Color) { if (buttons.isNotEmpty()) { Row( modifier = Modifier .fillMaxWidth() .padding(top = SettingsDimension.itemPaddingAround), modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy( space = SettingsDimension.itemPaddingEnd, alignment = Alignment.End, ), ) { for (button in buttons) { Button(button) Button(button, color) } } } else { Spacer(Modifier.height(SettingsDimension.itemPaddingAround)) } } @Composable private fun Button(button: CardButton) { if (button.isMain) { Button( onClick = button.onClick, colors = ButtonDefaults.buttonColors( containerColor = SettingsTheme.colorScheme.primaryContainer, ), ) { Text( text = button.text, color = SettingsTheme.colorScheme.onPrimaryContainer, ) } } else { OutlinedButton(onClick = button.onClick) { Text( text = button.text, color = MaterialTheme.colorScheme.onSurface, ) } private fun Button(button: CardButton, color: Color) { TextButton(onClick = button.onClick) { Text(text = button.text, color = color) } } Loading @@ -206,7 +198,6 @@ private fun SettingsCardPreview() { imageVector = Icons.Outlined.WarningAmber, buttons = listOf( CardButton(text = "Action") {}, CardButton(text = "Action", isMain = true) {}, ) ) ) Loading packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCollapsibleCard.kt +0 −1 Original line number Diff line number Diff line Loading @@ -141,7 +141,6 @@ private fun SettingsCollapsibleCardPreview() { imageVector = Icons.Outlined.Shield, buttons = listOf( CardButton(text = "Action") {}, CardButton(text = "Main action", isMain = true) {}, ) ) ) Loading Loading
packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/card/CardPageProvider.kt +9 −11 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import androidx.compose.material.icons.outlined.Error import androidx.compose.material.icons.outlined.PowerOff import androidx.compose.material.icons.outlined.Shield import androidx.compose.material.icons.outlined.WarningAmber import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue Loading Loading @@ -78,24 +79,19 @@ object CardPageProvider : SettingsPageProvider { imageVector = Icons.Outlined.WarningAmber, buttons = listOf( CardButton(text = "Action") {}, CardButton(text = "Action", isMain = true) {}, ) ), tintColor = MaterialTheme.colorScheme.error, containerColor = MaterialTheme.colorScheme.errorContainer, ) ) } @Composable private fun SettingsCardWithoutIcon() { var isVisible by rememberSaveable { mutableStateOf(true) } SettingsCard( CardModel( title = stringResource(R.string.sample_title), text = stringResource(R.string.sample_text), isVisible = { isVisible }, onDismiss = { isVisible = false }, buttons = listOf( CardButton(text = "Action") {}, ), ) ) } Loading @@ -104,6 +100,7 @@ object CardPageProvider : SettingsPageProvider { fun SampleSettingsCollapsibleCard() { val context = LocalContext.current var isVisible0 by rememberSaveable { mutableStateOf(true) } var isVisible1 by rememberSaveable { mutableStateOf(true) } val cards = remember { mutableStateListOf( CardModel( Loading @@ -114,16 +111,17 @@ object CardPageProvider : SettingsPageProvider { onDismiss = { isVisible0 = false }, buttons = listOf( CardButton(text = "Action") {}, ) ), ), CardModel( title = context.getString(R.string.sample_title), text = context.getString(R.string.sample_text), imageVector = Icons.Outlined.Shield, isVisible = { isVisible1 }, onDismiss = { isVisible1 = false }, buttons = listOf( CardButton(text = "Action") {}, CardButton(text = "Main action", isMain = true) {}, ) ), ) ) } Loading
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt +0 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ object SettingsDimension { val itemPaddingAround = 8.dp val itemDividerHeight = 32.dp val iconSmall = 16.dp val iconLarge = 48.dp /** The size when app icon is displayed in list. */ Loading
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/CardModel.kt +7 −1 Original line number Diff line number Diff line Loading @@ -16,11 +16,11 @@ package com.android.settingslib.spa.widget.card import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector data class CardButton( val text: String, val isMain: Boolean = false, val onClick: () -> Unit, ) Loading @@ -38,4 +38,10 @@ data class CardModel( val onDismiss: (() -> Unit)? = null, val buttons: List<CardButton> = emptyList(), /** If specified, this color will be used to tint the icon and the buttons. */ val tintColor: Color = Color.Unspecified, /** If specified, this color will be used to tint the icon and the buttons. */ val containerColor: Color = Color.Unspecified, )
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCard.kt +31 −40 Original line number Diff line number Diff line Loading @@ -23,26 +23,26 @@ import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Close import androidx.compose.material.icons.outlined.WarningAmber import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.takeOrElse import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp Loading Loading @@ -72,11 +72,14 @@ fun SettingsCard(content: @Composable ColumnScope.() -> Unit) { } @Composable fun SettingsCardContent(content: @Composable ColumnScope.() -> Unit) { fun SettingsCardContent( containerColor: Color = Color.Unspecified, content: @Composable ColumnScope.() -> Unit, ) { Card( shape = CornerExtraSmall, colors = CardDefaults.cardColors( containerColor = SettingsTheme.colorScheme.surface, containerColor = containerColor.takeOrElse { SettingsTheme.colorScheme.surface }, ), modifier = Modifier .fillMaxWidth() Loading @@ -95,37 +98,43 @@ fun SettingsCard(model: CardModel) { @Composable internal fun SettingsCardImpl(model: CardModel) { AnimatedVisibility(visible = model.isVisible()) { SettingsCardContent { SettingsCardContent(containerColor = model.containerColor) { Column( modifier = Modifier.padding(SettingsDimension.itemPaddingStart), modifier = Modifier.padding( horizontal = SettingsDimension.dialogItemPaddingHorizontal, vertical = SettingsDimension.itemPaddingAround, ), verticalArrangement = Arrangement.spacedBy(SettingsDimension.itemPaddingAround) ) { CardHeader(model.imageVector, model.onDismiss) CardHeader(model.imageVector, model.tintColor, model.onDismiss) SettingsTitle(model.title) SettingsBody(model.text) Buttons(model.buttons) Buttons(model.buttons, model.tintColor) } } } } @Composable fun CardHeader(imageVector: ImageVector?, onDismiss: (() -> Unit)? = null) { fun CardHeader(imageVector: ImageVector?, iconColor: Color, onDismiss: (() -> Unit)? = null) { if (imageVector != null || onDismiss != null) { Spacer(Modifier.height(SettingsDimension.buttonPaddingVertical)) } Row(Modifier.fillMaxWidth()) { CardIcon(imageVector) CardIcon(imageVector, iconColor) Spacer(modifier = Modifier.weight(1f)) DismissButton(onDismiss) } } @Composable private fun CardIcon(imageVector: ImageVector?) { private fun CardIcon(imageVector: ImageVector?, color: Color) { if (imageVector != null) { Icon( imageVector = imageVector, contentDescription = null, modifier = Modifier.size(SettingsDimension.itemIconSize), tint = MaterialTheme.colorScheme.primary, tint = color.takeOrElse { MaterialTheme.colorScheme.primary }, ) } } Loading @@ -146,52 +155,35 @@ private fun DismissButton(onDismiss: (() -> Unit)?) { contentDescription = stringResource( androidx.compose.material3.R.string.m3c_snackbar_dismiss ), modifier = Modifier.size(SettingsDimension.iconSmall), modifier = Modifier.padding(SettingsDimension.paddingSmall), ) } } } @Composable private fun Buttons(buttons: List<CardButton>) { private fun Buttons(buttons: List<CardButton>, color: Color) { if (buttons.isNotEmpty()) { Row( modifier = Modifier .fillMaxWidth() .padding(top = SettingsDimension.itemPaddingAround), modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy( space = SettingsDimension.itemPaddingEnd, alignment = Alignment.End, ), ) { for (button in buttons) { Button(button) Button(button, color) } } } else { Spacer(Modifier.height(SettingsDimension.itemPaddingAround)) } } @Composable private fun Button(button: CardButton) { if (button.isMain) { Button( onClick = button.onClick, colors = ButtonDefaults.buttonColors( containerColor = SettingsTheme.colorScheme.primaryContainer, ), ) { Text( text = button.text, color = SettingsTheme.colorScheme.onPrimaryContainer, ) } } else { OutlinedButton(onClick = button.onClick) { Text( text = button.text, color = MaterialTheme.colorScheme.onSurface, ) } private fun Button(button: CardButton, color: Color) { TextButton(onClick = button.onClick) { Text(text = button.text, color = color) } } Loading @@ -206,7 +198,6 @@ private fun SettingsCardPreview() { imageVector = Icons.Outlined.WarningAmber, buttons = listOf( CardButton(text = "Action") {}, CardButton(text = "Action", isMain = true) {}, ) ) ) Loading
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCollapsibleCard.kt +0 −1 Original line number Diff line number Diff line Loading @@ -141,7 +141,6 @@ private fun SettingsCollapsibleCardPreview() { imageVector = Icons.Outlined.Shield, buttons = listOf( CardButton(text = "Action") {}, CardButton(text = "Main action", isMain = true) {}, ) ) ) Loading