diff --git a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/bottomSheets/BottomSheetScreen.kt b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/bottomSheets/BottomSheetScreen.kt index e9c84e2fa..7018389bc 100644 --- a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/bottomSheets/BottomSheetScreen.kt +++ b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/bottomSheets/BottomSheetScreen.kt @@ -1,11 +1,13 @@ package org.hisp.dhis.common.screens.bottomSheets +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.requiredWidth +import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState @@ -34,6 +36,7 @@ import org.hisp.dhis.mobile.ui.designsystem.component.ColorStyle import org.hisp.dhis.mobile.ui.designsystem.component.ColumnComponentContainer import org.hisp.dhis.mobile.ui.designsystem.component.ColumnScreenContainer import org.hisp.dhis.mobile.ui.designsystem.component.LegendRange +import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor @Composable @@ -191,41 +194,45 @@ fun BottomSheetScreen() { subtitle = "Subtitle", description = lorem, buttonBlock = { - ButtonBlock( - primaryButton = { - Button( - style = ButtonStyle.OUTLINED, - icon = { - Icon( - imageVector = Icons.Filled.Add, - contentDescription = "Button", - ) - }, - enabled = true, - text = "Label", - onClick = { - showBottomSheetShellTwoButtons = false - }, - modifier = Modifier.fillMaxWidth(), - ) - }, - secondaryButton = { - Button( - style = ButtonStyle.FILLED, - icon = { - Icon( - imageVector = Icons.Filled.Add, - contentDescription = "Button", - ) - }, - enabled = true, - text = "Label", - onClick = { - }, - modifier = Modifier.fillMaxWidth(), - ) - }, - ) + Row( + modifier = Modifier.padding(Spacing.Spacing24), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Button( + modifier = Modifier.weight(0.5f), + style = ButtonStyle.OUTLINED, + icon = { + Icon( + imageVector = Icons.Filled.Add, + contentDescription = "Button", + ) + }, + enabled = true, + text = "Label", + onClick = { + showBottomSheetShellTwoButtons = false + }, + + ) + + Spacer(Modifier.size(Spacing.Spacing8)) + Button( + modifier = Modifier.weight(0.5f), + + style = ButtonStyle.FILLED, + icon = { + Icon( + imageVector = Icons.Filled.Add, + contentDescription = "Button", + ) + }, + enabled = true, + text = "Label", + onClick = { + }, + ) + } }, icon = { Icon( diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BottomSheet.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BottomSheet.kt index b1a0a519d..53b873ab1 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BottomSheet.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/BottomSheet.kt @@ -8,14 +8,11 @@ import androidx.compose.foundation.layout.Arrangement.spacedBy import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons @@ -37,7 +34,6 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp @@ -54,7 +50,7 @@ import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing.Spacing24 import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing.Spacing8 import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor -import org.hisp.dhis.mobile.ui.designsystem.theme.Color as ThemeColor +import org.hisp.dhis.mobile.ui.designsystem.theme.innerShadow /** * DHIS2 [BottomSheetHeader] component designed to be used @@ -224,10 +220,13 @@ fun BottomSheetShell( val canScrollForward by derivedStateOf { contentScrollState.canScrollForward } Column( - modifier = Modifier.padding( - bottom = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding(), - ), + modifier = Modifier.padding(bottom = Spacing0).background(SurfaceColor.SurfaceBright, Shape.ExtraLargeTop), ) { + val scrollColumnShadow = if (canScrollForward) { + Modifier.innerShadow(blur = 32.dp) + } else { + Modifier + } Column( modifier = Modifier .weight(1f, fill = false) @@ -284,19 +283,24 @@ fun BottomSheetShell( } else { Modifier } - Column( - modifier = Modifier - .padding(horizontal = Spacing24) - .heightIn(scrollableContainerMinHeight, scrollableContainerMaxHeight) - .then(scrollModifier), + Modifier + .then(scrollColumnShadow), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = spacedBy(Spacing8), ) { - content.invoke() - if (showSectionDivider) { + Column( + modifier = Modifier + .padding(horizontal = Spacing24) + .heightIn(scrollableContainerMinHeight, scrollableContainerMaxHeight) + .then(scrollModifier), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = spacedBy(Spacing8), + ) { + content.invoke() + } + if (showSectionDivider && !canScrollForward) { HorizontalDivider( - modifier = Modifier.fillMaxWidth(), + modifier = Modifier.fillMaxWidth().padding(horizontal = Spacing24), color = TextColor.OnDisabledSurface, thickness = Border.Thin, ) @@ -304,31 +308,8 @@ fun BottomSheetShell( } } } - - val shadowModifier = if (canScrollForward && content != null) { - Modifier.shadow( - elevation = 32.dp, - ambientColor = ThemeColor.Blue900, - spotColor = ThemeColor.Blue900, - ) - } else { - Modifier - } - - Box( - Modifier.fillMaxWidth() - .then(shadowModifier) - .background(SurfaceColor.SurfaceBright) - .padding( - start = Spacing24, - top = Spacing24, - end = Spacing24, - bottom = Spacing24, - ), - contentAlignment = Alignment.BottomCenter, - ) { - buttonBlock?.invoke() - Spacer(Modifier.size(Spacing8)) + buttonBlock?.let { + buttonBlock.invoke() } } } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/OrgBottomSheet.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/OrgBottomSheet.kt index 08525a5e1..355d39d82 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/OrgBottomSheet.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/OrgBottomSheet.kt @@ -30,7 +30,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.layout.onGloballyPositioned @@ -109,7 +108,6 @@ fun OrgBottomSheet( onSearch?.invoke(searchQuery) }, onSearch = onSearch, - scrollableContainerMinHeight = InternalSizeValues.Size386, scrollableContainerMaxHeight = maxOf(orgTreeHeightInDp, InternalSizeValues.Size386), content = { OrgTreeList( @@ -130,6 +128,7 @@ fun OrgBottomSheet( buttonBlock = { Row( verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(Spacing.Spacing24), ) { if (onClearAll != null) { Button( @@ -227,7 +226,6 @@ fun OrgUnitSelectorItem( modifier = modifier .testTag("$ITEM_TEST_TAG${orgTreeItem.label}") .fillMaxWidth() - .background(Color.White) .clickable( enabled = orgTreeItem.hasChildren, interactionSource = remember { diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Shadow.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Shadow.kt index 14df826bc..ea9bdf8d3 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Shadow.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Shadow.kt @@ -9,9 +9,11 @@ import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.draw.drawWithCache import androidx.compose.ui.geometry.CornerRadius import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.ClipOp import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.NativePaint import androidx.compose.ui.graphics.Paint +import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.drawOutline import androidx.compose.ui.graphics.drawscope.drawIntoCanvas @@ -83,6 +85,40 @@ internal fun Modifier.buttonShadow( }, ) +internal fun Modifier.innerShadow( + blur: Dp = 10.dp, +): Modifier = this.then( + drawBehind { + val shadowSize = Size(size.width, 12.dp.toPx()) + val shadowOutline = RectangleShape.createOutline(shadowSize, layoutDirection, this) + + // Create a Paint object + val paint = Paint() + // Apply specified color + paint.color = TextColor.OnSurfaceVariant.copy(alpha = 0.3f) + + // Check for valid blur radius + if (blur.toPx() > 0) { + paint.asFrameworkPaint().apply { + // Apply blur to the Paint + paintBlur(blur.toPx()) + } + } + + drawIntoCanvas { canvas -> + // Save the canvas state + canvas.save() + // Translate to specified offsets + canvas.translate(Spacing.Spacing0.toPx(), size.height - 12.dp.toPx()) + canvas.clipRect(0f, size.height - 12.dp.toPx(), size.width, size.height - 12.dp.toPx(), ClipOp.Difference) + // Draw the shadow + canvas.drawOutline(shadowOutline, paint) + // Restore the canvas state + canvas.restore() + } + }, +) + internal fun Modifier.iconCardShadow( color: Color = SurfaceColor.ContainerHighest, borderRadius: Dp = Radius.NoRounding,