Voice input

Push-to-talk that transcribes on device: the mic is the variant's key, a waveform drawn in the variant, then the transcript with Use and Retry.

Mock· scripted answersNo model runs in a browser, so every answer here is scripted. On a phone it comes from the model.
  • Apple Foundation Models: supported
  • Gemini Nano: not supported
  • Llama (not yet supported): not supported
  • A cloud model: not supported
  • iPhone only for now (Apple SpeechAnalyzer). The app passes in the recorder (for example expo-audio); without one nothing is recorded.

Install

npx ondai add voice-input

Usage

import { VoiceInput, type Recorder } from '@/components/ondai/voice-input'

// Audio capture is yours to provide (expo-audio, react-native-audio-record, your own module).
const recorder: Recorder = {
  start: () => audio.start(),
  stop: () => audio.stop(), // resolves WAV/PCM bytes
  onLevel: (cb) => audio.subscribeLevel(cb),
}

<VoiceInput recorder={recorder} presentation="pill" visual="bars" onTranscript={(text) => setQuery(text)} />
  • Transcription runs on device through useTranscribe (Apple SpeechAnalyzer on iOS 26). Without a recorder a simulated one runs, so the mock and the playground work out of the box.
  • mode="hold" is push-to-talk; mode="tap" toggles. visual is bars (a rippling waveform) or glow (a bloom rising from the bottom edge).

Customize

Every AI component takes the same look and customization props, so it fits your app rather than ours.

<VoiceInput
  variant="pop"
  tint="#FF5A5F"
  size="lg"
  radius={12}
  icons={{ mic: Search, stop: null }}
  labels={{ holdHint: '…', tapHint: '…' }}
/>
PropWhat it does
variantThe look of the whole component: clean, minimal, glass, pop, candy, metal, shine
sizesm, md, lg; type, rows, icons and keys scale together
tintAny colour; the variant paints its keys, tiles and glow in it
radiusCorner radius of the container
iconsReplace any icon (a lucide component, an element, or null to hide it): mic, stop, unavailable, retry, use
labelsEvery visible and spoken string; defaults are exported as voiceInputLabels: holdHint, tapHint, listening, transcribing, releaseToStop, tapToStop, prompt, voice, transcript, use, retry, unavailable, error, start, stop, holding, unavailableKey
SlotsDraw a part yourself: renderMic, renderTranscript, renderActions
stylesStyle any named part

Variants

PropOptions
variantclean, minimal, glass, pop, candy, metal, shine
presentationpill, card
visualbars, glow
sizesm, md, lg

Fallback

When no provider is ready the component renders the unavailable state (AvailabilityGate copy) and, where a deterministic path exists, keeps working without the model.

Eval score

No model-driven fixtures for this component.

Files

Registry dependencies: button, shimmer-text, streaming-text, surface

npm dependencies: @ondai/core, @ondai/tokens, expo-haptics, lucide-react-native, react-native-reanimated, react-native-svg

On this page