react-dictate-button
Version:
A button to start dictation using Web Speech API, with an easy to understand event lifecycle.
1 lines • 37.1 kB
Source Map (JSON)
{"version":3,"sources":["../src/Composer.tsx","../src/Context.ts","../src/private/assert.ts","../src/usePrevious.ts","../src/vendorPrefix.ts","../src/DictateButton.tsx","../src/hooks/internal/useDictateContext.ts","../src/hooks/useReadyState.ts","../src/hooks/useSupported.ts","../src/DictateCheckbox.tsx","../src/hooks/useAbortable.ts","../src/index.ts"],"sourcesContent":["/* eslint no-magic-numbers: [\"error\", { \"ignore\": [0, 1, 2, 3] }] */\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { useRefFrom } from 'use-ref-from';\n\nimport Context from './Context.ts';\nimport { type DictateEventHandler } from './DictateEventHandler.ts';\nimport { type EndEventHandler } from './EndEventHandler.ts';\nimport { type ErrorEventHandler } from './ErrorEventHandler.ts';\nimport assert from './private/assert.ts';\nimport { type ProgressEventHandler } from './ProgressEventHandler.ts';\nimport { type RawEventHandler } from './RawEventHandler.ts';\nimport { type SpeechGrammarListPolyfill } from './SpeechGrammarListPolyfill.ts';\nimport { type SpeechRecognitionPolyfill } from './SpeechRecognitionPolyfill.ts';\nimport { type StartEventHandler } from './StartEventHandler.ts';\nimport { type TypedEventHandler } from './TypedEventHandler.ts';\nimport usePrevious from './usePrevious.ts';\nimport vendorPrefix from './vendorPrefix.ts';\n\ntype ComposerProps = {\n children?:\n | ((\n context: Readonly<{\n abortable: boolean;\n readyState: number;\n supported: boolean;\n }>\n ) => ReactNode)\n | ReactNode\n | undefined;\n /**\n * Sets whether speech recognition is in continuous mode or interactive mode.\n *\n * Modifying this value during recognition will have no effect until restarted.\n */\n continuous?: boolean | undefined;\n extra?: Record<string, unknown> | undefined;\n grammar?: string | undefined;\n lang?: string | undefined;\n onDictate?: DictateEventHandler | undefined;\n onEnd?: EndEventHandler | undefined;\n onError?: ErrorEventHandler | undefined;\n onProgress?: ProgressEventHandler | undefined;\n onRawEvent?: RawEventHandler | undefined;\n onStart?: StartEventHandler | undefined;\n speechGrammarList?: SpeechGrammarListPolyfill | undefined;\n speechRecognition?: SpeechRecognitionPolyfill | undefined;\n started?: boolean | undefined;\n};\n\nfunction recognitionAbortable(recognition: unknown): recognition is {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n abort: () => void;\n} {\n return !!(\n recognition &&\n typeof recognition === 'object' &&\n 'abort' in recognition &&\n typeof recognition.abort === 'function'\n );\n}\n\nconst Composer = ({\n children,\n continuous,\n extra,\n grammar,\n lang,\n onDictate,\n onEnd,\n onError,\n onProgress,\n onRawEvent,\n onStart,\n speechGrammarList = navigator.mediaDevices &&\n // @ts-expect-error navigator.mediaDevices.getUserMedia may not be defined in older browsers.\n navigator.mediaDevices.getUserMedia &&\n vendorPrefix('SpeechGrammarList'),\n speechRecognition = navigator.mediaDevices &&\n // @ts-expect-error navigator.mediaDevices.getUserMedia may not be defined in older browsers.\n navigator.mediaDevices.getUserMedia &&\n vendorPrefix('SpeechRecognition'),\n started\n}: ComposerProps) => {\n const [readyState, setReadyState] = useState(0);\n const continuousRef = useRefFrom(continuous);\n const extraRef = useRefFrom(extra);\n const grammarRef = useRefFrom(grammar);\n const langRef = useRefFrom(lang);\n const notAllowedRef = useRef(false);\n const onDictateRef = useRefFrom(onDictate);\n const onEndRef = useRefFrom(onEnd);\n const onErrorRef = useRefFrom(onError);\n const onProgressRef = useRefFrom(onProgress);\n const onRawEventRef = useRefFrom(onRawEvent);\n const onStartRef = useRefFrom(onStart);\n const prevSpeechRecognition = usePrevious(speechRecognition);\n const recognitionRef = useRef<SpeechRecognition>();\n const speechGrammarListRef = useRefFrom(speechGrammarList);\n const speechRecognitionClassRef = useRefFrom(speechRecognition);\n const stateRef = useRef<'idle' | 'started' | 'has progress' | 'has result' | 'error'>('idle');\n const unmountedRef = useRef(false);\n\n // If \"speechRecognition\" ponyfill changed, reset the \"notAllowed\" flag.\n if (prevSpeechRecognition !== speechRecognition) {\n notAllowedRef.current = false;\n }\n\n const emitDictate = useCallback<DictateEventHandler>(\n event => {\n if (unmountedRef.current) {\n return;\n }\n\n assert(stateRef.current !== 'started');\n\n onDictateRef.current?.(event);\n stateRef.current = 'has result';\n },\n [onDictateRef, stateRef]\n );\n\n const emitEnd = useCallback(() => {\n if (unmountedRef.current) {\n return;\n }\n\n // \"dictate\" and \"progress\" works as a pair. If \"progress\" was emitted without \"dictate\", we should emit \"dictate\" before \"end\".\n if (stateRef.current === 'has progress') {\n emitDictate({ type: 'dictate' });\n stateRef.current = 'has result';\n }\n\n // \"start\" and \"end\" works as a pair. If \"start\" was emitted, we should emit \"end\" event.\n assert(stateRef.current === 'started' || stateRef.current === 'has result' || stateRef.current === 'error');\n\n onEndRef.current?.(new Event('end') as Event & { type: 'end' });\n\n if (stateRef.current !== 'error') {\n stateRef.current = 'idle';\n }\n }, [onEndRef, stateRef]);\n\n const emitError = useCallback<ErrorEventHandler>(\n event => {\n if (unmountedRef.current) {\n return;\n }\n\n onErrorRef.current?.(event);\n stateRef.current = 'error';\n },\n [onErrorRef, stateRef]\n );\n\n const emitProgress = useCallback<ProgressEventHandler>(\n event => {\n if (unmountedRef.current) {\n return;\n }\n\n assert(\n stateRef.current === 'started' || stateRef.current === 'has progress' || stateRef.current === 'has result'\n );\n\n // Web Speech API does not emit \"result\" when nothing is heard, and Chrome does not emit \"nomatch\" event.\n // Because we emitted onProgress, we should emit \"dictate\" if not error, so they works in pair.\n onProgressRef.current?.(event);\n stateRef.current = 'has progress';\n },\n [onProgressRef, stateRef]\n );\n\n const emitStart = useCallback(() => {\n if (unmountedRef.current) {\n return;\n }\n\n assert(stateRef.current === 'idle');\n\n // \"start\" and \"end\" works as a pair. Initially, or if \"end\" was emitted, we should emit \"start\" event.\n onStartRef.current?.(new Event('start') as Event & { type: 'start' });\n stateRef.current = 'started';\n }, [onStartRef, stateRef]);\n\n const handleAudioEnd = useCallback<TypedEventHandler<Event>>(\n ({ target }) => target === recognitionRef.current && setReadyState(3),\n [recognitionRef, setReadyState]\n );\n\n const handleAudioStart = useCallback<TypedEventHandler<Event>>(\n ({ target }) => {\n if (target !== recognitionRef.current) {\n return;\n }\n\n setReadyState(2);\n emitProgress({ abortable: recognitionAbortable(target), type: 'progress' });\n },\n [emitProgress, recognitionRef, setReadyState]\n );\n\n const handleEnd = useCallback<TypedEventHandler<Event>>(\n ({ target }) => {\n if (target !== recognitionRef.current) {\n return;\n }\n\n emitEnd();\n setReadyState(0);\n\n recognitionRef.current = undefined;\n },\n [emitEnd, recognitionRef, setReadyState]\n );\n\n const handleError = useCallback<TypedEventHandler<SpeechRecognitionErrorEvent>>(\n event => {\n if (event.target !== recognitionRef.current) {\n return;\n }\n\n // Error out, no need to emit \"dictate\"\n recognitionRef.current = undefined;\n\n if (event.error === 'not-allowed') {\n notAllowedRef.current = true;\n }\n\n setReadyState(0);\n\n emitError(event);\n emitEnd();\n },\n [emitEnd, emitError, notAllowedRef, recognitionRef, setReadyState]\n );\n\n const handleRawEvent = useCallback<TypedEventHandler<Event>>(\n event => {\n if (event.target !== recognitionRef.current) {\n return;\n }\n\n onRawEventRef.current?.(event);\n },\n [onRawEventRef, recognitionRef]\n );\n\n const handleResult = useCallback<TypedEventHandler<SpeechRecognitionEvent>>(\n ({ resultIndex, results: rawResults, target }) => {\n if (target !== recognitionRef.current) {\n return;\n }\n\n if (rawResults.length) {\n // web-speech-cognitive-services does not emit \"resultIndex\".\n\n // Destructuring breaks Angular due to a bug in Zone.js.\n // eslint-disable-next-line prefer-destructuring\n const rawResult = rawResults[resultIndex ?? rawResults.length - 1];\n\n if (rawResult?.isFinal) {\n const alt = rawResult[0];\n\n alt &&\n emitDictate({\n result: {\n confidence: alt.confidence,\n transcript: alt.transcript\n },\n type: 'dictate'\n });\n } else {\n emitProgress({\n abortable: recognitionAbortable(target),\n results: Object.freeze(\n Array.from(rawResults)\n .filter(result => !result.isFinal)\n .map(alts => {\n // Destructuring breaks Angular due to a bug in Zone.js.\n // eslint-disable-next-line prefer-destructuring\n const firstAlt = alts[0];\n\n return {\n confidence: firstAlt?.confidence || 0,\n transcript: firstAlt?.transcript || ''\n };\n })\n ),\n type: 'progress'\n });\n }\n }\n },\n [emitDictate, emitProgress, recognitionRef]\n );\n\n const handleStart = useCallback<TypedEventHandler<Event>>(\n ({ target }) => {\n if (target === recognitionRef.current) {\n emitStart();\n setReadyState(1);\n }\n },\n [emitStart, recognitionRef, setReadyState]\n );\n\n useEffect(() => {\n if (!started) {\n return;\n }\n\n if (!speechRecognitionClassRef.current || notAllowedRef.current) {\n throw new Error('Speech recognition is not supported');\n } else if (recognitionRef.current) {\n throw new Error('Speech recognition already started, cannot start a new one.');\n }\n\n const grammars = speechGrammarListRef.current && grammarRef.current && new speechGrammarListRef.current();\n const recognition = (recognitionRef.current = new speechRecognitionClassRef.current());\n\n if (grammars) {\n grammars.addFromString(grammarRef.current, 1);\n\n recognition.grammars = grammars;\n }\n\n if (typeof langRef.current !== 'undefined') {\n recognition.lang = langRef.current;\n }\n\n recognition.continuous = !!continuousRef.current;\n recognition.interimResults = true;\n\n recognition.addEventListener('audioend', handleAudioEnd);\n recognition.addEventListener('audiostart', handleAudioStart);\n recognition.addEventListener('end', handleEnd);\n recognition.addEventListener('error', handleError);\n recognition.addEventListener('result', handleResult);\n recognition.addEventListener('start', handleStart);\n\n recognition.addEventListener('nomatch', handleRawEvent);\n recognition.addEventListener('audioend', handleRawEvent);\n recognition.addEventListener('audiostart', handleRawEvent);\n recognition.addEventListener('end', handleRawEvent);\n recognition.addEventListener('error', handleRawEvent);\n recognition.addEventListener('result', handleRawEvent);\n recognition.addEventListener('soundend', handleRawEvent);\n recognition.addEventListener('soundstart', handleRawEvent);\n recognition.addEventListener('speechend', handleRawEvent);\n recognition.addEventListener('speechstart', handleRawEvent);\n recognition.addEventListener('start', handleRawEvent);\n\n const { current: extra } = extraRef;\n\n extra &&\n Object.entries(extra).forEach(([key, value]) => {\n if (key !== 'constructor' && key !== 'prototype' && key !== '__proto__') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (recognition as any)[key] = value;\n }\n });\n\n recognition.start();\n\n return () => {\n if (recognitionAbortable(recognition)) {\n recognition.abort();\n } else if (!unmountedRef.current) {\n console.warn('react-dictate-state: Cannot stop because SpeechRecognition does not have abort() function.');\n }\n };\n }, [\n continuousRef,\n emitEnd,\n extraRef,\n grammarRef,\n handleAudioEnd,\n handleAudioStart,\n handleEnd,\n handleError,\n handleRawEvent,\n handleResult,\n handleStart,\n langRef,\n notAllowedRef,\n recognitionRef,\n speechGrammarListRef,\n speechRecognitionClassRef,\n started,\n stateRef\n ]);\n\n useEffect(\n () => () => {\n unmountedRef.current = true;\n },\n []\n );\n\n const abortable = recognitionAbortable(recognitionRef.current) && readyState === 2;\n const supported = !!speechRecognition && !notAllowedRef.current;\n\n const context = useMemo(\n () =>\n Object.freeze({\n abortable,\n readyState,\n supported\n }),\n [abortable, readyState, supported]\n );\n\n return (\n <Context.Provider value={context}>\n <Context.Consumer>{context => (typeof children === 'function' ? children(context) : children)}</Context.Consumer>\n </Context.Provider>\n );\n};\n\nexport default Composer;\nexport { type ComposerProps };\n","import { createContext } from 'react';\n\ntype DictateContextType = Readonly<{\n abortable: boolean;\n readyState: number;\n supported: boolean;\n}>;\n\nconst Context = createContext<DictateContextType>(\n Object.freeze({\n abortable: false,\n readyState: 0,\n supported: true\n })\n);\n\nexport default Context;\nexport { type DictateContextType };\n","declare global {\n const IS_DEVELOPMENT: boolean;\n}\n\nexport default function assert(truthy: boolean) {\n if (IS_DEVELOPMENT && !truthy) {\n throw new Error('Assertion failed.');\n }\n}\n","import { useEffect, useRef } from 'react';\n\nexport default function usePrevious<T>(value: T): T | undefined {\n const ref = useRef<T>();\n\n useEffect(() => {\n ref.current = value;\n });\n\n return ref.current;\n}\n","// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport default function vendorPrefix<T = any>(name: string): T | undefined {\n if (typeof window !== 'undefined') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return name in window && typeof (window as Record<string, any>)[name] !== 'undefined'\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (window as Record<string, any>)[name]\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (window as Record<string, any>)[`webkit${name}`];\n }\n\n return;\n}\n","/* eslint no-magic-numbers: [\"error\", { \"ignore\": [0, 1, 2, 3] }] */\n\nimport React, { useCallback, useState, type MouseEventHandler, type ReactNode } from 'react';\nimport { useRefFrom } from 'use-ref-from';\n\nimport Composer from './Composer.tsx';\nimport { type DictateEventHandler } from './DictateEventHandler.ts';\nimport { type EndEventHandler } from './EndEventHandler.ts';\nimport { type ErrorEventHandler } from './ErrorEventHandler.ts';\nimport useReadyState from './hooks/useReadyState.ts';\nimport useSupported from './hooks/useSupported.ts';\nimport { type ProgressEventHandler } from './ProgressEventHandler.ts';\nimport { type RawEventHandler } from './RawEventHandler.ts';\nimport { type SpeechGrammarListPolyfill } from './SpeechGrammarListPolyfill.ts';\nimport { type SpeechRecognitionPolyfill } from './SpeechRecognitionPolyfill.ts';\nimport { type StartEventHandler } from './StartEventHandler.ts';\n\ntype DictateButtonCoreProps = Readonly<{\n children?: ((context: Readonly<{ readyState: number | undefined }>) => ReactNode) | ReactNode | undefined;\n className?: string | undefined;\n disabled?: boolean | undefined;\n onClick?: MouseEventHandler<HTMLButtonElement> | undefined;\n}>;\n\nconst DictateButtonCore = ({ children, className, disabled, onClick }: DictateButtonCoreProps) => {\n const [readyState] = useReadyState();\n const [supported] = useSupported();\n\n return (\n <button\n className={className}\n disabled={readyState === 1 || readyState === 3 || !supported || disabled}\n onClick={onClick}\n type=\"button\"\n >\n {typeof children === 'function' ? children({ readyState }) : children}\n </button>\n );\n};\n\ntype DictateButtonProps = {\n children?: ((context: Readonly<{ readyState: number | undefined }>) => ReactNode) | ReactNode | undefined;\n className?: string | undefined;\n continuous?: boolean | undefined;\n disabled?: boolean | undefined;\n extra?: Record<string, unknown> | undefined;\n grammar?: string | undefined;\n lang?: string | undefined;\n onClick?: MouseEventHandler<HTMLButtonElement> | undefined;\n onDictate?: DictateEventHandler | undefined;\n onEnd?: EndEventHandler | undefined;\n onError?: ErrorEventHandler | undefined;\n onProgress?: ProgressEventHandler | undefined;\n onRawEvent?: RawEventHandler | undefined;\n onStart?: StartEventHandler | undefined;\n speechGrammarList?: SpeechGrammarListPolyfill | undefined;\n speechRecognition?: SpeechRecognitionPolyfill | undefined;\n};\n\nconst DictateButton = ({\n children,\n className,\n continuous,\n disabled,\n extra,\n grammar,\n lang,\n onClick,\n onDictate,\n onEnd,\n onError,\n onProgress,\n onRawEvent,\n onStart,\n speechGrammarList,\n speechRecognition\n}: DictateButtonProps) => {\n const [started, setStarted] = useState<boolean>(false);\n const onClickRef = useRefFrom(onClick);\n const onEndRef = useRefFrom(onEnd);\n const onErrorRef = useRefFrom(onError);\n const onStartRef = useRefFrom(onStart);\n\n const handleClick = useCallback<MouseEventHandler<HTMLButtonElement>>(\n event => {\n onClickRef.current && onClickRef.current(event);\n !event.isDefaultPrevented() && setStarted(started => !started);\n },\n [onClickRef, setStarted]\n );\n\n const handleEnd = useCallback<EndEventHandler>(\n event => {\n setStarted(false);\n onEndRef.current?.(event);\n },\n [onEndRef, setStarted]\n );\n\n const handleError = useCallback<ErrorEventHandler>(\n event => {\n setStarted(false);\n onErrorRef.current?.(event);\n },\n [onErrorRef, setStarted]\n );\n\n const handleStart = useCallback<StartEventHandler>(\n event => {\n setStarted(true);\n onStartRef.current?.(event);\n },\n [onStartRef, setStarted]\n );\n\n return (\n <Composer\n continuous={continuous}\n extra={extra}\n grammar={grammar}\n lang={lang}\n onDictate={onDictate}\n onEnd={handleEnd}\n onError={handleError}\n onProgress={onProgress}\n onRawEvent={onRawEvent}\n onStart={handleStart}\n speechGrammarList={speechGrammarList}\n speechRecognition={speechRecognition}\n started={started && !disabled}\n >\n <DictateButtonCore className={className} disabled={disabled} onClick={handleClick}>\n {children}\n </DictateButtonCore>\n </Composer>\n );\n};\n\nexport default DictateButton;\nexport { type DictateButtonProps };\n","import { useContext } from 'react';\n\nimport Context, { type DictateContextType } from '../../Context.ts';\n\nexport default function useDictateContext(): DictateContextType {\n return useContext(Context);\n}\n","import useDictateContext from './internal/useDictateContext.ts';\n\nexport default function useReadyState(): readonly [number] {\n const { readyState } = useDictateContext();\n\n return Object.freeze([readyState]);\n}\n","import useDictateContext from './internal/useDictateContext.ts';\n\nexport default function useSupported(): readonly [boolean] {\n const { supported } = useDictateContext();\n\n return Object.freeze([supported]);\n}\n","/* eslint no-magic-numbers: [\"error\", { \"ignore\": [0, 1, 2, 3] }] */\n\nimport React, { useCallback, useState, type FormEventHandler, type ReactNode } from 'react';\n\nimport { useRefFrom } from 'use-ref-from';\nimport Composer from './Composer.tsx';\nimport { type DictateEventHandler } from './DictateEventHandler.ts';\nimport { type EndEventHandler } from './EndEventHandler.ts';\nimport { type ErrorEventHandler } from './ErrorEventHandler.ts';\nimport useReadyState from './hooks/useReadyState.ts';\nimport useSupported from './hooks/useSupported.ts';\nimport { type ProgressEventHandler } from './ProgressEventHandler.ts';\nimport { type RawEventHandler } from './RawEventHandler.ts';\nimport { type SpeechGrammarListPolyfill } from './SpeechGrammarListPolyfill.ts';\nimport { type SpeechRecognitionPolyfill } from './SpeechRecognitionPolyfill.ts';\nimport { type StartEventHandler } from './StartEventHandler.ts';\n\ntype DictateCheckboxCoreProps = {\n children?: ((context: Readonly<{ readyState: number }>) => ReactNode) | ReactNode | undefined;\n className?: string | undefined;\n disabled?: boolean | undefined;\n onChange?: FormEventHandler<HTMLInputElement>;\n started?: boolean;\n};\n\nconst DictateCheckboxCore = ({ children, className, disabled, onChange, started }: DictateCheckboxCoreProps) => {\n const [readyState] = useReadyState();\n const [supported] = useSupported();\n\n return (\n <label>\n <input\n checked={started}\n className={className}\n disabled={readyState === 1 || readyState === 3 || !supported || disabled}\n onChange={onChange}\n type=\"checkbox\"\n />\n {typeof children === 'function' ? children({ readyState }) : children}\n </label>\n );\n};\n\ntype DictateCheckboxProps = {\n children?: ((context: Readonly<{ readyState: number }>) => ReactNode) | ReactNode | undefined;\n className?: string | undefined;\n continuous?: boolean | undefined;\n disabled?: boolean | undefined;\n extra?: Record<string, unknown> | undefined;\n grammar?: string | undefined;\n lang?: string | undefined;\n onDictate?: DictateEventHandler | undefined;\n onEnd?: EndEventHandler | undefined;\n onError?: ErrorEventHandler | undefined;\n onProgress?: ProgressEventHandler | undefined;\n onRawEvent?: RawEventHandler | undefined;\n onStart?: StartEventHandler | undefined;\n speechGrammarList?: SpeechGrammarListPolyfill | undefined;\n speechRecognition?: SpeechRecognitionPolyfill | undefined;\n};\n\nconst DictateCheckbox = ({\n children,\n className,\n continuous,\n disabled,\n extra,\n grammar,\n lang,\n onDictate,\n onEnd,\n onError,\n onProgress,\n onRawEvent,\n onStart,\n speechGrammarList,\n speechRecognition\n}: DictateCheckboxProps) => {\n const [started, setStarted] = useState(false);\n const onEndRef = useRefFrom(onEnd);\n const onErrorRef = useRefFrom(onError);\n const onStartRef = useRefFrom(onStart);\n\n const handleChange = useCallback<FormEventHandler<HTMLInputElement>>(\n ({ currentTarget: { checked } }) => setStarted(checked),\n [setStarted]\n );\n\n const handleEnd = useCallback<EndEventHandler>(\n event => {\n setStarted(false);\n onEndRef.current?.(event);\n },\n [onEndRef, setStarted]\n );\n\n const handleError = useCallback<ErrorEventHandler>(\n event => {\n setStarted(false);\n onErrorRef.current?.(event);\n },\n [onErrorRef, setStarted]\n );\n\n const handleStart = useCallback<StartEventHandler>(\n event => {\n setStarted(true);\n onStartRef.current?.(event);\n },\n [onStartRef, setStarted]\n );\n\n return (\n <Composer\n continuous={continuous}\n extra={extra}\n grammar={grammar}\n lang={lang}\n onDictate={onDictate}\n onEnd={handleEnd}\n onError={handleError}\n onProgress={onProgress}\n onRawEvent={onRawEvent}\n onStart={handleStart}\n speechGrammarList={speechGrammarList}\n speechRecognition={speechRecognition}\n started={started && !disabled}\n >\n <DictateCheckboxCore className={className} disabled={disabled} onChange={handleChange} started={started}>\n {children}\n </DictateCheckboxCore>\n </Composer>\n );\n};\n\nexport default DictateCheckbox;\nexport { type DictateCheckboxProps };\n","import useDictateContext from './internal/useDictateContext.ts';\n\nexport default function useAbortable(): readonly [boolean] {\n const { abortable } = useDictateContext();\n\n return Object.freeze([abortable]);\n}\n","// eslint-disable-next-line import/no-unassigned-import\nimport './env.d.ts';\n\nimport Composer, { type ComposerProps } from './Composer.tsx';\nimport Context_ from './Context.ts';\nimport DictateButton, { type DictateButtonProps } from './DictateButton.tsx';\nimport DictateCheckbox, { type DictateCheckboxProps } from './DictateCheckbox.tsx';\nimport { type DictateEventHandler } from './DictateEventHandler.ts';\nimport { type EndEventHandler } from './EndEventHandler.ts';\nimport { type ErrorEventHandler } from './ErrorEventHandler.ts';\nimport useAbortable from './hooks/useAbortable.ts';\nimport useReadyState from './hooks/useReadyState.ts';\nimport useSupported from './hooks/useSupported.ts';\nimport { type ProgressEventHandler } from './ProgressEventHandler.ts';\nimport { type RawEventHandler } from './RawEventHandler.ts';\nimport { type SpeechGrammarListPolyfill } from './SpeechGrammarListPolyfill.ts';\nimport { type SpeechRecognitionPolyfill } from './SpeechRecognitionPolyfill.ts';\nimport { type StartEventHandler } from './StartEventHandler.ts';\nimport { type TypedEventHandler } from './TypedEventHandler.ts';\n\n/** @deprecated Use `useAbortable`, `useReadyState`, and `useSupported` hooks instead. */\nconst Context = Context_;\n\n/** @deprecated Use `import { DictateButton } from 'react-dictate-button'` instead. */\nconst DictateButton_ = DictateButton;\n\nexport default DictateButton_;\n\nexport {\n Composer,\n Context,\n DictateButton,\n DictateCheckbox,\n useAbortable,\n useReadyState,\n useSupported,\n type ComposerProps,\n type DictateButtonProps,\n type DictateCheckboxProps,\n type DictateEventHandler,\n type EndEventHandler,\n type ErrorEventHandler,\n type ProgressEventHandler,\n type RawEventHandler,\n type SpeechGrammarListPolyfill,\n type SpeechRecognitionPolyfill,\n type StartEventHandler,\n type TypedEventHandler\n};\n"],"mappings":"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","names":["useEffect","useRef","useRef","useEffect","extra","context","React","useCallback","useState","useRefFrom","React","useState","useRefFrom","useCallback","started","React","useCallback","useState","useRefFrom","React","useState","useRefFrom","useCallback","Context"]}