From 0e797e06bbad3e24f7608dc4f48be63ea4fb8f20 Mon Sep 17 00:00:00 2001 From: Christian Vidal Wolf Date: Sat, 11 Apr 2026 11:34:57 +0200 Subject: [PATCH] feat: add voice-to-text input using Web Speech API --- src/components/EditPanel.tsx | 45 ++++++++++++++++++-- src/lib/useSpeechRecognition.ts | 74 +++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 src/lib/useSpeechRecognition.ts diff --git a/src/components/EditPanel.tsx b/src/components/EditPanel.tsx index 396ab36..d588b2c 100644 --- a/src/components/EditPanel.tsx +++ b/src/components/EditPanel.tsx @@ -1,8 +1,9 @@ -import React, { useState } from 'react'; +import React, { useState, useRef, useCallback } from 'react'; import { ExcelRow, COLUMNS } from '../types'; -import { X, Sparkles, Save, Loader2, Languages, Package, CheckCircle2 } from 'lucide-react'; +import { X, Sparkles, Save, Loader2, Languages, Package, CheckCircle2, Mic, MicOff } from 'lucide-react'; import { generateGemini } from '../services/gemini'; import { cn } from '../lib/utils'; +import { useSpeechRecognition } from '../lib/useSpeechRecognition'; import { ConfirmModal } from './ConfirmModal'; interface EditPanelProps { @@ -49,6 +50,9 @@ interface FieldEditorProps { onGenerate: () => void; onChange: (val: string) => void; onKeyDown: (e: React.KeyboardEvent) => void; + isListening?: boolean; + onToggleVoice?: () => void; + voiceSupported?: boolean; } const FieldEditor = ({ @@ -61,7 +65,10 @@ const FieldEditor = ({ isLoading, onGenerate, onChange, - onKeyDown + onKeyDown, + isListening, + onToggleVoice, + voiceSupported }: FieldEditorProps) => (
@@ -73,6 +80,21 @@ const FieldEditor = ({ Can translate from existing
)} + {voiceSupported && ( + + )}