package com.peachpasswords.ui.vault import androidx.compose.animation.animateColorAsState import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box 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.layout.statusBarsPadding import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Check import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.peachpasswords.ui.theme.LocalPeachAccent import com.peachpasswords.ui.theme.peachColors import com.peachpasswords.ui.theme.PeachType /** * D12 multi-select per-row checkbox (spec §9). 20dp circle: unchecked = 1dp t2 * border on a transparent fill; checked = accent fill with a white check. */ @Composable fun MultiSelectCheckbox(checked: Boolean, modifier: Modifier = Modifier) { val accent = LocalPeachAccent.current val fill by animateColorAsState( targetValue = if (checked) accent else Color.Transparent, label = "checkbox-fill", ) Box( modifier = modifier .size(20.dp) .clip(CircleShape) .background(fill) .then( if (checked) Modifier else Modifier.border(1.dp, peachColors.T2, CircleShape), ), contentAlignment = Alignment.Center, ) { if (checked) { Icon( Icons.Rounded.Check, contentDescription = "selected", tint = Color.White, modifier = Modifier.size(13.dp), ) } } } /** * D12 multi-select top bar (spec §9). Replaces the wordmark/icons row while * [com.peachpasswords.ui.vault.VaultListViewModel.isMultiSelectMode] is on: * "[N] selected" + a breach-colored Delete + a t2 Cancel. */ @Composable fun MultiSelectTopBar( count: Int, onDelete: () -> Unit, onCancel: () -> Unit, ) { Row( modifier = Modifier .fillMaxWidth() .statusBarsPadding() .height(56.dp) .padding(horizontal = 16.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = "$count selected", color = peachColors.T0, style = PeachType.bodyMono.copy(fontSize = 13.sp), ) Row(verticalAlignment = Alignment.CenterVertically) { Text( text = "Delete", color = if (count > 0) peachColors.Breach else peachColors.T2, style = PeachType.labelMono.copy(fontSize = 11.sp), modifier = Modifier .clip(RoundedCornerShape(4.dp)) .clickable(enabled = count > 0, onClick = onDelete) .padding(horizontal = 8.dp, vertical = 6.dp), ) Spacer(Modifier.width(8.dp)) Text( text = "Cancel", color = peachColors.T2, style = PeachType.labelMono.copy(fontSize = 11.sp), modifier = Modifier .clip(RoundedCornerShape(4.dp)) .clickable(onClick = onCancel) .padding(horizontal = 8.dp, vertical = 6.dp), ) } } }