From de7db6bd3c0fa6f54dd05f10fcdfd42a66dd6a5c Mon Sep 17 00:00:00 2001 From: Romain Goutte-Fangeas Date: Wed, 26 Feb 2025 10:42:38 +0100 Subject: [PATCH] Add action to GrapesSection --- .../grapes/compose/section/GrapesSection.kt | 128 ++++++++++++++++-- 1 file changed, 119 insertions(+), 9 deletions(-) diff --git a/library-compose/src/main/java/com/spendesk/grapes/compose/section/GrapesSection.kt b/library-compose/src/main/java/com/spendesk/grapes/compose/section/GrapesSection.kt index e3042599..ffc4becb 100644 --- a/library-compose/src/main/java/com/spendesk/grapes/compose/section/GrapesSection.kt +++ b/library-compose/src/main/java/com/spendesk/grapes/compose/section/GrapesSection.kt @@ -1,14 +1,23 @@ package com.spendesk.grapes.compose.section +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.material3.ButtonColors import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults 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.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.spendesk.grapes.compose.internal.Slot @@ -22,6 +31,7 @@ import com.spendesk.grapes.compose.theme.GrapesTheme fun GrapesSection( title: String, modifier: Modifier = Modifier, + action: @Composable (GrapesSectionActionScope.() -> Unit)? = null, content: @Composable () -> Unit, ) { Card( @@ -33,28 +43,128 @@ fun GrapesSection( ), ) { Column( - modifier = Modifier.padding(vertical = GrapesTheme.dimensions.unit8), + modifier = Modifier + .padding(vertical = GrapesTheme.dimensions.unit8) + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Text( + text = title, + style = GrapesTheme.typography.titleS, + color = GrapesTheme.colors.contentSecondaryBGSecondary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier + .weight(1f) + .padding( + horizontal = GrapesTheme.dimensions.unit16, + vertical = GrapesTheme.dimensions.unit8, + ) + ) + if (action != null) { + Box { + GrapesSectionActionScope.action() + } + } + } + content() + } + } +} + +object GrapesSectionActionScope { + + @Composable + fun Action( + title: String, + modifier: Modifier = Modifier, + enabled: Boolean = true, + onClick: () -> Unit, + ) { + TextButton( + onClick = onClick, + contentPadding = PaddingValues( + horizontal = GrapesTheme.dimensions.unit16, + vertical = 0.dp, + ), + shape = GrapesTheme.shapes.radius8, + enabled = enabled, + colors = ButtonColors( + contentColor = GrapesTheme.colors.contentBrandDefault, + containerColor = GrapesTheme.colors.backgroundPrimaryDefault, + disabledContentColor = GrapesTheme.colors.contentDisable, + disabledContainerColor = GrapesTheme.colors.backgroundPrimaryDefault, + ), + modifier = modifier + .widthIn(min = GrapesTheme.dimensions.unit48) + .height(GrapesTheme.dimensions.unit32) ) { Text( text = title, style = GrapesTheme.typography.titleS, - color = GrapesTheme.colors.contentSecondaryBGSecondary, - modifier = Modifier.padding( - horizontal = GrapesTheme.dimensions.unit16, - vertical = GrapesTheme.dimensions.unit8, - ), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + } +} + +@Preview +@Preview(fontScale = 2f) +@Composable +private fun PreviewGrapesSectionWithAction() { + GrapesTheme { + GrapesSection( + title = "Some section title", + action = { + Action( + title = "Actionable", + onClick = {}, + enabled = true, + ) + }, + ) { + Slot( + modifier = Modifier + .fillMaxWidth() + .height(100.dp) + ) + } + } +} + +@Preview +@Composable +private fun PreviewGrapesSectionWithActionDisabled() { + GrapesTheme { + GrapesSection( + title = "Some section title", + action = { + Action( + title = "Actionable", + onClick = {}, + enabled = false, + ) + }, + ) { + Slot( + modifier = Modifier + .fillMaxWidth() + .height(100.dp) ) - content() } } } @Preview @Composable -private fun GrapesSectionPreview() { +private fun PreviewGrapesSectionWithoutAction() { GrapesTheme { GrapesSection( - title = "Title", + title = "Some section title", + action = null, ) { Slot( modifier = Modifier