Prodular UI

Waveform

Pro

A recording drawn as mirrored bars, with a playhead you can drag and an optional color per bar for each speaker.

npx prodular-ui add waveform

Part of Prodular UI Pro. Preview and read the docs freely, install with a license. See pricing

Player

Press play, or click, drag or use the arrow keys on the bars to move through the recording.

Voicemail from Daniel Reyes

Tidewater Freight, accounts payable. Today at 9:12

0:11

Colored by speaker

Each bar in the color of whoever was talking. Without progress there is no playhead and every bar is drawn in full.

  • Maya Okafor
  • Daniel Reyes

Anatomy

<Waveform  values={levels}  progress={currentTime / duration}  duration={duration}  onSeek={(p) => (audio.currentTime = p * duration)}  label="Voicemail from Daniel Reyes"/>

Guidance

Use it when

  • Use it for recordings people review: calls, voicemails, meetings, voice notes.
  • Color bars by speaker when the question is who said what, and keep the same color in the Transcript and the legend.
  • Pair it with a play button and the elapsed time. The waveform shows where you are, not whether it is playing.

Avoid

  • Live microphone levels. Use VoiceLevels from Voice input for that.
  • Drawing fake bars for a recording you have not analysed. Show a skeleton until the levels are ready.
  • More colors than speakers, or colors that mean something other than who is talking.

Rules for AI agents

Published in llms-full.txt, the registry and the MCP server, so coding agents follow them when they build with this component.

  • Pass values computed from the audio: one peak or RMS value per bar, scaled to 0 to 1. Downsample long recordings to 80 to 200 bars. On narrow screens the waveform merges neighbouring bars itself, keeping the loudest, so pass the full set.
  • Pass progress as currentTime / duration on every timeupdate, and duration in seconds so the slider announces the time.
  • Pass onSeek to make it seekable, and set audio.currentTime = progress * duration inside it. Without onSeek it is an image, so give it a label that says what was recorded.
  • For speaker colors use chart tokens such as var(--chart-1), never raw hex, and reuse each speaker's color in TranscriptTurn color.

API

Waveform

PropTypeDefaultDescription
valuesnumber[]One value from 0 to 1 per bar.
progressnumberHow much has played, 0 to 1. Leave it out for no playhead.
colors(string | null)[]A CSS color per bar, for example var(--chart-1). Missing entries use the foreground.
durationnumberSeconds. Sets the spoken value and a 5 second arrow key step.
onSeek(progress: number) => voidMakes it a slider: click, drag, arrows, Page Up and Down, Home and End.
labelstring"Recording"Accessible name.

Installation

The Prodular UI CLI adds the source to components/ui with everything it depends on. In a project that already uses shadcn/ui, the shadcn CLI installs it from the Prodular registry too. See Installation for the first setup.

npx prodular-ui add waveform# or, with the registry in components.jsonnpx shadcn@latest add @prodular/waveform