Skip to content
ComposerDictation buttonMenu

Dictation button

Microphone button with permission, listening with live level bars, transcribing and a blocked state that says how to fix it. Backed by useChatcnDictation.

A simulated session: permission, live levels, transcribing.

Installation

$ pnpm dlx shadcn@latest add https://chatcn.dev/r/dictation-button.json

Usage

tsx
import { DictationButton } from "@/components/ui/chatcn/dictation-button"
import { useChatcnDictation } from "@/hooks/use-chatcn-dictation"

const dictation = useChatcnDictation({
  onTranscript: (text) => setValue((v) => (v ? `${v} ${text}` : text)),
})

<DictationButton
  status={dictation.status}
  level={dictation.level}
  error={dictation.error}
  onStart={dictation.start}
  onStop={dictation.stop}
/>

The button takes plain props, so it works with any recognizer: pass status and a level from 0 to 1 from your own service. useChatcnDictation wraps the browser's Web Speech API, adds a Web Audio level meter and reports supported: false where the API is missing.

Examples

States

Idle, requesting, listening, transcribing and blocked.

Live

The real Web Speech API through useChatcnDictation.

Props

PropTypeNotes
status"idle" | "requesting" | "listening" | "transcribing" | "error"
levelnumber0 to 1 while listening
errorDictationErrornot-allowed, audio-capture, no-speech, network, unsupported, unknown
errorMessageReactNodeOverride the fix hint
onStart, onStop() => voidStop also cancels a pending permission prompt
size"sm" | "md"28 or 32 px, 44 px on touch

useChatcnDictation

ReturnsNotes
status, error, supportedState, last error, Web Speech availability
transcript, interimTranscriptSettled and in-progress text
levelAbout 20 updates a second from an AnalyserNode. Turn off with meter: false
start, stop, cancel, toggleStop delivers onTranscript; cancel drops what was heard

Accessibility

  • aria-pressed while listening; the name follows the state: Dictate, Cancel dictation, Stop dictation, Transcribing.
  • A polite live region says Waiting for microphone permission, Listening and Transcribing.
  • Errors open a hint beside the button with a title, how to fix it and Try again. It does not steal focus from the composer.

Motion

  • States crossfade in one footprint with the 150 ms blur swap.
  • Bars scale on the Y axis with a 100 ms linear transition, each with its own weight and jitter so speech reads as speech.
  • Under reduced motion the bars hold still at half height: the state shows, the movement goes.