Coverage Summary for Class: PreferenceOptionsSheetKt (com.georgeci.moneysurfer.feature.settings.preferences)

Class Class, % Method, % Branch, % Line, % Instruction, %
PreferenceOptionsSheetKt 0% (0/1) 0% (0/6) 0% (0/12) 0% (0/26) 0% (0/381)


 package com.georgeci.moneysurfer.feature.settings.preferences
 
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.heightIn
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.ModalBottomSheet
 import androidx.compose.material3.rememberModalBottomSheetState
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.unit.dp
 import com.georgeci.moneysurfer.uikit.components.SurferBottomSheetContent
 import com.georgeci.moneysurfer.uikit.components.settings.SurferSettingsRadio
 import com.georgeci.moneysurfer.uikit.components.settings.SurferSettingsRow
 import com.georgeci.moneysurfer.uikit.theme.AppTheme
 
 /** One choice in a [PreferenceOptionsSheet]: the value to store and how to write it out. */
 internal data class PreferenceOption<T>(
     val value: T,
     val label: String,
     /** Stable selector for the row, independent of the label — see [PreferencesTestTags]. */
     val tag: String,
 )
 
 private val SHEET_PADDING = 20.dp
 
 /** Caps the list so a nine-region sheet scrolls instead of pushing the title off the screen. */
 private val LIST_MAX_HEIGHT = 420.dp
 
 /**
  * Single-choice chooser for one preference row, in the same modal shape the dashboard card-style
  * sheet uses. Radio rows rather than a dialog: the option sets are short but the sheet reaches the
  * thumb, and it matches the appearance screen's radio idiom.
  *
  * The currency row does not use this — it has its own searchable sheet in `uikit`, because that
  * list is data and keeps growing.
  */
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 internal fun <T> PreferenceOptionsSheet(
     title: String,
     options: List<PreferenceOption<T>>,
     selected: T,
     onSelect: (T) -> Unit,
     onDismiss: () -> Unit,
 ) {
     ModalBottomSheet(
         onDismissRequest = onDismiss,
         sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
         containerColor = AppTheme.materialColors.surfaceContainerLow,
         shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp),
     ) {
         SurferBottomSheetContent(title = title) {
             Column(
                 modifier = Modifier
                     .fillMaxWidth()
                     .heightIn(max = LIST_MAX_HEIGHT)
                     .verticalScroll(rememberScrollState())
                     .padding(horizontal = SHEET_PADDING),
                 verticalArrangement = Arrangement.spacedBy(8.dp),
             ) {
                 options.forEach { option ->
                     SurferSettingsRow(
                         title = option.label,
                         onClick = { onSelect(option.value) },
                         trailing = { SurferSettingsRadio(selected = option.value == selected) },
                         modifier = Modifier.testTag(option.tag),
                     )
                 }
             }
         }
     }
 }