Files
temetro/.agents/skills/ai-elements/references/voice-selector.md
T
Khalid Abdi 929bec8f31 feat: AI-added records save with placeholders + "Added by AI" provenance
Stop blocking AI imports/proposals on missing non-critical fields. Records
the chat agent drafts now save with safe placeholders, auto-generated file
numbers, and a source="ai" marker that surfaces an "Added by AI" badge so a
clinician can review/edit them later.

Backend:
- add `source` (manual|ai) column to patients/appointments/prescriptions
  (migration 0014) + canonical types, services, validation schemas
- relax patient/appointment validation: empty file number allowed, demographic
  + type/provider/initials fall back to placeholders (initials derived from name)
- patients.generateFileNumber() auto-assigns an MRN when one is missing
- proposeAppointment accepts a name when no file number resolves; AI commits +
  /api/ai/import stamp source="ai"

Frontend:
- `source` on Appointment/Patient/Prescription types; AI commits send source="ai"
- reusable <AiBadge> shown on the Patients table/detail and prescriptions list

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 19:27:17 +03:00

10 KiB

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.

Prop Type Default Description
value string - The selected voice ID (controlled).
defaultValue string - The default selected voice ID (uncontrolled).
onValueChange `(value: string undefined) => void` -
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<typeof Dialog> - Any other props are spread to the Dialog component.

<VoiceSelectorTrigger />

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<typeof DialogTrigger> - Any other props are spread to the DialogTrigger component.

<VoiceSelectorContent />

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<typeof DialogContent> - Any other props are spread to the DialogContent component.

<VoiceSelectorDialog />

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

Prop Type Default Description
...props React.ComponentProps<typeof CommandDialog> - Any other props are spread to the CommandDialog component.

<VoiceSelectorInput />

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<typeof CommandInput> - Any other props are spread to the CommandInput component.

<VoiceSelectorList />

Scrollable container for voice items and groups.

Prop Type Default Description
...props React.ComponentProps<typeof CommandList> - Any other props are spread to the CommandList component.

<VoiceSelectorEmpty />

Message shown when no voices match the search query.

Prop Type Default Description
children ReactNode - The message to display.
...props React.ComponentProps<typeof CommandEmpty> - Any other props are spread to the CommandEmpty component.

<VoiceSelectorGroup />

Groups related voices together with an optional heading.

Prop Type Default Description
heading string - The heading text for the group.
...props React.ComponentProps<typeof CommandGroup> - Any other props are spread to the CommandGroup component.

<VoiceSelectorItem />

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<typeof CommandItem> - Any other props are spread to the CommandItem component.

<VoiceSelectorSeparator />

Visual separator between voice groups.

Prop Type Default Description
...props React.ComponentProps<typeof CommandSeparator> - Any other props are spread to the CommandSeparator component.

<VoiceSelectorName />

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.

<VoiceSelectorGender />

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.

<VoiceSelectorAccent />

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.

<VoiceSelectorAge />

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.

<VoiceSelectorDescription />

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.

<VoiceSelectorAttributes />

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.

<VoiceSelectorBullet />

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.

<VoiceSelectorShortcut />

Displays keyboard shortcuts for voice items.

Prop Type Default Description
...props React.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.

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<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.

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

Prop Type Default Description
value `string undefined` -
setValue `(value: string undefined) => void` -
open boolean - Whether the dialog is currently open.
setOpen (open: boolean) => void - Function to control the dialog open state.