• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
drewmcdonald

drewmcdonald

promptCompare

Public
Like
promptCompare
Home
Code
7
.claude
3
backend
2
docs
1
frontend
4
shared
.mcp.json
deno.json
Environment variables
2
Branches
1
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
.claude
/
skills
/
ai-elements
/
references
/
voice-selector.md
Code
/
.claude
/
skills
/
ai-elements
/
references
/
voice-selector.md
Search
…
Viewing readonly version of main branch: v137
View latest version
voice-selector.md

Voice Selector

A composable dialog component for selecting AI voices with metadata display and search functionality.

The VoiceSelector component provides a flexible and composable interface for selecting AI voices. Built on shadcn/ui's Dialog and Command components, it features a searchable voice list with support for metadata display (gender, accent, age), grouping, and customizable layouts. The component includes a context provider for accessing voice selection state from any nested component.

See scripts/voice-selector.tsx for this example.

Installation

npx ai-elements@latest add voice-selector

Features

  • Fully composable architecture with granular control components
  • Built on shadcn/ui Dialog and Command components
  • React Context API for accessing state in nested components
  • Searchable voice list with real-time filtering
  • Support for voice metadata with icons and emojis (gender icons, accent flags, age)
  • Voice preview button with play/pause/loading states
  • Voice grouping with separators and bullet dividers
  • Keyboard navigation support
  • Controlled and uncontrolled component patterns
  • Full TypeScript support with proper types for all components

Props

<VoiceSelector />

Root Dialog component that provides context for all child components. Manages both voice selection and dialog open states.

PropTypeDefaultDescription
valuestring-The selected voice ID (controlled).
defaultValuestring-The default selected voice ID (uncontrolled).
onValueChange`(value: stringundefined) => void`-
defaultOpenbooleanfalseThe default open state (uncontrolled).
openboolean-The open state (controlled).
onOpenChange(open: boolean) => void-Callback fired when the open state changes.
modalbooleantrueWhether the dialog is modal (blocks interaction with the rest of the page).
...propsReact.ComponentProps<typeof Dialog>-Any other props are spread to the Dialog component.

<VoiceSelectorTrigger />

Button or element that opens the voice selector dialog.

PropTypeDefaultDescription
asChildbooleanfalseChange the default rendered element for the one passed as a child, merging their props and behavior.
...propsReact.ComponentProps<typeof DialogTrigger>-Any other props are spread to the DialogTrigger component.

<VoiceSelectorContent />

Container for the Command component and voice list, rendered inside the dialog.

PropTypeDefaultDescription
titleReactNode-The title for screen readers. Hidden visually but accessible to assistive technologies.
classNamestring-Additional CSS classes to apply to the dialog content.
...propsReact.ComponentProps<typeof DialogContent>-Any other props are spread to the DialogContent component.

<VoiceSelectorDialog />

Alternative dialog implementation using CommandDialog for a full-screen command palette style.

PropTypeDefaultDescription
...propsReact.ComponentProps<typeof CommandDialog>-Any other props are spread to the CommandDialog component.

<VoiceSelectorInput />

Search input for filtering voices.

PropTypeDefaultDescription
placeholderstring-Placeholder text for the search input.
classNamestring-Additional CSS classes to apply.
...propsReact.ComponentProps<typeof CommandInput>-Any other props are spread to the CommandInput component.

<VoiceSelectorList />

Scrollable container for voice items and groups.

PropTypeDefaultDescription
...propsReact.ComponentProps<typeof CommandList>-Any other props are spread to the CommandList component.

<VoiceSelectorEmpty />

Message shown when no voices match the search query.

PropTypeDefaultDescription
childrenReactNode-The message to display.
...propsReact.ComponentProps<typeof CommandEmpty>-Any other props are spread to the CommandEmpty component.

<VoiceSelectorGroup />

Groups related voices together with an optional heading.

PropTypeDefaultDescription
headingstring-The heading text for the group.
...propsReact.ComponentProps<typeof CommandGroup>-Any other props are spread to the CommandGroup component.

<VoiceSelectorItem />

