# 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 ```bash 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 ### `` Root Dialog component that provides context for all child components. Manages both voice selection and dialog open states. | Prop | Type | Default | Description | |------|------|---------|-------------| | `value` | `string` | - | The selected voice ID (controlled). | | `defaultValue` | `string` | - | The default selected voice ID (uncontrolled). | | `onValueChange` | `(value: string | undefined) => void` | - | Callback fired when the selected voice changes. | | `defaultOpen` | `boolean` | `false` | The default open state (uncontrolled). | | `open` | `boolean` | - | The open state (controlled). | | `onOpenChange` | `(open: boolean) => void` | - | Callback fired when the open state changes. | | `modal` | `boolean` | `true` | Whether the dialog is modal (blocks interaction with the rest of the page). | | `...props` | `React.ComponentProps` | - | Any other props are spread to the Dialog component. | ### `` Button or element that opens the voice selector dialog. | Prop | Type | Default | Description | |------|------|---------|-------------| | `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the DialogTrigger component. | ### `` Container for the Command component and voice list, rendered inside the dialog. | Prop | Type | Default | Description | |------|------|---------|-------------| | `title` | `ReactNode` | - | The title for screen readers. Hidden visually but accessible to assistive technologies. | | `className` | `string` | - | Additional CSS classes to apply to the dialog content. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the DialogContent component. | ### `` Alternative dialog implementation using CommandDialog for a full-screen command palette style. | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandDialog component. | ### `` Search input for filtering voices. | Prop | Type | Default | Description | |------|------|---------|-------------| | `placeholder` | `string` | - | Placeholder text for the search input. | | `className` | `string` | - | Additional CSS classes to apply. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandInput component. | ### `` Scrollable container for voice items and groups. | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandList component. | ### `` Message shown when no voices match the search query. | Prop | Type | Default | Description | |------|------|---------|-------------| | `children` | `ReactNode` | - | The message to display. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandEmpty component. | ### `` Groups related voices together with an optional heading. | Prop | Type | Default | Description | |------|------|---------|-------------| | `heading` | `string` | - | The heading text for the group. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandGroup component. | ### `` Selectable item representing a voice. | Prop | Type | Default | Description | |------|------|---------|-------------| | `value` | `string` | - | The unique identifier for this voice. Used for search filtering. | | `onSelect` | `(value: string) => void` | - | Callback fired when the voice is selected. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandItem component. | ### `` Visual separator between voice groups. | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandSeparator component. | ### `` Displays the voice name with proper styling. | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Additional CSS classes to apply. | | `...props` | `React.ComponentProps<` | - | Any other props are spread to the span element. | ### `` Displays the voice gender metadata with icons from Lucide. Supports multiple gender identities with corresponding icons. | Prop | Type | Default | Description | |------|------|---------|-------------| | `value` | `unknown` | - | The gender value that determines which icon to display. Supported values: | | `className` | `string` | - | Additional CSS classes to apply. | | `children` | `ReactNode` | - | Override the icon with custom content. | | `...props` | `React.ComponentProps<` | - | Any other props are spread to the span element. | ### `` Displays the voice accent metadata with emoji flags representing different countries/regions. | Prop | Type | Default | Description | |------|------|---------|-------------| | `value` | `unknown` | - | The accent value that determines which flag emoji to display. Supports 27 different accents including: | | `className` | `string` | - | Additional CSS classes to apply. | | `children` | `ReactNode` | - | Override the flag emoji with custom content. | | `...props` | `React.ComponentProps<` | - | Any other props are spread to the span element. | ### `` Displays the voice age metadata with muted styling and tabular numbers for consistent alignment. | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Additional CSS classes to apply. | | `...props` | `React.ComponentProps<` | - | Any other props are spread to the span element. | ### `` Displays a description for the voice with muted styling. | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Additional CSS classes to apply. | | `...props` | `React.ComponentProps<` | - | Any other props are spread to the span element. | ### `` Container for grouping voice attributes (gender, accent, age) together. Use with `VoiceSelectorBullet` for separation. | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Additional CSS classes to apply. | | `...props` | `React.ComponentProps<` | - | Any other props are spread to the div element. | ### `` Displays a bullet separator (•) between voice attributes. Hidden from screen readers via `aria-hidden`. | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Additional CSS classes to apply. | | `...props` | `React.ComponentProps<` | - | Any other props are spread to the span element. | ### `` Displays keyboard shortcuts for voice items. | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandShortcut component. | ### `` A button that allows users to preview/play a voice sample before selecting it. Shows play, pause, or loading icons based on state. | Prop | Type | Default | Description | |------|------|---------|-------------| | `playing` | `boolean` | - | Whether the voice is currently playing. Shows pause icon when true. | | `loading` | `boolean` | - | Whether the voice preview is loading. Shows loading spinner and disables the button. | | `onPlay` | `() => void` | - | Callback fired when the preview button is clicked. | | `className` | `string` | - | Additional CSS classes to apply. | | `...props` | `Omit

Selected voice: {value ?? "None"}

); } ``` #### Return Value | Prop | Type | Default | Description | |------|------|---------|-------------| | `value` | `string | undefined` | - | The currently selected voice ID. | | `setValue` | `(value: string | undefined) => void` | - | Function to update the selected voice ID. | | `open` | `boolean` | - | Whether the dialog is currently open. | | `setOpen` | `(open: boolean) => void` | - | Function to control the dialog open state. |