Search for a command to run...
A compound audio player for blob and URL sources. Compose a play control, title, metadata (duration, size, date), an optional scrubber, and download/remove actions from a shared `Root`. Drives self-contained playback by default, or hands control to a parent coordinator so a list can guarantee a single active preview.
Root owns the <audio> element, playback state, and source metadata; the parts read it through context. Compose only the pieces a surface needs — a compact list row uses a single Row, a full player stacks a title Row above a PlayButton + Scrubber Row.
Hayden preview
Generated preview
May 30, 2026
Training sample
May 30, 2026
AudioPlayer.RootProvides context and (when uncontrolled) mounts the <audio> element. Renders a flex flex-col container.
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | "" | Audio source (blob or URL). |
variant | "card" | "bare" | "card" | card adds a rounded bg-surface-secondary surface; bare is unstyled for nesting. |
durationSeconds | number | — | Known length; fallback for Meta/Scrubber until <audio> metadata loads. |
fileSize | number | — | Size in bytes. Auto-detected from src (HEAD request / blob) when omitted. |
date | string | — | Pre-formatted date string, surfaced via the "date" meta field. |
downloadFileName | string | — | Default filename for DownloadButton; extension added when missing. |
controller | AudioPlaybackController | — | Hand playback to a parent. When set, Root does not mount its own <audio> and seeking is off. |
className | string | — | Forwarded to the container. |
| Component | Notes |
|---|---|
AudioPlayer.Row | Horizontal flex items-center gap-3 group. Use one per visual line. |
AudioPlayer.Info | flex-1 column wrapper for title + meta (keeps them truncating and left-aligned). |
AudioPlayer.Title | Truncating title text. Pass a custom node directly inside Info for animated titles. |
AudioPlayer.Meta | fields: AudioMetaField[] — pick and order "duration", "size", "date". Crossfades on change. |
AudioPlayer.PlayButton | Play / pause / loading control. Disabled while a controller reports loading or has no source. |
AudioPlayer.Scrubber | Current time + seek slider + duration. Seeking is disabled in controlled mode. |
AudioPlayer.DownloadButton | Ghost download control. Optional fileName overrides Root's downloadFileName. |
AudioPlayer.RemoveButton | Ghost trash control. Requires onRemove; optional aria-label (defaults to "Remove"). |
Compose explicitly. A list row is a Root with one Row; a full player adds a second Row
for the PlayButton + Scrubber. The markup documents the layout.
Use a controller when several rows share one preview source, so only one plays at a time.
Pair it with variant="bare" when nesting inside an existing card.
Put surface-specific actions (delete, rename) in the Row alongside DownloadButton /
RemoveButton rather than as a sibling outside the player.
Render Scrubber in controlled mode and expect seeking — a coordinated preview has no local
<audio> to seek. Use a compact row instead.
Reach for raw <audio> or a bespoke play button. Every audio preview in the product composes
these parts so playback, a11y, and metadata stay consistent.