Selectable item representing a voice.

PropTypeDefaultDescription
valuestring-The unique identifier for this voice. Used for search filtering.
onSelect(value: string) => void-Callback fired when the voice is selected.
...propsReact.ComponentProps<typeof CommandItem>-Any other props are spread to the CommandItem component.

<VoiceSelectorSeparator />

Visual separator between voice groups.

PropTypeDefaultDescription
...propsReact.ComponentProps<typeof CommandSeparator>-Any other props are spread to the CommandSeparator component.

<VoiceSelectorName />

Displays the voice name with proper styling.

PropTypeDefaultDescription
classNamestring-Additional CSS classes to apply.
...propsReact.ComponentProps<-Any other props are spread to the span element.

<VoiceSelectorGender />

Displays the voice gender metadata with icons from Lucide. Supports multiple gender identities with corresponding icons.

PropTypeDefaultDescription
valueunknown-The gender value that determines which icon to display. Supported values:
classNamestring-Additional CSS classes to apply.
childrenReactNode-Override the icon with custom content.
...propsReact.ComponentProps<-Any other props are spread to the span element.

<VoiceSelectorAccent />

Displays the voice accent metadata with emoji flags representing different countries/regions.

PropTypeDefaultDescription
valueunknown-The accent value that determines which flag emoji to display. Supports 27 different accents including:
classNamestring-Additional CSS classes to apply.
childrenReactNode-Override the flag emoji with custom content.
...propsReact.ComponentProps<-Any other props are spread to the span element.

<VoiceSelectorAge />

Displays the voice age metadata with muted styling and tabular numbers for consistent alignment.

PropTypeDefaultDescription
classNamestring-Additional CSS classes to apply.
...propsReact.ComponentProps<-Any other props are spread to the span element.

<VoiceSelectorDescription />

Displays a description for the voice with muted styling.

PropTypeDefaultDescription
classNamestring-Additional CSS classes to apply.
...propsReact.ComponentProps<-Any other props are spread to the span element.

<VoiceSelectorAttributes />

Container for grouping voice attributes (gender, accent, age) together. Use with VoiceSelectorBullet for separation.

PropTypeDefaultDescription
classNamestring-Additional CSS classes to apply.
...propsReact.ComponentProps<-Any other props are spread to the div element.

<VoiceSelectorBullet />

Displays a bullet separator (•) between voice attributes. Hidden from screen readers via aria-hidden.

PropTypeDefaultDescription
classNamestring-Additional CSS classes to apply.
...propsReact.ComponentProps<-Any other props are spread to the span element.

<VoiceSelectorShortcut />

Displays keyboard shortcuts for voice items.

PropTypeDefaultDescription
...propsReact.ComponentProps<typeof CommandShortcut>-Any other props are spread to the CommandShortcut component.

<VoiceSelectorPreview />

A button that allows users to preview/play a voice sample before selecting it. Shows play, pause, or loading icons based on state.

PropTypeDefaultDescription
playingboolean-Whether the voice is currently playing. Shows pause icon when true.
loadingboolean-Whether the voice preview is loading. Shows loading spinner and disables the button.
onPlay() => void-Callback fired when the preview button is clicked.
classNamestring-Additional CSS classes to apply.
...propsOmit<React.ComponentProps<-Any other props are spread to the button element.

Hooks

useVoiceSelector()

A custom hook for accessing the voice selector context. This hook allows you to access and control the voice selection state from any component nested within VoiceSelector.

Create val
import { useVoiceSelector } from "@repo/elements/voice-selector"; export default function CustomVoiceDisplay() { const { value, setValue, open, setOpen } = useVoiceSelector(); return ( <div> <p>Selected voice: {value ?? "None"}</p> <button onClick={() => setOpen(!open)}>Toggle Dialog</button> </div> ); }

Return Value

PropTypeDefaultDescription
value`stringundefined`-
setValue`(value: stringundefined) => void`-
openboolean-Whether the dialog is currently open.
setOpen(open: boolean) => void-Function to control the dialog open state.
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2026 Val Town, Inc.