┌───────────────────────────────────────────────────────────┐ │ 📄 shadcn/directory/elevenlabs/ui/components/voice-button │ └───────────────────────────────────────────────────────────┘
╔══════════════════════════════════════════════════════════════════════════════════════════════╗
║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
<ComponentPreview name="voice-button-demo" description="A beautiful button for voice and audio interactions" />
npx @elevenlabs/cli@latest components add voice-button
</TabsContent>
<TabsContent value="manual">
<Steps>
<Step>Copy and paste the following code into your project.</Step>
<ComponentSource name="voice-button" title="components/ui/voice-button.tsx" /><Step>Update the import paths to match your project setup.</Step>
</Steps> </TabsContent> </CodeTabs>import { VoiceButton } from "@/components/ui/voice-button"
const [state, setState] = useState<"idle" | "recording" | "processing">("idle")
<VoiceButton
state={state}
onPress={() => {
if (state === "idle") {
setState("recording")
} else {
setState("processing")
}
}}
/>
<VoiceButton
state="idle"
label="Press to speak"
trailing="⌥Space"
onPress={() => console.log("Button pressed")}
/>
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" />
</>
)
import { MicIcon } from "lucide-react"
import { VoiceButton } from "@/components/ui/voice-button"
export default () => <VoiceButton state="idle" size="icon" icon={<MicIcon />} />
<VoiceButton
state="recording"
variant="default"
size="lg"
className="w-full"
waveformClassName="bg-primary/10"
/>
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} />
}
A button component with multiple states for voice recording workflows, including live waveform visualization.
| Prop | Type | Default | Description |
| ----------------- | ----------------------------------------------------------------------------- | ----------- | ------------------------------------------------- |
| state | "idle" \| "recording" \| "processing" \| "success" \| "error" | "idle" | Current state of the voice button |
| onPress | () => void | - | Callback when button is clicked |
| label | ReactNode | - | Content to display on the left side |
| trailing | ReactNode | - | Content to display on the right (e.g., shortcuts) |
| icon | ReactNode | - | Icon to display when idle (for icon size buttons) |
| variant | "default" \| "destructive" \| "outline" \| "secondary" \| "ghost" \| "link" | "outline" | Button variant |
| size | "default" \| "sm" \| "lg" \| "icon" | "default" | Button size |
| className | string | - | Optional CSS classes for the button |
| waveformClassName | string | - | Optional CSS classes for the waveform container |
| feedbackDuration | number | 1500 | Duration in ms to show success/error states |
| ...props | HTMLButtonElement | - | All standard button element props |
type VoiceButtonState =
| "idle"
| "recording"
| "processing"
| "success"
| "error"
feedbackDuration║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
╚══════════════════════════════════════════════════════════════════════════════════════════════╝