Skip to main content

Common Examples

The component has three states, discriminated on state. The host owns all voice state and transport; VoiceModeFab renders the control and reports presses.

Collapsed

idle is a plain dark circle — voice is available but not running. active is the same circle with a blue presence glow, meaning Atlas is listening. Both take a single onPress.

Expanded

The control strip: a status label plus mic-mute, stop, and collapse. Those three are required — each appears in every frame of the design, and an absent handler would render a control that looks live and does nothing. A speaker control is available on top, and renders only when the isSpeakerMuted / onToggleSpeakerMuted pair is wired — they are optional as a unit, never half-set.
Wiring onToggleSpeakerMuted adds the Atlas-audio control:
onStop and onCollapse are not interchangeable. Collapsing returns to active with voice still running; stopping ends voice mode entirely. The two controls sit next to each other in the strip, so wiring them to the same handler is an easy mistake with very different consequences for the user.
label is caller-supplied so the host can localize it and reflect its own state (“Talking”, “Listening”, …). The kit owns only the action names.

Accessibility

  • Every control is a button with an explicit accessible name.
  • The collapsed control’s name changes with state — “Start voice mode” when idle, “Voice mode controls” when active. The glow is purely visual, so the name is the only signal a screen-reader user gets.
  • The mute controls carry their state in their name (“Mute microphone” / “Unmute microphone”) rather than a checked state — the two together would contradict, announcing an unmuted mic as “Mute microphone, not selected”.
  • Each mute control also shows its state visually: the glyph crosses out and its tint turns critical, so a muted channel is not announced-only.
  • Built-in action labels are English until the kit gains an i18n layer; label is already caller-supplied.
Last modified on September 10, 2026