TranscriptSync
StableA recording's transcript that follows playback. Press a line to play from there.
Also known as synced transcript, interactive transcript
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
Support call with its recording
Support call, 3 October, 14:02
Press a line to play from there.
<TranscriptSync
audio={{ title: "Call with Maya Okafor", subtitle: "Support call, 3 October, 14:02", duration: 192, peaks, markers }}
speakers={{
maya: { label: "Maya Okafor" },
assistant: { label: "Support assistant", ai: true },
dev: { label: "Dev Raman" },
}}
lines={[
{ id: "l1", speaker: "assistant", start: 0, clock: "14:02:10", text: "Hello, this is the Halden Home support assistant. I am an AI. How can I help today?" },
{ id: "l2", speaker: "maya", start: 7, clock: "14:02:17", text: "Hi. My kettle order was meant to arrive on Monday and it still has not come." },
// ...
{ id: "l8", speaker: "assistant", start: 66, text: "The courier now expects Thursday. I can also send a new kettle today...", status: "interrupted", spokenUpTo: 71 },
// ...
]}
/>Pass audio and the part wires in its own player. Press Play and the current line follows; press any line to jump. The assistant was cut off at 1:06, so the rest of that line is marked Not spoken.
When to use it
Lets someone read a call and listen to any part of it, so a reviewer can check what was really said.
Made of: Player (optional) · Hint · Back to current line · Line button · Speaker mark · Speaker name · Time and clock · Now tag · Text · Not spoken part
Use it for
- Reviewing a support call handled by a voice agent, including the hand-over to a person.
- Checking a generated voice-over against its script.
- Any recording where people need to find a moment by reading.
Not for
- Captions of a live conversation: use VoicePanel.
- A text chat: use MessageList.
- Audio with no transcript: use AudioPlayer.
Do and avoid
Press a line to play from there.
Press a line to play from there.
Do
- Show both the time from the start and the wall-clock time for calls, so reviewers can match logs.
- Mark speech that was never played as Not spoken.
- Keep the player above the transcript, so it stays in reach while reading.
Avoid
- Don't colour a person's lines with the AI colour, or the current line. The AI colour is only on the AI speaker's mark.
- Don't announce each line as it plays. People read the list when they want to.
- Don't scroll the page to follow the line. Only the list scrolls, and only until the person scrolls it.
On a phone
- It fills the width and the list scrolls inside itself, so the player stays put above it.
- Each line is a full-width button at least 44px tall.
- Scrolling the list stops it following; Back to current line, 44px tall on touch screens, brings it back.
- Speaker, time and the Now tag wrap onto two lines when space is short.
Seen in products
- Vapi call logs show each transcript line with the wall-clock time and the offset from the call start, and selecting a line jumps the recording to it.
- Zoom offers a full transcript side panel with Save Transcript.
- Zoom's own guides say automatic captions do not meet the accuracy needed for full accessibility.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| linesrequired | TranscriptLine[] | none | Each line: id, speaker, start in seconds, text, and optional end, clock, status ("final" | "interrupted" | "redacted") and spokenUpTo. |
| speakersrequired | Record<string, { label: string; ai?: boolean }> | none | Who is who. ai lines get the AI mark; people stay neutral. |
| audio | Omit<AudioPlayerProps, "current" | "onTimeChange"> | none | Wires in a player above the list. The part then keeps the time itself. |
| current | number | none | Playback position in seconds, when your own player keeps it. |
| onSeek | (seconds: number) => void | none | Called with a line's start when it is pressed. |
| label | string | "Transcript" | Name of the transcript region. |
| loading | boolean | false | Shows placeholder lines. |
| emptyText | string | "There is no transcript for this recording." | Shown when there are no lines. |
| listClassName | string | none | Classes for the scrolling list, for example a different max height. |
| className | string | none | Extra classes on the wrapper. |
"Show code under the preview gives the code for the example on the stage."
In Figma
In Figma, one TranscriptSync switches all of this from its properties panel, across 2 variants. Each property sets the React prop beside it, so design and code use the same names.
| Figma property | React | Values |
|---|---|---|
| Loading | loading | On or off |
Tokens
Change one of these and every part that uses it follows.
--fg--fg-muted--fg-subtle--surface--surface-sunken--border--lime--on-lime--dur-fast--text-compact--text-small
Built in
- The list is a section named by label. Every line is a button; pressing it seeks to the line's start.
- The current line has aria-current, a bar on its left, a tint and the visible word Now, so it never depends on colour.
- Speaker names are text. AI speakers also get a hidden "(AI)" after the name, and the AI mark is decorative.
- Words that were not spoken are struck through and preceded by hidden text "Not spoken:", with a visible Not spoken tag.
- Following stops when the person scrolls the current line out of view, and Back to current line brings it back. It scrolls only the list, never the page.
- Nothing in the list is announced while playing. Loading is announced once through a status region.
- Highlight changes take --dur-fast; there is no other motion.
What you need to do
- Name every speaker in speakers, and set ai on the ones that are AI.
- Mark lines the assistant did not finish saying with status interrupted and spokenUpTo, so the record matches what was played.
- Hide card numbers and codes in the text before passing it, and set status redacted.
- Automatic transcripts make mistakes. Where the transcript becomes a record, give people a way to flag errors.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide