Skip to main content

AudioPlayer

Implemented

Inline audio player — custom compact/expanded UI with play/pause, seek via keyboard (Space, ←→ ±5s, ↑↓ volume), and an error fallback alert. No pointer scrubbing yet (slider is keyboard-only). Autoplay is guarded by prefers-reduced-motion and gesture-blocked autoplay currently surfaces as the error state (tracked).

Categorymolecules
Sourcepatterns/molecules/audioplayer.html
AI HintInline audio previews (event media, interview clips). Do not set autoplay without the reduced-motion guard; drive error stories with a genuinely broken src, not autoplay rejection. The play CTA uses interactive tokens — do not swap in a brand token (3.08:1 fails AA).

Inline audio player with custom play control and progress UI.

AudioPlayer

Media & playback — molecule

Inline audio player with custom play control and progress UI.

Audio progress
0:00 / 0:00

Opening keynote

Main hall

Opening keynote progress
0:00 / 0:00
Audio progress
0:00 / 0:00

Usage

AudioPlayer is self-managing: give it a real src and an accessible label, and it handles play state, timing and the error fallback itself. The compact layout shows the play button, progress track and timecode; any of title / artist / artwork switches it to the expanded layout.

import { AudioPlayer } from '@epasslive/design-system'

// Compact
<AudioPlayer src="/track.mp3" label="Interview" />

// Expanded (title/artist/artwork)
<AudioPlayer
  src="/keynote.mp3"
  label="Opening keynote"
  title="Opening keynote"
  artist="Main hall"
  artwork="/artwork.jpg"
/>

Keyboard

KeyAction
SpaceToggle play / pause (container focused)
←Seek back 5 seconds
→Seek forward 5 seconds
↑Volume up (+0.1)
↓Volume down (−0.1)

Honest notes (current limitations)

  • Seeking is keyboard-only today. Focus the player and press ← / → (±5 s). The progress track has no pointer or touch interaction yet — mouse users cannot scrub. Pointer seeking is planned via the DS Slider molecule.
  • Volume is keyboard-only. ↑ / ↓ adjust volume; there is no visible volume control or mute button yet.
  • Do not set autoplay. Playback is suppressed when the user prefers reduced motion, and a browser that blocks ungestured autoplay currently surfaces the error alert even for healthy audio (known defect — NotAllowedError is not distinguished from real media errors yet). No demo or story here uses autoplay.
  • The error fallback reflects genuine media failures. The third preview above uses a 404 source on purpose so the inline role="alert" fallback renders for the right reason.
  • No captions/transcript support yet (WCAG 1.2.1 for audio-only content is the consumer's responsibility today).

Props

Prop
Type
Default
Description
src*
string
—

Audio source URL, passed straight to the native <audio> element (HTTPS or data URI).

label*
string
—

Accessible name for the player region; prefixes the Play/Pause button labels ("Play {label}").

title
string
—

Track title. Providing title, artist or artwork switches to the expanded layout.

artist
string
—

Track artist line, shown under the title in the expanded layout.

artwork
string
—

Square cover image URL (rendered 48×48, decorative — empty alt).

autoplay
boolean
—

Attempt playback on mount. Suppressed when the user prefers reduced motion. Default false.

loop
boolean
—

Replay from the start when the track ends. Default false.

className
string
—

Additional classes on the root element.

id
string
—

Stable root id; falls back to an SSR-safe useId() value.

Props

Preview

AudioPlayer

Prop
Type
Required
Default
Description
src
string
Required
—

Audio source URL.

title
string
Optional
—

Track title (expanded variant).

artist
string
Optional
—

Artist line (expanded variant).

artwork
string
Optional
—

Artwork image URL (expanded variant).

autoplay
boolean
Optional
false

Attempt playback on mount — guarded by prefers-reduced-motion; note gesture-blocked autoplay currently renders the error state.

loop
boolean
Optional
false

Loop the track when it ends.

label
string
Required
—

Accessible name for the player — feeds the Play/Pause aria-labels and the progress slider's name.

className
string
Optional
—

Additional CSS classes.

id
string
Optional
—

Stable root id.

Quick use:<AudioPlayer />

Accessibility

ARIA roleapplication

ARIA

2 rules

WCAG 4.1.2

root carries role='application'; the slider exposes aria-valuenow/min/max and an accessible name (`{label} progress`); play/pause button is aria-labelled `Play {label}` / `Pause {label}`

WCAG 4.1.3

playback failure renders an inline role='alert' error message (currently also fires for gesture-blocked autoplay)

Usage

Import

tsxSnippet
import { AudioPlayer } from "@epasslive/design-system"

Example 1

tsxSnippet
<AudioPlayer src="/media/interview.mp3" label="Interview" />

Example 2

tsxSnippet
<AudioPlayer src={url} label={track.name} title={track.name} artist={track.artist} artwork={track.cover} />

Anti-patterns

— Do not set autoplay without accounting for gesture-blocked playback — it currently renders the error state

— Do not promise pointer scrubbing — seeking is keyboard-only until the slider interaction lands

Design System v4.1.0 | ePassLive