import { splitProps, Show, For, createSignal } from 'solid-js'; import { cn } from '../utils/cn'; import { Button } from '../ui/button'; import { Tooltip } from '../ui/tooltip'; import { useVoiceRecorder } from '../primitives/use-voice-recorder'; export interface VoiceInputProps { onTranscribe: (audio: Blob) => Promise; onTranscription: (text: string) => void; disabled?: boolean; class?: string; } export function VoiceInput(props: VoiceInputProps) { const [local] = splitProps(props, ['onTranscribe', 'onTranscription', 'disabled', 'class']); const { isRecording, start, stop } = useVoiceRecorder(); const [isProcessing, setIsProcessing] = createSignal(false); const label = () => isProcessing() ? 'Transcribing...' : isRecording() ? 'Stop recording' : 'Voice input'; async function handleClick() { if (isRecording()) { stop(); } else { try { const blob = await start(); setIsProcessing(true); try { const text = await local.onTranscribe(blob); if (text.trim()) local.onTranscription(text.trim()); } finally { setIsProcessing(false); } } catch { setIsProcessing(false); } } } // Mic icon (not recording) const MicIcon = () => ( ); // Square stop icon (recording) const StopIcon = () => ( ); // Spinner (processing transcription) const Spinner = () => ( ); return (
{/* Animated pulse rings when recording */} {(index) => (
)}
); }