Coverage Summary for Class: SurferWorkspaceRowKt (com.georgeci.moneysurfer.uikit.components.workspace)

Class Class, % Method, % Branch, % Line, % Instruction, %
SurferWorkspaceRowKt 0% (0/1) 0% (0/8) 0% (0/84) 0% (0/127) 0% (0/1545)


 package com.georgeci.moneysurfer.uikit.components.workspace
 
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 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.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material3.Icon
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import com.georgeci.moneysurfer.uikit.atom.SurferActionCard
 import com.georgeci.moneysurfer.uikit.atom.SurferCard
 import com.georgeci.moneysurfer.uikit.components.base.SurferOutlinedChip
 import com.georgeci.moneysurfer.uikit.icons.SurferIcons
 import com.georgeci.moneysurfer.uikit.preview.SurferComponentPreview
 import com.georgeci.moneysurfer.uikit.semantics.SurferSemantics
 import com.georgeci.moneysurfer.uikit.theme.AppTheme
 
 private val IconSize = 48.dp
 private val IconCorner = RoundedCornerShape(14.dp)
 
 /**
  * Full workspace selector row. Renders via [SurferCard] — variant + selected fill driven by the
  * theme's container style. When [selected] is true and [showActions] is on, "Edit" and "Members"
  * chips appear under the title.
  */
 @Composable
 fun SurferWorkspaceRow(
     name: String,
     subtitle: String,
     selected: Boolean,
     enabled: Boolean,
     onClick: () -> Unit,
     modifier: Modifier = Modifier,
     showActions: Boolean = false,
     editLabel: String? = null,
     membersLabel: String? = null,
     onEditClick: () -> Unit = {},
     onMembersClick: () -> Unit = {},
 ) {
     SurferCard(
         modifier = modifier.fillMaxWidth(),
         selected = selected,
         onClick = onClick.takeIf { enabled },
     ) {
         RowBody(
             name = name,
             subtitle = subtitle,
             selected = selected,
             showActions = selected && showActions,
             enabled = enabled,
             editLabel = editLabel,
             membersLabel = membersLabel,
             onEditClick = onEditClick,
             onMembersClick = onMembersClick,
         )
     }
 }
 
 @Composable
 fun SurferCreateWorkspaceRow(
     title: String,
     subtitle: String,
     onClick: () -> Unit,
     modifier: Modifier = Modifier,
 ) {
     SurferActionCard(
         modifier = modifier.fillMaxWidth(),
         onClick = onClick,
     ) {
         Row(
             verticalAlignment = Alignment.CenterVertically,
             horizontalArrangement = Arrangement.spacedBy(14.dp),
         ) {
             Box(
                 modifier = Modifier
                     .size(IconSize)
                     .clip(IconCorner)
                     .background(AppTheme.materialColors.surfaceContainer),
                 contentAlignment = Alignment.Center,
             ) {
                 Icon(
                     imageVector = SurferIcons.Add,
                     contentDescription = SurferSemantics.Decorative,
                     tint = AppTheme.materialColors.onSurfaceVariant,
                 )
             }
             Column(modifier = Modifier.weight(1f)) {
                 Text(
                     text = title,
                     style = AppTheme.typography.titleMedium,
                     color = AppTheme.materialColors.onSurface,
                 )
                 Text(
                     text = subtitle,
                     style = AppTheme.typography.bodySmall,
                     color = AppTheme.materialColors.onSurfaceVariant,
                 )
             }
         }
     }
 }
 
 @Composable
 private fun RowBody(
     name: String,
     subtitle: String,
     selected: Boolean,
     showActions: Boolean,
     enabled: Boolean,
     editLabel: String?,
     membersLabel: String?,
     onEditClick: () -> Unit,
     onMembersClick: () -> Unit,
 ) {
     Row(
         modifier = Modifier.fillMaxWidth(),
         verticalAlignment = Alignment.Top,
         horizontalArrangement = Arrangement.spacedBy(14.dp),
     ) {
         WorkspaceIconBubble(name = name)
         Column(
             modifier = Modifier.weight(1f),
             verticalArrangement = Arrangement.spacedBy(2.dp),
         ) {
             Text(
                 text = name,
                 style = AppTheme.typography.titleMedium,
                 color = AppTheme.materialColors.onSurface,
                 maxLines = 1,
                 overflow = TextOverflow.Ellipsis,
             )
             Text(
                 text = subtitle,
                 style = AppTheme.typography.bodySmall,
                 color = AppTheme.materialColors.onSurfaceVariant,
                 maxLines = 2,
                 overflow = TextOverflow.Ellipsis,
             )
             if (showActions) {
                 Spacer(Modifier.height(6.dp))
                 Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
                     if (editLabel != null) {
                         SurferOutlinedChip(
                             label = editLabel,
                             icon = SurferIcons.Edit,
                             onClick = onEditClick,
                             enabled = enabled,
                         )
                     }
                     if (membersLabel != null) {
                         SurferOutlinedChip(
                             label = membersLabel,
                             icon = SurferIcons.People,
                             onClick = onMembersClick,
                             enabled = enabled,
                         )
                     }
                 }
             }
         }
         RadioIndicator(selected = selected, modifier = Modifier.padding(top = 12.dp))
     }
 }
 
 @Composable
 private fun WorkspaceIconBubble(name: String) {
     val initial = name.firstOrNull()?.uppercaseChar()?.toString().orEmpty()
     Box(
         modifier = Modifier
             .size(IconSize)
             .clip(IconCorner)
             .background(AppTheme.materialColors.surfaceContainerHighest),
         contentAlignment = Alignment.Center,
     ) {
         Text(
             text = initial,
             style = AppTheme.typography.titleMedium.copy(fontWeight = FontWeight.Medium),
             color = AppTheme.materialColors.onSurface,
         )
     }
 }
 
 @Composable
 private fun RadioIndicator(selected: Boolean, modifier: Modifier = Modifier) {
     val primary = AppTheme.materialColors.primary
     val outline = AppTheme.materialColors.outline
     val surface = AppTheme.materialColors.surface
     Box(
         modifier = modifier
             .size(24.dp)
             .clip(CircleShape)
             .then(
                 if (selected) {
                     Modifier.background(primary)
                 } else {
                     Modifier.border(2.dp, outline, CircleShape)
                 },
             ),
         contentAlignment = Alignment.Center,
     ) {
         if (selected) {
             Box(
                 modifier = Modifier
                     .size(10.dp)
                     .clip(CircleShape)
                     .background(surface),
             )
         }
     }
 }
 
 @Preview
 @Composable
 private fun SurferWorkspaceRowPreview() {
     SurferComponentPreview {
         Column(
             verticalArrangement = Arrangement.spacedBy(AppTheme.spacing.default),
             modifier = Modifier.padding(16.dp),
         ) {
             SurferWorkspaceRow(
                 name = "Family",
                 subtitle = "Household budget",
                 selected = true,
                 enabled = true,
                 showActions = true,
                 editLabel = "Edit",
                 membersLabel = "Members",
                 onClick = {},
                 onEditClick = {},
                 onMembersClick = {},
             )
             SurferWorkspaceRow(
                 name = "Family",
                 subtitle = "Selected without actions",
                 selected = true,
                 enabled = true,
                 onClick = {},
             )
             SurferWorkspaceRow(
                 name = "Lisbon trip",
                 subtitle = "Apr 12 – Apr 22",
                 selected = false,
                 enabled = true,
                 onClick = {},
             )
             SurferCreateWorkspaceRow(
                 title = "New workspace",
                 subtitle = "For a trip, side project, or anything",
                 onClick = {},
             )
         }
     }
 }