Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5ebf7b1 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[expressive design] Update Spinner layout." into main

parents 71a1d657 98b11660
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import androidx.compose.ui.unit.dp
object SettingsDimension {
    val paddingTiny = 2.dp
    val paddingExtraSmall = 4.dp
    val paddingExtraSmall1 = 6.dp
    val paddingSmall = if (isSpaExpressiveEnabled) 8.dp else 4.dp
    val paddingExtraSmall5 = 10.dp
    val paddingExtraSmall6 = 12.dp
@@ -87,4 +88,7 @@ object SettingsDimension {
    val illustrationCornerRadius = 28.dp

    val preferenceMinHeight = 72.dp

    val spinnerOptionMinHeight = 48.dp
    val spinnerIconSize = 20.dp
}
+3 −1
Original line number Diff line number Diff line
@@ -24,7 +24,9 @@ object SettingsShape {

    val CornerMedium = RoundedCornerShape(12.dp)

    val categoryCorner = RoundedCornerShape(20.dp)
    val CornerMedium2 = RoundedCornerShape(20.dp)

    val CornerLarge = RoundedCornerShape(24.dp)

    val CornerExtraLarge = RoundedCornerShape(28.dp)
}
+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ fun Category(title: String? = null, content: @Composable ColumnScope.() -> Unit)
                    }
                    .then(
                        if (isSpaExpressiveEnabled)
                            Modifier.fillMaxWidth().clip(SettingsShape.categoryCorner)
                            Modifier.fillMaxWidth().clip(SettingsShape.CornerMedium2)
                        else Modifier
                    ),
            verticalArrangement =
+139 −60
Original line number Diff line number Diff line
@@ -19,9 +19,14 @@ package com.android.settingslib.spa.widget.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Check
import androidx.compose.material.icons.outlined.ExpandLess
import androidx.compose.material.icons.outlined.ExpandMore
import androidx.compose.material3.Button
@@ -38,20 +43,19 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
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.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.framework.theme.SettingsShape
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.theme.isSpaExpressiveEnabled

data class SpinnerOption(
    val id: Int,
    val text: String,
)
data class SpinnerOption(val id: Int, val text: String)

@Composable
fun Spinner(options: List<SpinnerOption>, selectedId: Int?, setId: (id: Int) -> Unit) {
@@ -62,23 +66,72 @@ fun Spinner(options: List<SpinnerOption>, selectedId: Int?, setId: (id: Int) ->
    var expanded by rememberSaveable { mutableStateOf(false) }

    Box(
        modifier = Modifier
            .padding(
        modifier =
            Modifier.padding(
                    start = SettingsDimension.itemPaddingStart,
                    top = SettingsDimension.itemPaddingAround,
                    end = SettingsDimension.itemPaddingEnd,
                    bottom = SettingsDimension.itemPaddingAround,
                )
            .selectableGroup(),
                .selectableGroup()
    ) {
        val contentPadding = if (isSpaExpressiveEnabled) PaddingValues(
        if (isSpaExpressiveEnabled) {
            Button(
                modifier = Modifier.semantics { role = Role.DropdownList },
                onClick = { expanded = true },
                colors =
                    ButtonDefaults.buttonColors(
                        containerColor = MaterialTheme.colorScheme.secondaryContainer,
                        contentColor = MaterialTheme.colorScheme.onSecondaryContainer,
                    ),
                contentPadding =
                    PaddingValues(
                        horizontal = SettingsDimension.spinnerHorizontalPadding,
            vertical = SettingsDimension.spinnerVerticalPadding
        ) else PaddingValues(horizontal = SettingsDimension.itemPaddingEnd)
                        vertical = SettingsDimension.spinnerVerticalPadding,
                    ),
            ) {
                SpinnerText(options.find { it.id == selectedId })
                ExpandIcon(expanded)
            }
            DropdownMenu(
                expanded = expanded,
                onDismissRequest = { expanded = false },
                shape = SettingsShape.CornerLarge,
                modifier =
                    Modifier.background(MaterialTheme.colorScheme.surfaceContainerLow)
                        .padding(horizontal = SettingsDimension.paddingSmall),
            ) {
                for ((index, option) in options.withIndex()) {
                    val selected = index + 1 == selectedId
                    DropdownMenuItem(
                        text = { SpinnerOptionText(option = option, selected) },
                        onClick = {
                            expanded = false
                            setId(option.id)
                        },
                        contentPadding =
                            PaddingValues(
                                horizontal = SettingsDimension.paddingSmall,
                                vertical = SettingsDimension.paddingExtraSmall1,
                            ),
                        modifier =
                            Modifier.heightIn(min = SettingsDimension.spinnerOptionMinHeight)
                                .then(
                                    if (selected)
                                        Modifier.clip(SettingsShape.CornerMedium2)
                                            .background(MaterialTheme.colorScheme.primaryContainer)
                                    else Modifier
                                ),
                    )
                }
            }
        } else {
            val contentPadding = PaddingValues(horizontal = SettingsDimension.itemPaddingEnd)
            Button(
                modifier = Modifier.semantics { role = Role.DropdownList },
                onClick = { expanded = true },
            colors = ButtonDefaults.buttonColors(
                colors =
                    ButtonDefaults.buttonColors(
                        containerColor = MaterialTheme.colorScheme.primaryContainer,
                        contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
                    ),
@@ -111,11 +164,13 @@ fun Spinner(options: List<SpinnerOption>, selectedId: Int?, setId: (id: Int) ->
            }
        }
    }
}

@Composable
internal fun ExpandIcon(expanded: Boolean) {
    Icon(
        imageVector = when {
        imageVector =
            when {
                expanded -> Icons.Outlined.ExpandLess
                else -> Icons.Outlined.ExpandMore
            },
@@ -131,7 +186,8 @@ private fun SpinnerText(
) {
    Text(
        text = option?.text ?: "",
        modifier = modifier
        modifier =
            modifier
                .padding(end = SettingsDimension.itemPaddingEnd)
                .then(
                    if (!isSpaExpressiveEnabled)
@@ -143,6 +199,29 @@ private fun SpinnerText(
    )
}

@Composable
private fun SpinnerOptionText(option: SpinnerOption?, selected: Boolean) {
    Row {
        if (selected) {
            Icon(
                imageVector = Icons.Outlined.Check,
                modifier = Modifier.size(SettingsDimension.spinnerIconSize),
                tint = MaterialTheme.colorScheme.onPrimaryContainer,
                contentDescription = null,
            )
            Spacer(Modifier.padding(SettingsDimension.paddingSmall))
        }
        Text(
            text = option?.text ?: "",
            modifier = Modifier.padding(end = SettingsDimension.itemPaddingEnd),
            color =
                if (selected) MaterialTheme.colorScheme.onPrimaryContainer
                else MaterialTheme.colorScheme.onSurface,
            style = MaterialTheme.typography.labelLarge,
        )
    }
}

@Preview(showBackground = true)
@Composable
private fun SpinnerPreview() {