Cards
Cardsanimated

Waveform Scrubber

Audio clip card drawing a waveform with a draggable played and unplayed split.

Voice Memo

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 WaveformScrubber(played: Float) {
  val amps = remember {
    List(28) { (4..36).random().toFloat() }
  }
  Card(
    shape = RoundedCornerShape(18.dp),
    modifier = Modifier.fillMaxWidth(),
  ) {
    Column(Modifier.padding(16.dp)) {
      Text("Voice Memo", style = MaterialTheme.typography.titleSmall)
      Spacer(Modifier.height(12.dp))
      Canvas(
        modifier = Modifier
          .fillMaxWidth()
          .height(44.dp),
      ) {
        val gap = size.width / amps.size
        amps.forEachIndexed { i, a ->
          val x = i * gap + gap / 2
          val on = i.toFloat() / amps.size <= played
          drawLine(
            color = if (on) Color(0xFF22D3EE)
            else Color(0xFF94A3B8),
            start = Offset(x, size.height / 2 - a),
            end = Offset(x, size.height / 2 + a),
            strokeWidth = 4f,
            cap = StrokeCap.Round,
          )
        }
      }
    }
  }
}