Merge pull request #1835 from vitorpamplona/claude/add-swipe-delete-cancel-QjI5b

Add cancel button to swipe-to-delete confirmation UI
This commit is contained in:
Vitor Pamplona
2026-03-13 20:42:43 -04:00
committed by GitHub
@@ -27,9 +27,11 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@@ -110,10 +112,16 @@ fun SwipeToDeleteWithConfirmation(
state = dismissState, state = dismissState,
modifier = modifier, modifier = modifier,
backgroundContent = { backgroundContent = {
ConfirmDeleteBackground(dismissState) { ConfirmDeleteBackground(
onDelete() dismissState = dismissState,
scope.launch { dismissState.reset() } onConfirmDelete = {
} onDelete()
scope.launch { dismissState.reset() }
},
onCancel = {
scope.launch { dismissState.reset() }
},
)
}, },
enableDismissFromEndToStart = true, enableDismissFromEndToStart = true,
content = content, content = content,
@@ -165,6 +173,7 @@ fun DismissBackground(dismissState: SwipeToDismissBoxState) {
fun ConfirmDeleteBackground( fun ConfirmDeleteBackground(
dismissState: SwipeToDismissBoxState, dismissState: SwipeToDismissBoxState,
onConfirmDelete: () -> Unit, onConfirmDelete: () -> Unit,
onCancel: () -> Unit,
) { ) {
val settled = dismissState.currentValue == Settled && dismissState.targetValue == Settled val settled = dismissState.currentValue == Settled && dismissState.targetValue == Settled
@@ -189,23 +198,51 @@ fun ConfirmDeleteBackground(
Modifier Modifier
.fillMaxSize() .fillMaxSize()
.background(color) .background(color)
.clickable(enabled = !settled) { onConfirmDelete() }
.padding(20.dp, 8.dp), .padding(20.dp, 8.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
) { ) {
Icon( Row(
Icons.Default.Delete, modifier =
contentDescription = stringRes(id = R.string.request_deletion), Modifier
) .weight(1f)
Text( .fillMaxHeight()
text = stringRes(id = R.string.request_deletion), .clickable(enabled = !settled) { onConfirmDelete() },
color = Color.White, verticalAlignment = Alignment.CenterVertically,
style = MaterialTheme.typography.titleMedium, horizontalArrangement = Arrangement.Center,
) ) {
Icon( Icon(
Icons.Default.Delete, Icons.Default.Delete,
contentDescription = stringRes(id = R.string.request_deletion), contentDescription = stringRes(id = R.string.request_deletion),
) tint = Color.White,
)
Spacer(modifier = Modifier.padding(horizontal = 4.dp))
Text(
text = stringRes(id = R.string.request_deletion),
color = Color.White,
style = MaterialTheme.typography.titleMedium,
)
}
Row(
modifier =
Modifier
.weight(1f)
.fillMaxHeight()
.clickable(enabled = !settled) { onCancel() },
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
) {
Icon(
Icons.Default.Close,
contentDescription = stringRes(id = R.string.cancel),
tint = Color.White,
)
Spacer(modifier = Modifier.padding(horizontal = 4.dp))
Text(
text = stringRes(id = R.string.cancel),
color = Color.White,
style = MaterialTheme.typography.titleMedium,
)
}
} }
} }