Transcript

A scrollable list of transcript lines bound to a Player. The active line tracks playback and clicking a time stamp seeks to it.

Anatomy

Transcript consumes the playback context from Player. A source part (PlayerAudio or PlayerVideo) feeds the media, and the transcript registers its items so the current time can be matched against each line's range.

TSX

The Player parts (PlayPause, Progress, Volume, Waveform) and the transcript live in the same root, so a custom control bar slots in next to the list without any extra wiring.

API

Reference for each part of the component, including its available props and behavior.

Transcript

The list root. Consumes usePlayer to derive the active item from the current playback time, registers items so order doesn't have to match the JSX order, and exposes autoScroll so the list can follow the playhead.

Prop

TranscriptContent

The scroll viewport. Sized to fill the remaining space and scrolls vertically. Use the render prop to swap in a custom scroll area without changing the rest of the tree.

TSX

Auto-scroll uses scrollIntoView with block: "nearest", so it walks up to the nearest scrollable ancestor on its own. The swapped element keeps owning overflow and the active line still glides into view.

Prop

TranscriptList

Container for the items. A simple flex column with a small gap and a touch of padding. Trade it for any layout when needed.

Prop

TranscriptItem

A single line. Takes the line's start time, and optionally an end. Sets data-active when the current playback position falls inside the line. Items register themselves on mount, so the order in the JSX does not need to match the order in time.

Prop

TranscriptSpeaker

Label for who is speaking. A small text block above or beside the line. Omit it for single-voice transcripts.

Prop

TranscriptText

The line itself. Muted by default, switches to the foreground color when the parent item is active so the eye can scan the current line at a glance.

For live transcription, pass interim while the text is still arriving from the recognizer. The line renders in italic with a softer color so the user can tell it might still rewrite, then settles to a normal line once interim flips off.

TSX
Prop

TranscriptWord

Per-word progress for transcripts with word-level timing. Each word reads currentTime from the player and exposes two attributes: data-played when the playhead has reached or passed the word, and data-active while the playhead sits inside its range. The default styling tracks progress: words start muted and brighten to the foreground color as they're spoken. Drop it inside TranscriptText whenever the transcript source carries per-word timestamps (ElevenLabs Scribe, Whisper word-level, AssemblyAI, and so on).

Override the className to switch to a karaoke-style background highlight if that fits the design better, for example data-active:bg-primary data-active:text-primary-foreground.

TSX

A long transcript becomes a lot of subscribing components. For multi-minute audio with hundreds of words, consider splitting by segment so only the visible words re-render on each tick.

Prop

TranscriptTime

The clickable timestamp. Reads the start time from the parent item and the duration from the player. Click calls jumpTo(start). Pass format to render a custom label and render to swap the underlying element.

Prop

useTranscript

Hook for reading transcript state from a child of Transcript. Returns activeId, autoScroll, and setAutoScroll. For playback state and controls, use usePlayer instead, since the two concerns are intentionally split.