Cards
Cardsanimated

Multi Metric Grid

A two-by-two grid of small KPIs reveals with a soft stagger.

Visits
24.5k
Signups
1,820
Bounce
32%
Avg Time
3m 12s

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
@Composable
fun MultiMetricGridCard() {
  data class M(val label: String, val value: String)
  val items = listOf(
    M("Visits", "24.5k"),
    M("Signups", "1,820"),
    M("Bounce", "32%"),
    M("Avg Time", "3m 12s"),
  )
  Card(
    shape = RoundedCornerShape(20.dp),
    modifier = Modifier.width(260.dp),
  ) {
    Column(Modifier.padding(16.dp)) {
      items.chunked(2).forEach { row ->
        Row(
          Modifier.fillMaxWidth(),
          horizontalArrangement = Arrangement.spacedBy(12.dp),
        ) {
          row.forEachIndexed { i, m ->
            val a = remember { Animatable(0f) }
            LaunchedEffect(Unit) {
              delay(i * 120L)
              a.animateTo(1f, tween(500))
            }
            Surface(
              shape = RoundedCornerShape(12.dp),
              color = MaterialTheme.colorScheme.surfaceVariant
                .copy(alpha = 0.5f),
              modifier = Modifier
                .weight(1f)
                .graphicsLayer { alpha = a.value },
            ) {
              Column(Modifier.padding(12.dp)) {
                Text(
                  text = m.label,
                  style = MaterialTheme.typography.labelSmall,
                  color = MaterialTheme.colorScheme.onSurfaceVariant,
                )
                Text(
                  text = m.value,
                  fontWeight = FontWeight.Bold,
                )
              }
            }
          }
        }
        Spacer(Modifier.height(12.dp))
      }
    }
  }
}