

<Preview name="SpeechInputDefaultExample" />

## Overview [#overview]

`SpeechInput` renders a standalone microphone button that captures voice input and returns transcript text through `onTranscriptionChange`.

It uses the browser Web Speech API when available. Use `onInterimTranscriptionChange` to preview provisional speech before the browser commits a final transcript chunk. If recording stops while interim text is visible, `SpeechInput` commits that latest interim text through `onTranscriptionChange`. When Web Speech is unavailable, it can record audio with `MediaRecorder` if you provide `onAudioRecorded` to send the audio blob to your transcription service.

Use `PromptInputSpeechButton` from `PromptInput` when you want dictation wired directly into a prompt composer.

## Usage [#usage]

```tsx
import { SpeechInput } from "@tilt-legal/cubitt-components/chat-elements";
```

## Examples [#examples]

### Default [#default]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="SpeechInputDefaultExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    <SpeechInput
      aria-label="Record voice prompt"
      onAudioRecorded={async (blob) => transcribe(blob)}
      onInterimTranscriptionChange={(text) => setInterimTranscript(text)}
      onTranscriptionChange={(text) => {
        setTranscript((current) => (current ? `${current} ${text}` : text));
        setInterimTranscript("");
      }}
    />
    ```
  </Tab>
</Tabs>

### Disabled [#disabled]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="SpeechInputDisabledExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    <SpeechInput aria-label="Record voice prompt" disabled />
    ```
  </Tab>
</Tabs>

## API Reference [#api-reference]

### SpeechInput [#speechinput]

Standalone microphone button for voice capture. Extends all Button props, including `aria-label`, `disabled`, `size`, `variant`, and `className`.

| Prop                           | Type                                   | Default   | Description                                                                                        |
| ------------------------------ | -------------------------------------- | --------- | -------------------------------------------------------------------------------------------------- |
| `onTranscriptionChange`        | `(text: string) => void`               | -         | Called when final transcript text is available.                                                    |
| `onInterimTranscriptionChange` | `(text: string) => void`               | -         | Called with provisional transcript text from the Web Speech API, and with `""` when it is cleared. |
| `onAudioRecorded`              | `(audioBlob: Blob) => Promise<string>` | -         | MediaRecorder fallback callback. Return transcribed text to forward it to `onTranscriptionChange`. |
| `lang`                         | `string`                               | `"en-US"` | Language code passed to the Web Speech recognition instance.                                       |
| `variant`                      | `ButtonProps["variant"]`               | `"ghost"` | Button variant for the resting microphone button.                                                  |
| `className`                    | `string`                               | -         | Additional CSS classes for the underlying Button.                                                  |

The button disables itself when no speech input mode is available, while MediaRecorder fallback requires `onAudioRecorded`.
