Skip to content
kitn AI/UI

Voice Input

kai-voice-input

A self-contained mic button that records audio, hands the Blob to your transcription function, and fires the result — plug in any speech-to-text backend to get voice dictation.

  • Shadow DOM
  • 2 events
  • Function-property pattern
  • Framework agnostic
  • Disableable

Assign your transcribe function to the element and listen for kai-transcription:

<kai-voice-input id="voice"></kai-voice-input>
<script type="module">
import '@kitn.ai/ui/elements';
await customElements.whenDefined('kai-voice-input');
const voice = document.getElementById('voice');
voice.transcribe = async (blob) => {
const form = new FormData();
form.append('audio', blob, 'recording.webm');
const res = await fetch('/api/transcribe', { method: 'POST', body: form });
return (await res.json()).text;
};
voice.addEventListener('kai-transcription', (e) => {
document.getElementById('prompt').value = e.detail.text;
});
</script>
  • transcribe — assign an async (blob: Blob) => Promise<string> function once the element is in the DOM.
  • To handle audio yourself, skip transcribe and listen for kai-audio-captured instead; it fires { blob } immediately after recording stops.
  • disabled prevents interaction while the assistant is streaming or mic access is pending.

Without a transcribe property the raw audio is still emitted via kai-audio-captured.

PropertyTypeDefaultNotes
theme'auto'Color mode (`auto` follows prefers-color-scheme).
transcribeTranscriber the host supplies: records audio, returns the text. This is a **function-valued property** (`el.transcribe = async blob => '...'`) because a value-returning callback can't be modelled as a fire-and-forget event.
disabledfalseDisable the mic button (non-interactive).
recognitionLangBCP-47 language tag for the native `SpeechRecognition` path (e.g. `en-US`). Attribute: `recognition-lang` (the plain `lang` attribute is reserved by `HTMLElement` and can't be a custom-element property). No effect when `transcribe` is set or the browser lacks SpeechRecognition.
interimfalseEmit live partial transcripts (`kai-transcript-interim`) during native recognition. Attribute: `interim`. No-op on the transcribe/fallback paths.
EventDetailNotes
Raw audio captured (before transcription), for hosts that prefer to handle transcription themselves instead of via the `transcribe` property. Also the unsupported-fallback signal: no `transcribe`, no SpeechRecognition, so only the blob is produced (no text).
Recording started or stopped. Lets the host drive its own UI (waveform, push-to-talk indicator) in sync with the mic. Fires on real transitions only (manual click and programmatic start()/stop()), never on mount.
Live partial transcript during native recognition (only when `interim` is set). Fires repeatedly before the final `kai-transcription`.
Final transcript: the `transcribe` property resolved, OR native `SpeechRecognition` produced final text (no `transcribe` set).
MethodSignatureNotes
(): voidBegin recording programmatically (e.g. push-to-talk bound to a global key). Runs the same getUserMedia path as clicking the mic; no-ops if already recording.
(): voidStop the in-progress recording, producing the blob (→ kai-audio-captured) and running transcription. Pairs with start() for push-to-talk.

This element wraps these SolidJS components — reach for them directly when you need finer control than the props expose.

VoiceInput