Voice indicator
Show caller-supplied voice state and audio level.
Preview
Play the reply to see the form follow the audio. Audio player supplies playback state and measured waveform samples. To use this example, replace /audio/voice-response.mp3 with your own audio file.
Design guidance
Use Voice indicator when a voice interaction needs a quiet, visible center: a caller can pair it with a transcript, playback, or session controls. The liquid form gives listening, thinking, and speaking different motion and light. Muted is pale and washed out. Error uses a warm reflection and an uneven outline. Keep a readable state label beside the artwork.
The artwork is decorative. Voice indicator does not start capture, play audio, infer a session state, or announce each level change. Keep microphone permission, speech services, transport, and business status with the caller. Supply input and output levels only when real measurements are available; omit either value when it is not. OS reduced-motion preference always wins. Loading starts with a blurred form that clears after the first rendered frame. If graphics cannot start, a clear still drop and its state text remain visible. A press or tap adds a small visual ripple; it does not trigger an action. Offscreen or hidden artwork releases its graphics scene.
Installation
The Liquid Glass renderer uses React Three Fiber and Three.js; the registry source item includes these dependencies. In a source-distribution host, include the VoiceIndicator source and install @react-three/fiber and three. VoiceIndicator has no audio or AI SDK requirement. The Preview composes AudioPlayer, so install that component too when using the complete example.
Download example files — JSX recipes, demo styles and any sample assets. Install the component first.
Basic usage
Levels are finite normalized values from 0 to 1 and are clamped to that range. A missing or non-finite value is treated as zero. The component does not source measurements or choose a state.
Structures
The root is a native div with forwarded attributes and HTMLDivElement ref. The art is hidden from assistive technology; state and optional label remain readable, and description is connected with aria-describedby. Caller children render after the state text. Keep actions outside the decorative art so there is no nested or implied audio action.
Examples
Voice chat
Keep the transcript beside a smaller orb so people can read while they listen. Start voice replays sample speech events; Stop reply keeps the words already shown. This example does not use a microphone or speech service.
Call bar
Use orientation="horizontal" to put the orb beside its label and state. Keep call controls in the same row, with the current caption below. The bar stays compact in a chat sidebar. It uses the same sample speech events as Voice chat.
Audio levels
Compare input and output levels while you change the voice state. These controls use sample values.
States
Compare Idle, Listening, Thinking, and Speaking.
Connection states
Show connection progress, a stopped reply, a muted microphone, or an error. Muted loses color; Error adds warm light and a gently disrupted shape. Both keep a gentle liquid flow unless reduced motion is requested.
Sizes
Use sm (48px) in a call bar, base (96px) in a panel, lg (160px) beside a transcript, and xl (240px) for a focused voice view. The default is base.
Custom size
Use a number when an existing layout needs a specific size. This assistant panel uses 72px.
Reduced motion
Keep the form still while its state remains clear. The operating-system preference takes priority over this control.
API reference
VoiceIndicatorVoiceIndicator | forwardRef<HTMLDivElement, VoiceIndicatorProps> | — | Native div group with forwarded attributes and ref. |
|---|
state | VoiceIndicatorState | 'idle' | Caller-supplied state: idle, connecting, listening, thinking, speaking, interrupted, muted, or error. |
|---|
inputLevel | number | — | Optional normalized input level from 0 to 1. Finite values are clamped; missing or non-finite values resolve to zero. |
|---|
outputLevel | number | — | Optional normalized output level from 0 to 1. Finite values are clamped; missing or non-finite values resolve to zero. |
|---|
size | VoiceIndicatorSize | 'base' | Artwork size: sm (48px), base (96px), lg (160px), xl (240px), or a custom finite pixel size. Values below 1px resolve to 1px; non-finite numeric values use base. |
|---|
orientation | 'vertical' | 'horizontal' | 'vertical' | Place the label and state below the art, or beside it in a call bar. |
|---|
reducedMotion | boolean | false | Requests the still artwork when true. The operating-system reduced-motion preference always overrides false. |
|---|
label | string | — | Optional visible name associated with the state. |
|---|
description | string | — | Optional visible supporting text, also referenced by aria-describedby. |
|---|
children | React.ReactNode | — | Optional caller-owned content rendered after the state text. |
|---|
VoiceIndicatorState, VoiceIndicatorSize, and VoiceIndicatorProps are exported. The root has no action target or continuous live-region updates. Capture, playback, generated speech, application policy, and session controls remain caller-owned.