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-inputUsage
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 arecordera simulated one runs, so the mock and the playground work out of the box. mode="hold"is push-to-talk;mode="tap"toggles.visualisbars(a rippling waveform) orglow(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: '…' }}
/>| Prop | What it does |
|---|---|
variant | The look of the whole component: clean, minimal, glass, pop, candy, metal, shine |
size | sm, md, lg; type, rows, icons and keys scale together |
tint | Any colour; the variant paints its keys, tiles and glow in it |
radius | Corner radius of the container |
icons | Replace any icon (a lucide component, an element, or null to hide it): mic, stop, unavailable, retry, use |
labels | Every 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 |
| Slots | Draw a part yourself: renderMic, renderTranscript, renderActions |
styles | Style any named part |
Variants
| Prop | Options |
|---|---|
variant | clean, minimal, glass, pop, candy, metal, shine |
presentation | pill, card |
visual | bars, glow |
size | sm, 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











