diff --git a/packages/core/src/hooks/useSpeechRecognition/useSpeechRecognition.test.ts b/packages/core/src/hooks/useSpeechRecognition/useSpeechRecognition.test.ts index 7d6260e2..3f13a761 100644 --- a/packages/core/src/hooks/useSpeechRecognition/useSpeechRecognition.test.ts +++ b/packages/core/src/hooks/useSpeechRecognition/useSpeechRecognition.test.ts @@ -50,6 +50,7 @@ class MockSpeechRecognition { } start = () => this.onstart?.(); stop = () => this.onend?.(); + abort = () => this.onend?.(); } const createResultEvent = (transcript: string) => @@ -87,6 +88,7 @@ it('Should use speech recognition', () => { expect(result.current.recognition).toBeInstanceOf(MockSpeechRecognition); expect(result.current.start).toBeTypeOf('function'); expect(result.current.stop).toBeTypeOf('function'); + expect(result.current.abort).toBeTypeOf('function'); expect(result.current.toggle).toBeTypeOf('function'); }); @@ -101,6 +103,7 @@ it('Should use speech recognition on server side', () => { expect(result.current.recognition).toBeUndefined(); expect(result.current.start).toBeTypeOf('function'); expect(result.current.stop).toBeTypeOf('function'); + expect(result.current.abort).toBeTypeOf('function'); expect(result.current.toggle).toBeTypeOf('function'); }); @@ -162,6 +165,24 @@ it('Should stop listening', () => { expect(result.current.recognition!.lang).toBe('en-US'); }); +it('Should abort listening', () => { + const onEnd = vi.fn(); + const onResult = vi.fn(); + const { result } = renderHook(() => useSpeechRecognition({ onEnd, onResult })); + + act(() => result.current.start()); + + expect(result.current.listening).toBeTruthy(); + expect(result.current.final).toBeFalsy(); + + act(() => result.current.abort()); + + expect(result.current.listening).toBeFalsy(); + expect(onEnd).toHaveBeenCalledTimes(1); + expect(onResult).toHaveBeenCalledTimes(0); + expect(result.current.recognition!.lang).toBe('en-US'); +}); + it('Should toggle listening state', () => { const { result } = renderHook(useSpeechRecognition); diff --git a/packages/core/src/hooks/useSpeechRecognition/useSpeechRecognition.ts b/packages/core/src/hooks/useSpeechRecognition/useSpeechRecognition.ts index 5cd347f6..d84847f5 100644 --- a/packages/core/src/hooks/useSpeechRecognition/useSpeechRecognition.ts +++ b/packages/core/src/hooks/useSpeechRecognition/useSpeechRecognition.ts @@ -38,8 +38,10 @@ interface UseSpeechRecognitionReturn { transcript: string; /** Begins speech recognition */ start: () => void; - /** Ends speech recognition, finalizing results */ + /** Ends speech recognition, finalizing results (will trigger `onResult`) */ stop: () => void; + /** Immediately interrupts speech recognition without a final result (will not trigger `onResult`). */ + abort: () => void; /** Toggles the listening state */ toggle: (value?: boolean) => void; } @@ -67,7 +69,7 @@ export const getSpeechRecognition = () => * @returns {UseSpeechRecognitionReturn} An object containing the speech recognition functionality * * @example - * const { supported, value, recognition, listening, error, start, stop, toggle } = useSpeechRecognition(); + * const { supported, value, recognition, listening, error, start, stop, abort, toggle } = useSpeechRecognition(); */ export const useSpeechRecognition = ( options: UseSpeechRecognitionOptions = {} @@ -133,6 +135,7 @@ export const useSpeechRecognition = ( const start = () => recognition?.start(); const stop = () => recognition?.stop(); + const abort = () => recognition?.abort(); const toggle = (value = !listening) => { if (value) return start(); @@ -148,6 +151,7 @@ export const useSpeechRecognition = ( error, start, stop, + abort, toggle }; };