VoiceRecord
voice-recordPresents hold-to-talk or tap-to-toggle recording controls with waveform and processing states.
Usage
Basic usage (press and hold to speak)
Default pressAndHold: press to start recording, release to end and enter processing, iOS gesture interruption (pointercancel) can also release correctly.
Hold to talk
tsx
const [status, setStatus] = useState<VoiceRecordStatus>("idle");
const [levels, setLevels] = useState<number[]>([]); // Microphone analyzer feeds 0-1 waveform
<VoiceRecord
status={status}
levels={levels}
onPress={() => setStatus("recording")}
onRelease={() => setStatus("processing")}
/>Click to switch modes
pressAndHold={false} Click Start/Click End again, and onToggle will transfer automatically after receiving the current status.
Click to speak
tsx
<VoiceRecord
status={status}
levels={levels}
pressAndHold={false}
onToggle={(s) => (s === "idle" ? start() : stop())}
/>Dimensions
sm / md / lg three levels, icons and labels scale with the level.
Hold to talk
Hold to talk
Hold to talk
tsx
<>
<VoiceRecord size="sm" />
<VoiceRecord size="md" />
<VoiceRecord size="lg" />
</>VoiceRecord
Voice recording trigger whose status drives its visual feedback.
States
| Status | Effect | Click behavior |
|---|---|---|
| idle | Default microphone icon | Calls onToggle to start recording. |
| recording | Pulsing halo, waveform, and compact danger button | Calls onToggle to stop. |
| processing | Spinner | No response. |
| disabled | Muted and noninteractive | No response. |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| status | "idle" | "recording" | "processing" | "disabled" | "idle" | Current status |
| onToggle | (status) => void | — | Called from idle or recording with the current status. |
| levels | number[] | [] | Waveform levels from 0–1; an empty array hides the waveform. |
| size | "sm" | "md" | "lg" | "md" | Button size. |
| labelIdle | string | "\u6309\u4f4f\u8bf4\u8bdd" | Idle-state label; the built-in Chinese copy means “Hold to speak.” |
| labelRecording | string | "\u677e\u5f00\u7ed3\u675f" | Recording-state label; the built-in Chinese copy means “Release to finish.” |
| labelProcessing | string | "\u5904\u7406\u4e2d\u2026" | Processing-state label; the built-in Chinese copy means “Processing…”. |
Usage
tsx
<VoiceRecord
status={phase === "recording" ? "recording" : phase === "processing" ? "processing" : "idle"}
levels={audioLevels}
onToggle={(s) => s === "idle" ? onStart() : onStop()}
/>Playground
Press and hold to speak
<VoiceRecord status="idle" size="md" />