Features
- State Management: Five distinct states (idle, recording, processing, success, error)
- Live Waveform: Displays real-time audio visualization during recording
- Automatic Transitions: Success/error states auto-transition back to idle
- Keyboard Shortcuts: Display keyboard shortcuts in the trailing slot
- Flexible Layouts: Supports label/trailing content or icon-only mode
- Customizable Feedback: Configurable duration for success/error states
- Accessibility: Proper ARIA labels and button semantics
Usage
import { VoiceButton } from "@/components/ui/voice-button";
Basic Usage
const [state, setState] = useState<"idle" | "recording" | "processing">("idle")
<VoiceButton
state={state}
onPress={() => {
if (state === "idle") {
setState("recording")
} else {
setState("processing")
}
}}
/>
With Label and Keyboard Shortcut
<VoiceButton
state="idle"
label="Press to speak"
trailing="⌥Space"
onPress={() => console.log("Button pressed")}
/>
Different States
import { VoiceButton } from "@/components/ui/voice-button";
export default () => (
<>
{/* Idle state */}
<VoiceButton state="idle" />
{/* Recording with waveform */}
<VoiceButton state="recording" />
{/* Processing */}
<VoiceButton state="processing" />
{/* Success feedback */}
<VoiceButton state="success" />
{/* Error feedback */}
<VoiceButton state="error" />
</>
);
Icon Button
import { MicIcon } from "lucide-react";
import { VoiceButton } from "@/components/ui/voice-button";
export default () => <VoiceButton state="idle" size="icon" icon={<MicIcon />} />;
Custom Styling
<VoiceButton
state="recording"
variant="default"
size="lg"
className="w-full"
waveformClassName="bg-primary/10"
/>
Auto-transitioning States
import { useState } from "react";
import { VoiceButton, type VoiceButtonState } from "@/components/ui/voice-button";
export default () => {
const [state, setState] = useState<VoiceButtonState>("idle");
const handlePress = () => {
if (state === "idle") {
setState("recording");
} else if (state === "recording") {
setState("processing");
// Simulate API call
setTimeout(() => {
setState("success");
// Auto-return to idle after feedback
}, 2000);
}
};
return <VoiceButton state={state} onPress={handlePress} />;
};
