diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/ListCard.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/ListCard.kt index a02de65d0..22c8d68fd 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/ListCard.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/ListCard.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -40,7 +41,6 @@ import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.testTag import androidx.compose.ui.semantics.Role -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import org.hisp.dhis.mobile.ui.designsystem.component.internal.conditional import org.hisp.dhis.mobile.ui.designsystem.resource.provideDHIS2Icon @@ -84,8 +84,7 @@ fun ListCard( val expandableItemList = mutableListOf() val constantItemList = mutableListOf() - additionalInfoList.forEach { - item -> + additionalInfoList.forEach { item -> if (item.isConstantItem) { constantItemList.add(item) } else { @@ -140,7 +139,6 @@ fun ListCard( isConstantItem = false, ), showLoading = showLoading, - ) actionButton?.invoke() } @@ -175,8 +173,7 @@ fun CardDetail( val expandableItemList = mutableListOf() val constantItemList = mutableListOf() - additionalInfoList.forEach { - item -> + additionalInfoList.forEach { item -> if (item.isConstantItem) { constantItemList.add(item) } else { @@ -221,7 +218,6 @@ fun CardDetail( isConstantItem = false, ), showLoading = showLoading, - ) actionButton?.invoke() } @@ -260,11 +256,13 @@ fun Avatar( } } } + AvatarStyle.METADATA -> { metadataAvatar?.let { metadataAvatar.invoke() } } + AvatarStyle.IMAGE -> { Image( painter = imagePainter, @@ -366,7 +364,6 @@ private fun AdditionalInfoColumn( color = expandTextColor, style = MaterialTheme.typography.bodyMedium, modifier = Modifier.padding(horizontal = Spacing4), - ) } } @@ -383,86 +380,76 @@ private fun KeyValue( isDetailCard: Boolean = false, modifier: Modifier = Modifier, ) { - Row( - modifier = modifier, - ) { - val keyColor: Color - var valueColor: Color - val interactionSource = remember { MutableInteractionSource() } + BoxWithConstraints(modifier = Modifier.fillMaxWidth()) { + val maxKeyWidth = maxWidth / 2 - Spacing.Spacing16 - if (isDetailCard) { - keyColor = AdditionalInfoItemColor.DEFAULT_KEY.color - valueColor = additionalInfoItem.color ?: AdditionalInfoItemColor.DEFAULT_VALUE.color - additionalInfoItem.key?.let { - Box( - Modifier.background(color = Color.Transparent).widthIn(Spacing.Spacing0, Spacing.Spacing160), - ) { - Text( - text = it, + Row( + modifier = modifier, + ) { + val keyColor: Color + var valueColor: Color + val interactionSource = remember { MutableInteractionSource() } + + if (isDetailCard) { + keyColor = AdditionalInfoItemColor.DEFAULT_KEY.color + valueColor = additionalInfoItem.color ?: AdditionalInfoItemColor.DEFAULT_VALUE.color + additionalInfoItem.key?.let { + ListCardKey( + text = additionalInfoItem.key, color = keyColor, - style = MaterialTheme.typography.bodyMedium, - modifier = Modifier, - overflow = TextOverflow.Ellipsis, - maxLines = 2, + Modifier.padding(end = Spacing4).widthIn(Spacing.Spacing0, maxKeyWidth), ) } - } - Row( - modifier = Modifier - .clip(shape = RoundedCornerShape(Radius.XS)) - .conditional(additionalInfoItem.action != null, { - clickable( - role = Role.Button, - interactionSource = interactionSource, - indication = rememberRipple( - color = SurfaceColor.Primary, - ), - onClick = additionalInfoItem.action ?: {}, - ) - }), - ) { - Spacer(Modifier.size(Spacing4)) - if (additionalInfoItem.icon != null) { - Box( - Modifier.background(color = Color.Transparent).size(InternalSizeValues.Size20), - ) { - additionalInfoItem.icon.invoke() + Row( + modifier = Modifier + .clip(shape = RoundedCornerShape(Radius.XS)) + .conditional(additionalInfoItem.action != null, { + clickable( + role = Role.Button, + interactionSource = interactionSource, + indication = rememberRipple( + color = SurfaceColor.Primary, + ), + onClick = additionalInfoItem.action ?: {}, + ) + }), + ) { + Spacer(Modifier.size(Spacing4)) + if (additionalInfoItem.icon != null) { + Box( + Modifier.background(color = Color.Transparent).size(InternalSizeValues.Size20), + ) { + additionalInfoItem.icon.invoke() + } } - } - Spacer(Modifier.size(Spacing4)) - valueColor = if (additionalInfoItem.action != null) SurfaceColor.Primary else valueColor - ListCardValue(text = additionalInfoItem.value, color = valueColor) - Spacer(Modifier.size(Spacing4)) - } - } else { - keyColor = additionalInfoItem.color ?: AdditionalInfoItemColor.DEFAULT_KEY.color - valueColor = additionalInfoItem.color ?: AdditionalInfoItemColor.DEFAULT_VALUE.color - if (additionalInfoItem.icon != null) { - Box( - Modifier.background(color = Color.Transparent).size(InternalSizeValues.Size20), - ) { - additionalInfoItem.icon.invoke() + Spacer(Modifier.size(Spacing4)) + valueColor = if (additionalInfoItem.action != null) SurfaceColor.Primary else valueColor + ListCardValue(text = additionalInfoItem.value, color = valueColor) + Spacer(Modifier.size(Spacing4)) } - Spacer(Modifier.size(Spacing4)) } else { - additionalInfoItem.key?.let { + keyColor = additionalInfoItem.color ?: AdditionalInfoItemColor.DEFAULT_KEY.color + valueColor = additionalInfoItem.color ?: AdditionalInfoItemColor.DEFAULT_VALUE.color + if (additionalInfoItem.icon != null) { Box( - Modifier.background(color = Color.Transparent).widthIn(Spacing.Spacing0, Spacing.Spacing160), + Modifier.background(color = Color.Transparent).size(InternalSizeValues.Size20), ) { - Text( - text = it, + additionalInfoItem.icon.invoke() + } + Spacer(Modifier.size(Spacing4)) + } else { + additionalInfoItem.key?.let { + ListCardKey( + text = additionalInfoItem.key, color = keyColor, - style = MaterialTheme.typography.bodyMedium, - modifier = Modifier.padding(end = Spacing4), - overflow = TextOverflow.Ellipsis, - maxLines = 2, + Modifier.padding(end = Spacing4).widthIn(Spacing.Spacing0, maxKeyWidth), ) } } + ListCardValue(text = additionalInfoItem.value, color = valueColor) } - ListCardValue(text = additionalInfoItem.value, color = valueColor, Modifier.weight(1f)) } } } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/Text.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/Text.kt index 0ebeac575..d624cff98 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/Text.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/Text.kt @@ -7,6 +7,10 @@ import androidx.compose.foundation.layout.size import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.Color @@ -166,6 +170,32 @@ internal fun ListCardLastUpdated( ) } +@Composable +internal fun ListCardKey( + text: String, + color: Color, + modifier: Modifier = Modifier, +) { + var modifiedText by remember { mutableStateOf(text) } + Text( + text = modifiedText, + color = color, + style = MaterialTheme.typography.bodyMedium, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + modifier = modifier, + onTextLayout = { textLayoutResult -> + if (textLayoutResult.hasVisualOverflow) { + val lineIndex = textLayoutResult.getLineEnd( + lineIndex = 0, + visibleEnd = true, + ) + modifiedText = modifiedText.substring(0, lineIndex) + "...:" + } + }, + ) +} + @Composable internal fun ListCardValue( text: String,