Usage
AudioPlayer from @prepared911/ui-audio-player is the minimal, inline player used everywhere dispatch surfaces audio: call records in a row, evidence in a drawer, voice notes in a timeline. It's a play/pause cluster with an optional scrub slider, timestamps, and skip controls—not a full media player. The mental model is "the fastest path from 'see a clip' to 'hear the clip'".
Under the hood it wraps a small state machine around <audio>; callers supply the source URL (or an async resolver), volume and speed defaults, and whether to show timestamps or skip buttons. The cluster stays compact so it slots into row heights and condensed panels without reflow.
Use AudioPlayer in DataTable cells or compact list rows where operators click to sample a clip without leaving the list. Keep it in-row so the review context—caller, timestamp, outcome—stays visible alongside playback.
Drawers that expose evidence, training clips, or caller-side audio should host AudioPlayer in the body. Combine with DataList entries for metadata; the player's compact footprint leaves room for text context above and below.
For one-to-three-minute clips—voicemails, call snippets, short recordings—the slim control is ideal. Users scrub, listen, and move on without the cognitive overhead of a full player.
WaveformPlayer instead.AudioPlayer; it's for deliberate review.AudioPlayer has no video surface; use a product-owned video component.AudioPlayer exposes a handful of slots and props:
src as URL or async resolver (for short-lived signed URLs). Handle loading and error states explicitly when using a resolver.showSkipButtons adds ±15s skips; showTimeStamps shows current and total duration; showSlider (on by default) exposes the scrub slider.play, pause, seekTo, and getCurrentTime, so callers can pair multiple players or sync with an external transcript.mm:ss for clips under an hour, hh:mm:ss past that. Stay consistent with the rest of the page; don't mix relative and absolute formats.If src is a promise, the player should render the cluster in a disabled, "loading" state while the URL resolves, then enable controls. A failed resolve shows an inline message and disables play; don't leave the user guessing.
When the underlying <audio> errors, render an inline error instead of surfacing browser default messaging. If the error is transient (network), offer a retry that re-invokes the source resolver.
In views where multiple players may appear (call list, timeline), pause siblings on play. The shared controller pattern is to lift active-player state into context and have each player observe it.
For dispatch workflows that may run on restricted networks, show a clear message when the CDN is unreachable. The cluster should gracefully degrade—timestamps visible, scrub disabled—rather than vanish.
Do
Don't
IconButton play/pause with visible tooltip titles, keyboard-operable slider, and inline error announcements keep AudioPlayer usable with screen readers and keyboards. See the Accessibility page for labeling patterns, live-region decisions, and multi-player focus order.
On this page