Voice Picker

PreviousNext

Searchable voice selector with audio preview, orb visualization, and ElevenLabs voice integration.

Installation

pnpm dlx @elevenlabs/agents-cli@latest components add voice-picker

Usage

import { VoicePicker } from "@/components/ui/voice-picker"

Basic Usage

import { ElevenLabs } from "@elevenlabs/elevenlabs-js"
 
const voices: ElevenLabs.Voice[] = [
  {
    voice_id: "21m00Tcm4TlvDq8ikWAM",
    name: "Rachel",
    preview_url: "https://example.com/rachel-preview.mp3",
    // ... other voice properties
  },
  // ... more voices
]
 
const [selectedVoice, setSelectedVoice] = useState("")
 
<VoicePicker
  voices={voices}
  value={selectedVoice}
  onValueChange={setSelectedVoice}
/>

Controlled vs Uncontrolled

{
  /* Controlled */
}
;<VoicePicker
  voices={voices}
  value={selectedVoice}
  onValueChange={setSelectedVoice}
/>
 
{
  /* Uncontrolled */
}
;<VoicePicker
  voices={voices}
  onValueChange={(voiceId) => console.log("Selected:", voiceId)}
/>

Control Open State

const [open, setOpen] = useState(false)
 
<VoicePicker
  voices={voices}
  open={open}
  onOpenChange={setOpen}
  value={selectedVoice}
  onValueChange={setSelectedVoice}
/>

Custom Placeholder

<VoicePicker
  voices={voices}
  placeholder="Choose your voice..."
  value={selectedVoice}
  onValueChange={setSelectedVoice}
/>

Fetching Voices from ElevenLabs API

import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js"
 
const [voices, setVoices] = useState<ElevenLabs.Voice[]>([])
 
useEffect(() => {
  const client = new ElevenLabsClient({
    apiKey: process.env.ELEVENLABS_API_KEY,
  })
 
  client.voices.getAll().then((response) => {
    setVoices(response.voices)
  })
}, [])
 
<VoicePicker
  voices={voices}
  value={selectedVoice}
  onValueChange={setSelectedVoice}
/>

API Reference

VoicePicker

A searchable dropdown for selecting ElevenLabs voices with audio preview and orb visualization.

Props

PropTypeDefaultDescription
voicesElevenLabs.Voice[]-Required. Array of ElevenLabs voices
valuestring-Selected voice ID (controlled)
onValueChange(value: string) => void-Callback when selection changes
placeholderstring"Select a voice..."Placeholder text when no voice selected
classNamestring-Optional CSS classes for the trigger button
openboolean-Control popover open state
onOpenChange(open: boolean) => void-Callback when popover open state changes

Features

  • Search Functionality: Filter voices by name with built-in search
  • Audio Preview: Play voice samples with play/pause controls
  • Orb Visualization: Visual representation of each voice with the Orb component
  • Keyboard Navigation: Full keyboard support for accessibility
  • Controlled/Uncontrolled: Supports both controlled and uncontrolled patterns
  • ElevenLabs Integration: Works seamlessly with ElevenLabs Voice API
  • Audio Player: Integrated audio playback with shared state management

Notes

  • Built on top of Command, Popover, and AudioPlayer components
  • Requires @elevenlabs/elevenlabs-js for ElevenLabs Voice types
  • Each voice displays with an Orb visualization and preview audio
  • Audio playback is managed by AudioPlayerProvider for consistent state
  • Search is case-insensitive and filters by voice name
  • Supports both controlled (value/onValueChange) and uncontrolled modes
  • Open state can be controlled externally via open/onOpenChange props
  • Keyboard accessible with standard combobox patterns
  • Preview URLs from ElevenLabs Voice objects are used for audio playback