From af31ad6eee5270a34c6d0cb77d2a744ff9f9506b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Miguel=20Rubio?= Date: Thu, 14 Sep 2023 12:00:49 +0200 Subject: [PATCH] [ANDROAPP-5556] Section ripple effect (#64) * Modify Section component to allow onClickCallback and no_header * [ANDROAPP-5556] Aviod ripple effect for flat sections --- .../hisp/dhis/common/screens/SectionScreen.kt | 10 ++ .../ui/designsystem/component/Sections.kt | 132 +++++++++++++----- .../ui/designsystem/component/SectionTest.kt | 2 + 3 files changed, 112 insertions(+), 32 deletions(-) diff --git a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/SectionScreen.kt b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/SectionScreen.kt index 2cbaabb17..2a9d7ad89 100644 --- a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/SectionScreen.kt +++ b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/SectionScreen.kt @@ -35,6 +35,7 @@ fun SectionScreen() { warningCount = 0, content = { TestingFields() }, onNextSection = { }, + onSectionClick = { }, ) Section( title = "Section title", @@ -46,6 +47,7 @@ fun SectionScreen() { warningCount = 1, content = { TestingFields() }, onNextSection = { }, + onSectionClick = { }, ) Section( title = "Section title", @@ -57,6 +59,7 @@ fun SectionScreen() { warningCount = 1, content = { TestingFields() }, onNextSection = { }, + onSectionClick = { }, ) Section( title = "Section title", @@ -68,6 +71,7 @@ fun SectionScreen() { warningCount = 0, content = { TestingFields() }, onNextSection = { }, + onSectionClick = { }, ) Section( title = "Section title Section title Section title Section title Section title", @@ -79,6 +83,7 @@ fun SectionScreen() { warningCount = 0, content = { TestingFields() }, onNextSection = { }, + onSectionClick = { }, ) } @@ -95,6 +100,7 @@ fun SectionScreen() { warningCount = 0, content = { TestingFields() }, onNextSection = { }, + onSectionClick = { }, ) Section( title = "Section title", @@ -106,6 +112,7 @@ fun SectionScreen() { warningCount = 1, content = { TestingFields() }, onNextSection = { }, + onSectionClick = { }, ) Section( title = "Section title", @@ -117,6 +124,7 @@ fun SectionScreen() { warningCount = 0, content = { TestingFields() }, onNextSection = { }, + onSectionClick = { }, ) Section( title = "Section title", @@ -128,6 +136,7 @@ fun SectionScreen() { warningCount = 0, content = { TestingFields() }, onNextSection = { }, + onSectionClick = { }, ) Section( title = "Section title Section title Section title Section title Section title", @@ -139,6 +148,7 @@ fun SectionScreen() { warningCount = 0, content = { TestingFields() }, onNextSection = { }, + onSectionClick = { }, ) } } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/Sections.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/Sections.kt index ae05bebe4..bf034f462 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/Sections.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/Sections.kt @@ -6,6 +6,7 @@ import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement.spacedBy import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -50,19 +51,21 @@ import org.hisp.dhis.mobile.ui.designsystem.resource.provideStringResource import org.hisp.dhis.mobile.ui.designsystem.theme.Color.Ash600 import org.hisp.dhis.mobile.ui.designsystem.theme.Shape import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing +import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing.Spacing0 import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing.Spacing16 import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing.Spacing24 import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor enum class SectionState { - OPEN, CLOSE, FIXED; + OPEN, CLOSE, FIXED, NO_HEADER; fun getNextState(): SectionState { return when (this) { OPEN -> CLOSE CLOSE -> OPEN FIXED -> FIXED + NO_HEADER -> NO_HEADER } } } @@ -79,10 +82,47 @@ fun Section( errorCount: Int, warningCount: Int, onNextSection: () -> Unit, + onSectionClick: () -> Unit, + content: @Composable ColumnScope.() -> Unit, +) { + when (state) { + SectionState.NO_HEADER -> SectionContent(spacedBy(Spacing0)) { content() } + else -> SectionBlock( + modifier = modifier, + isLastSection = isLastSection, + title = title, + description = description, + completedFields = completedFields, + totalFields = totalFields, + state = state, + errorCount = errorCount, + warningCount = warningCount, + onNextSection = onNextSection, + onSectionClick = onSectionClick, + ) { + content() + } + } +} + +@Composable +internal fun SectionBlock( + modifier: Modifier, + isLastSection: Boolean, + title: String, + description: String?, + completedFields: Int, + totalFields: Int, + state: SectionState, + errorCount: Int, + warningCount: Int, + onNextSection: () -> Unit, + onSectionClick: () -> Unit, content: @Composable ColumnScope.() -> Unit, ) { var sectionState by remember(state) { mutableStateOf(state) } - val bottomPadding = when (state) { + + val bottomPadding = when (sectionState) { SectionState.FIXED -> Spacing.Spacing40 else -> Spacing16 } @@ -92,7 +132,7 @@ fun Section( .fillMaxWidth() .background(Color.White) .run { - if (state != SectionState.FIXED) { + if (sectionState != SectionState.FIXED) { bottomBorder(1.dp, Ash600) } else { this @@ -111,6 +151,7 @@ fun Section( warningCount = warningCount, onSectionClick = { sectionState = sectionState.getNextState() + onSectionClick() }, ) AnimatedVisibility( @@ -118,34 +159,35 @@ fun Section( enter = expandVertically(expandFrom = Alignment.CenterVertically), exit = shrinkVertically(shrinkTowards = Alignment.CenterVertically), ) { - Column( - modifier = Modifier - .testTag(SectionTestTag.CONTENT) - .fillMaxWidth(), - verticalArrangement = spacedBy(Spacing16), - ) { - content() - } + SectionContent(verticalArrangement = spacedBy(Spacing16)) { content() } } if (!isLastSection && sectionState == SectionState.OPEN) { - Button( + NextSectionButton( modifier = Modifier.align(Alignment.End), - style = ButtonStyle.TEXT, - text = provideStringResource("action_next"), - icon = { - Icon( - imageVector = Icons.Filled.ArrowForward, - contentDescription = "Icon Button", - ) - }, - onClick = onNextSection, - ) + ) { onNextSection() } } } } @Composable -fun SectionHeader( +internal fun SectionContent( + verticalArrangement: Arrangement.HorizontalOrVertical, + content: + @Composable() + (ColumnScope.() -> Unit), +) { + Column( + modifier = Modifier + .testTag(SectionTestTag.CONTENT) + .fillMaxWidth(), + verticalArrangement = verticalArrangement, + ) { + content() + } +} + +@Composable +internal fun SectionHeader( modifier: Modifier = Modifier, title: String, description: String?, @@ -164,6 +206,7 @@ fun SectionHeader( SectionState.OPEN -> hideFieldsLabel SectionState.CLOSE -> showFieldsLabel SectionState.FIXED -> "" + SectionState.NO_HEADER -> "" } } } @@ -174,6 +217,7 @@ fun SectionHeader( SectionState.OPEN -> Icons.Filled.KeyboardArrowUp SectionState.CLOSE -> Icons.Filled.KeyboardArrowDown SectionState.FIXED -> null + SectionState.NO_HEADER -> null } } } @@ -189,15 +233,20 @@ fun SectionHeader( .fillMaxWidth() .background(color = Color.White, Shape.Small) .clip(Shape.Small) - .clickable( - enabled = sectionState != SectionState.FIXED, - role = Role.Button, - interactionSource = interactionSource, - indication = rememberRipple( - color = SurfaceColor.Primary, - ), - ) { - onSectionClick() + .let { + if (sectionState == SectionState.FIXED) { + it + } else { + it.clickable( + role = Role.Button, + interactionSource = interactionSource, + indication = rememberRipple( + color = SurfaceColor.Primary, + ), + ) { + onSectionClick() + } + } } .padding(vertical = Spacing.Spacing8), ) { @@ -317,6 +366,25 @@ internal fun StateIndicator(label: String, icon: ImageVector?) { } } +@Composable +internal fun NextSectionButton( + modifier: Modifier, + onClick: () -> Unit, +) { + Button( + modifier = modifier, + style = ButtonStyle.TEXT, + text = provideStringResource("action_next"), + icon = { + Icon( + imageVector = Icons.Filled.ArrowForward, + contentDescription = "Icon Button", + ) + }, + onClick = onClick, + ) +} + internal object SectionTestTag { const val CONTENT = "CONTENT" const val HEADER = "HEADER" diff --git a/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/SectionTest.kt b/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/SectionTest.kt index 853bbfb72..dbceef623 100644 --- a/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/SectionTest.kt +++ b/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/SectionTest.kt @@ -90,6 +90,7 @@ class SectionTest { warningCount = 0, onNextSection = { }, + onSectionClick = { }, content = { }, ) @@ -126,6 +127,7 @@ class SectionTest { warningCount = 0, onNextSection = { }, + onSectionClick = { }, content = { }, )