{
  "name": "VoicePlayer",
  "package": "@magicblocksai/ui",
  "file": "packages/ui/src/components/VoicePlayer.tsx",
  "chapterTag": "26 Embed Extras",
  "chapter": "26-embed-extras.html",
  "sectionId": "voice-player",
  "elName": "Compact",
  "demoUrl": "https://brand.magicblocks.ai/components/26-embed-extras#voice-player",
  "hasLiveDemo": false,
  "description": "`<VoicePlayer>` — audio playback chrome for voice agents.",
  "useClient": true,
  "interactivity": "interactive",
  "namedExports": [
    {
      "name": "VoicePlayer",
      "isPrincipal": true,
      "isType": false
    },
    {
      "name": "VoicePlayerProps",
      "isPrincipal": false,
      "isType": true
    },
    {
      "name": "VoicePlayerVariant",
      "isPrincipal": false,
      "isType": true
    }
  ],
  "importStatement": "import { VoicePlayer } from \"@magicblocksai/ui\";",
  "props": [
    {
      "name": "src",
      "optional": true,
      "type": "string",
      "doc": "Audio source URL (mp3 / wav / ogg). Optional — the player renders chrome without a source so demos work without media."
    },
    {
      "name": "durationMs",
      "optional": true,
      "type": "number",
      "doc": "Total duration in milliseconds, used for the time readout before metadata loads. Falls back to `HTMLMediaElement.duration` once decoded."
    },
    {
      "name": "autoplay",
      "optional": true,
      "type": "boolean",
      "doc": "Begin playback on mount. Defaults to `false`; honours `prefers-reduced-motion` — if the user prefers reduced motion the flag is ignored at runtime."
    },
    {
      "name": "playing",
      "optional": true,
      "type": "boolean",
      "doc": "Controlled playback state. Pair with `onPlayingChange` to drive the player from outside."
    },
    {
      "name": "onPlayingChange",
      "optional": true,
      "type": "(playing: boolean) => void",
      "doc": "Fires whenever play / pause toggles, controlled or not."
    },
    {
      "name": "onTimeUpdate",
      "optional": true,
      "type": "(ms: number) => void",
      "doc": "Fires roughly every animation frame while playing. Throttled internally via `requestAnimationFrame`; safe to call `setState` in the handler."
    },
    {
      "name": "transcript",
      "optional": true,
      "type": "string",
      "doc": "Optional plain-text transcript of the audio. When the user toggles the Transcript button, the transcript is revealed underneath the player chrome. The button uses `aria-pressed` to signal its toggled state to assistive tech."
    },
    {
      "name": "variant",
      "optional": true,
      "type": "VoicePlayerVariant",
      "doc": "Compact for in-bubble use; expanded for trace timelines (adds a scrubbable axis above the waveform). Defaults to `\"compact\"`."
    },
    {
      "name": "className",
      "optional": true,
      "type": "string",
      "doc": "Class merged via the kit's `cn()` helper. Caller wins over defaults."
    }
  ],
  "classesUsed": [
    "voice-player",
    "voice-player-axis",
    "voice-player-axis-input",
    "voice-player-row",
    "voice-player-scrubber",
    "voice-player-scrubber-fill",
    "voice-player-time",
    "voice-player-toggle",
    "voice-player-transcript",
    "voice-player-transcript-toggle",
    "voice-player-wave"
  ],
  "examples": {
    "react": "<VoicePlayer\n  src=\"/audio/agent-response-0042.mp3\"\n  durationMs={64_000}\n  transcript=\"Yes, I can help with that. Let me pull up your account.\"\n/>",
    "html": "<div class=\"voice-player\" data-variant=\"compact\"><audio preload=\"metadata\"></audio><div class=\"voice-player-row\"><button type=\"button\" class=\"voice-player-toggle\" aria-label=\"Play\" aria-pressed=\"false\"><svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M8 5v14l11-7z\"></path></svg></button><div class=\"voice-player-scrubber\" style=\"--vp:0\" aria-hidden=\"true\"><div class=\"voice-player-scrubber-fill\" style=\"width:0%\"></div></div><svg class=\"voice-player-wave\" viewBox=\"0 0 240 32\" preserveAspectRatio=\"none\" aria-hidden=\"true\"><g fill=\"currentColor\"><rect x=\"0\" y=\"11\" width=\"2\" height=\"10\" rx=\"1\"></rect><rect x=\"6\" y=\"7\" width=\"2\" height=\"18\" rx=\"1\"></rect><rect x=\"12\" y=\"4\" width=\"2\" height=\"24\" rx=\"1\"></rect><rect x=\"18\" y=\"9\" width=\"2\" height=\"14\" rx=\"1\"></rect><rect x=\"24\" y=\"3\" width=\"2\" height=\"26\" rx=\"1\"></rect><rect x=\"30\" y=\"7\" width=\"2\" height=\"18\" rx=\"1\"></rect><rect x=\"36\" y=\"5\" width=\"2\" height=\"22\" rx=\"1\"></rect><rect x=\"42\" y=\"11\" width=\"2\" height=\"10\" rx=\"1\"></rect><rect x=\"48\" y=\"9\" width=\"2\" height=\"14\" rx=\"1\"></rect><rect x=\"54\" y=\"4\" width=\"2\" height=\"24\" rx=\"1\"></rect><rect x=\"60\" y=\"7\" width=\"2\" height=\"18\" rx=\"1\"></rect><rect x=\"66\" y=\"5\" width=\"2\" height=\"22\" rx=\"1\"></rect><rect x=\"72\" y=\"11\" width=\"2\" height=\"10\" rx=\"1\"></rect><rect x=\"78\" y=\"3\" width=\"2\" height=\"26\" rx=\"1\"></rect><rect x=\"84\" y=\"7\" width=\"2\" height=\"18\" rx=\"1\"></rect><rect x=\"90\" y=\"9\" width=\"2\" height=\"14\" rx=\"1\"></rect><rect x=\"96\" y=\"5\" width=\"2\" height=\"22\" rx=\"1\"></rect><rect x=\"102\" y=\"11\" width=\"2\" height=\"10\" rx=\"1\"></rect><rect x=\"108\" y=\"7\" width=\"2\" height=\"18\" rx=\"1\"></rect><rect x=\"114\" y=\"3\" width=\"2\" height=\"26\" rx=\"1\"></rect><rect x=\"120\" y=\"9\" width=\"2\" height=\"14\" rx=\"1\"></rect><rect x=\"126\" y=\"5\" width=\"2\" height=\"22\" rx=\"1\"></rect><rect x=\"132\" y=\"11\" width=\"2\" height=\"10\" rx=\"1\"></rect><rect x=\"138\" y=\"7\" width=\"2\" height=\"18\" rx=\"1\"></rect><rect x=\"144\" y=\"3\" width=\"2\" height=\"26\" rx=\"1\"></rect><rect x=\"150\" y=\"9\" width=\"2\" height=\"14\" rx=\"1\"></rect><rect x=\"156\" y=\"7\" width=\"2\" height=\"18\" rx=\"1\"></rect><rect x=\"162\" y=\"11\" width=\"2\" height=\"10\" rx=\"1\"></rect><rect x=\"168\" y=\"5\" width=\"2\" height=\"22\" rx=\"1\"></rect><rect x=\"174\" y=\"9\" width=\"2\" height=\"14\" rx=\"1\"></rect><rect x=\"180\" y=\"3\" width=\"2\" height=\"26\" rx=\"1\"></rect><rect x=\"186\" y=\"7\" width=\"2\" height=\"18\" rx=\"1\"></rect><rect x=\"192\" y=\"11\" width=\"2\" height=\"10\" rx=\"1\"></rect><rect x=\"198\" y=\"5\" width=\"2\" height=\"22\" rx=\"1\"></rect><rect x=\"204\" y=\"9\" width=\"2\" height=\"14\" rx=\"1\"></rect><rect x=\"210\" y=\"3\" width=\"2\" height=\"26\" rx=\"1\"></rect><rect x=\"216\" y=\"7\" width=\"2\" height=\"18\" rx=\"1\"></rect><rect x=\"222\" y=\"11\" width=\"2\" height=\"10\" rx=\"1\"></rect><rect x=\"228\" y=\"9\" width=\"2\" height=\"14\" rx=\"1\"></rect><rect x=\"234\" y=\"5\" width=\"2\" height=\"22\" rx=\"1\"></rect></g></svg><span class=\"voice-player-time\">0:00 / 1:04</span><button type=\"button\" class=\"voice-player-transcript-toggle\" aria-pressed=\"false\">Transcript</button></div><p class=\"voice-player-transcript\" hidden=\"\">Yes, I can help with that. Let me pull up your account.</p></div>",
    "css": ".voice-player {\n  display: flex;\n  flex-direction: column;\n  gap: var(--s-2);\n  padding: var(--s-3);\n  border: 1px solid var(--hair);\n  border-radius: var(--r-md);\n  background: var(--bg-paper);\n  font: 400 13px/1.4 var(--f-body);\n}\n\n.voice-player-axis { width: 100%; }\n\n.voice-player-axis-input {\n  flex: 1;\n  width: 100%;\n  margin: 0;\n  height: 24px;\n  accent-color: var(--accent);\n  cursor: pointer;\n}\n\n.voice-player-row { display: flex; align-items: center; gap: var(--s-3); }\n\n.voice-player-scrubber { flex: 1; min-width: 0; height: 4px; background: var(--bg-sunk); border-radius: 999px; position: relative; }\n\n.voice-player-scrubber-fill { height: 100%; background: var(--accent); border-radius: 999px; }\n\n.voice-player-time { font: 500 12px/1 var(--f-mono); color: var(--fg-dim); min-width: 56px; }\n\n.voice-player-toggle {\n  width: 36px; height: 36px;\n  display: inline-flex; align-items: center; justify-content: center;\n  border-radius: 50%;\n  background: var(--accent);\n  color: var(--on-accent);\n  border: 0;\n  cursor: pointer;\n  flex-shrink: 0;\n}\n\n.voice-player-transcript {\n  margin: 0; padding: var(--s-2) var(--s-3);\n  background: var(--bg-sunk); border-radius: var(--r-sm);\n  font: 400 13px/1.5 var(--f-body); color: var(--fg);\n}\n\n.voice-player-transcript-toggle {\n  display: inline-flex; align-items: center; gap: 4px;\n  font: 500 12px/1 var(--f-body); color: var(--fg-soft);\n  background: transparent; border: 0; cursor: pointer;\n  padding: 8px; min-height: 32px;\n}\n\n.voice-player-wave { height: 32px; width: 100%; color: var(--accent); opacity: 0.6; }"
  }
}
