Nasaq
Components

VoiceCallOverlay

Full-screen voice call with an AI agent showing who, how long, a level-driven visualiser, the listening, thinking or speaking state, live captions and mute, captions and hang-up controls.

PreviewOpen ↗

Code

<VoiceCallOverlay  state={state}  level={level}  agent={{ name: "Salma", avatar: "🎧" }}  muted={muted}  onMutedChange={setMuted}  elapsed={seconds}  captions={captions}  onEnd={hangUp}/>

AI Assistant · beta

Live examples and controls: VoiceCallOverlay in the lab.

Install

npx shadcn@latest add https://docs.nasaqui.com/r/voice-call-overlay.json

The UI of a voice call with an agent. It holds no audio: you connect the call and feed it state and level, and act on onEnd and onMutedChange. It never requests the microphone.

When to use

  • A voice agent call screen.
  • VoiceVisualizer alone as an audio level meter.

When not to use

  • Text chat: use CopilotChat.
  • Recording or playing audio files: use a media player.

Import

import { VoiceCallOverlay, voiceLevelFromSamples } from "@fadymondy/nasaq/web";

Quick start

<VoiceCallOverlay
  state={state}
  level={level}
  agent={{ name: "Salma", avatar: "🎧" }}
  muted={muted}
  onMutedChange={setMuted}
  elapsed={seconds}
  captions={captions}
  onEnd={hangUp}
/>

Anatomy

A role="dialog" surface: header (agent mark, name, subtitle, timer), the visualiser and a state word, the last caption lines, and a control bar (mute, captions, end call). The visualiser is a role="meter" of bars driven by a short history of level.

API

PropTypeDescription
state"connecting" | "listening" | "thinking" | "speaking" | "error"Required.
agent{ name, avatar?, subtitle? }Required.
levelnumberLoudness 0 to 1 of the current speaker.
muted, onMutedChangeMicrophone mute (controlled).
onEnd() => void | PromiseHang up. Required.
elapsednumberSeconds since answer.
captions, captionLines, showCaptions, defaultShowCaptions, onShowCaptionsChangeLive captions.
onInterrupt() => voidAdds a Cut in button while speaking.
error, onRetryShown in the error state.
containedbooleanFill the nearest positioned parent instead of the window.
extraControls, labelsExtra buttons; string overrides.

Helpers voiceLevelFromSamples(samples) (float or byte audio samples to a 0 to 1 level) and formatVoiceCallTime(seconds) are re-exported from the component.

Examples

Feeding the level from an analyser

const level = voiceLevelFromSamples(samples);

Accessibility

The state is spoken text, not only motion. Mute and captions are toggle buttons with aria-pressed. The visualiser exposes the level as a meter. With reduced motion the level is quantised and the pulse and transitions are off.

RTL & i18n

  • English and Arabic strings ship and follow the Nasaq locale. Pass labels to override any string.
  • Layout uses logical properties, so it mirrors in right-to-left. The timer stays left-to-right.

Styling & tokens

  • Uses bg-background, the accent token for the speaking bars and the danger token for the end button. Fixed to the window unless contained.

Do / Don't

  • Do ask for microphone permission in your own code, not here.
  • Don't pass raw sample arrays as level; convert them first.

Lab

https://docs.nasaqui.com/?path=/docs/components-ai-assistant-voice-call-overlay--docs

On this page