MultiSelectUi.kt

4.2 KB · raw

1package com.peachpasswords.ui.vault23import androidx.compose.animation.animateColorAsState4import androidx.compose.foundation.background5import androidx.compose.foundation.border6import androidx.compose.foundation.clickable7import androidx.compose.foundation.layout.Arrangement8import androidx.compose.foundation.layout.Box9import androidx.compose.foundation.layout.Row10import androidx.compose.foundation.layout.Spacer11import androidx.compose.foundation.layout.fillMaxWidth12import androidx.compose.foundation.layout.height13import androidx.compose.foundation.layout.padding14import androidx.compose.foundation.layout.size15import androidx.compose.foundation.layout.statusBarsPadding16import androidx.compose.foundation.layout.width17import androidx.compose.foundation.shape.CircleShape18import androidx.compose.foundation.shape.RoundedCornerShape19import androidx.compose.material.icons.Icons20import androidx.compose.material.icons.rounded.Check21import androidx.compose.material3.Icon22import androidx.compose.material3.Text23import androidx.compose.runtime.Composable24import androidx.compose.runtime.getValue25import androidx.compose.ui.Alignment26import androidx.compose.ui.Modifier27import androidx.compose.ui.draw.clip28import androidx.compose.ui.graphics.Color29import androidx.compose.ui.unit.dp30import androidx.compose.ui.unit.sp31import com.peachpasswords.ui.theme.LocalPeachAccent32import com.peachpasswords.ui.theme.peachColors33import com.peachpasswords.ui.theme.PeachType3435/**36 * D12 multi-select per-row checkbox (spec §9). 20dp circle: unchecked = 1dp t237 * border on a transparent fill; checked = accent fill with a white check.38 */39@Composable40fun MultiSelectCheckbox(checked: Boolean, modifier: Modifier = Modifier) {41    val accent = LocalPeachAccent.current42    val fill by animateColorAsState(43        targetValue = if (checked) accent else Color.Transparent,44        label = "checkbox-fill",45    )46    Box(47        modifier = modifier48            .size(20.dp)49            .clip(CircleShape)50            .background(fill)51            .then(52                if (checked) Modifier53                else Modifier.border(1.dp, peachColors.T2, CircleShape),54            ),55        contentAlignment = Alignment.Center,56    ) {57        if (checked) {58            Icon(59                Icons.Rounded.Check,60                contentDescription = "selected",61                tint = Color.White,62                modifier = Modifier.size(13.dp),63            )64        }65    }66}6768/**69 * D12 multi-select top bar (spec §9). Replaces the wordmark/icons row while70 * [com.peachpasswords.ui.vault.VaultListViewModel.isMultiSelectMode] is on:71 * "[N] selected" + a breach-colored Delete + a t2 Cancel.72 */73@Composable74fun MultiSelectTopBar(75    count: Int,76    onDelete: () -> Unit,77    onCancel: () -> Unit,78    includeStatusBarPadding: Boolean = true,79) {80    Row(81        modifier = Modifier82            .fillMaxWidth()83            .then(if (includeStatusBarPadding) Modifier.statusBarsPadding() else Modifier)84            .height(56.dp)85            .padding(horizontal = 16.dp),86        verticalAlignment = Alignment.CenterVertically,87        horizontalArrangement = Arrangement.SpaceBetween,88    ) {89        Text(90            text = "$count selected",91            color = peachColors.T0,92            style = PeachType.bodyMono.copy(fontSize = 13.sp),93        )94        Row(verticalAlignment = Alignment.CenterVertically) {95            Text(96                text = "Delete",97                color = if (count > 0) peachColors.Breach else peachColors.T2,98                style = PeachType.labelMono.copy(fontSize = 11.sp),99                modifier = Modifier100                    .clip(RoundedCornerShape(4.dp))101                    .clickable(enabled = count > 0, onClick = onDelete)102                    .padding(horizontal = 8.dp, vertical = 6.dp),103            )104            Spacer(Modifier.width(8.dp))105            Text(106                text = "Cancel",107                color = peachColors.T2,108                style = PeachType.labelMono.copy(fontSize = 11.sp),109                modifier = Modifier110                    .clip(RoundedCornerShape(4.dp))111                    .clickable(onClick = onCancel)112                    .padding(horizontal = 8.dp, vertical = 6.dp),113            )114        }115    }116}