Blocks
Crypto Swap
A token-swap screen with pay and receive cards, a flip toggle, fee details and a slide-to-confirm action.
9:41
8
Swap
You Pay52.34 BNBMax
BBNB0.01
≈ 6,247.70 USD
⇅
You Receive187.52 USDT
TUSDT6.7345108344
≈ 28,197.64 USD
🔥 Fee: 0.255851 USDT
1 BNB = 673.45108 (198,98 USD)
Slide to Swap›››
Installation
caveui components are copy-paste Jetpack Compose built entirely on Material 3 — there's no caveui dependency to add. Make sure Material 3 is on your classpath (it ships with the Compose BOM), then copy the Usage snippet below into your project.
kotlin
// build.gradle.kts (module)
dependencies {
implementation(platform("androidx.compose:compose-bom:2025.06.00"))
implementation("androidx.compose.material3:material3")
}Usage
kotlin
data class Token(val symbol: String, val amount: String, val usd: String)
@Composable
fun SwapScreen(pay: Token, receive: Token, fee: String, onSwap: () -> Unit) {
Column(
Modifier.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f))
.padding(16.dp),
) {
Text("Swap", Modifier.fillMaxWidth(), textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold)
Spacer(Modifier.height(12.dp))
TokenCard("You Pay", pay)
Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
Surface(shape = CircleShape, color = MaterialTheme.colorScheme.background,
modifier = Modifier.size(36.dp).offset(y = (-8).dp)) {
Box(contentAlignment = Alignment.Center) {
Icon(Icons.Filled.SwapVert, "Flip")
}
}
}
TokenCard("You Receive", receive)
Spacer(Modifier.height(8.dp))
Text("Fee: $fee", Modifier.fillMaxWidth(), textAlign = TextAlign.Center,
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant)
Spacer(Modifier.weight(1f))
Surface(color = MaterialTheme.colorScheme.onBackground, shape = CircleShape,
modifier = Modifier.fillMaxWidth().clickable { onSwap() }) {
Row(Modifier.padding(6.dp), verticalAlignment = Alignment.CenterVertically) {
Surface(shape = CircleShape, color = MaterialTheme.colorScheme.background,
modifier = Modifier.size(36.dp)) {
Box(contentAlignment = Alignment.Center) { Icon(Icons.Filled.Check, null) }
}
Text("Slide to Swap", Modifier.weight(1f), textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.background, fontWeight = FontWeight.SemiBold)
}
}
}
}
@Composable
private fun TokenCard(label: String, token: Token) {
Surface(color = MaterialTheme.colorScheme.background, shape = RoundedCornerShape(16.dp),
modifier = Modifier.fillMaxWidth()) {
Column(Modifier.padding(16.dp)) {
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Text(label, style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant)
Text("${token.amount} ${token.symbol}",
style = MaterialTheme.typography.labelMedium)
}
Text(token.usd, Modifier.padding(top = 8.dp),
style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold)
}
}
}