@siberiacancode/reactuse 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/hooks/useDropZone/useDropZone.cjs.map +1 -1
- package/dist/cjs/hooks/useEventSource/useEventSource.cjs +1 -1
- package/dist/cjs/hooks/useEventSource/useEventSource.cjs.map +1 -1
- package/dist/cjs/hooks/useField/useField.cjs +1 -1
- package/dist/cjs/hooks/useField/useField.cjs.map +1 -1
- package/dist/cjs/hooks/useLongPress/useLongPress.cjs +1 -1
- package/dist/cjs/hooks/useLongPress/useLongPress.cjs.map +1 -1
- package/dist/cjs/hooks/useSpeechRecognition/useSpeechRecognition.cjs +1 -1
- package/dist/cjs/hooks/useSpeechRecognition/useSpeechRecognition.cjs.map +1 -1
- package/dist/cjs/hooks/useSpeechSynthesis/useSpeechSynthesis.cjs +1 -1
- package/dist/cjs/hooks/useSpeechSynthesis/useSpeechSynthesis.cjs.map +1 -1
- package/dist/cjs/hooks/useStorage/useStorage.cjs +1 -1
- package/dist/cjs/hooks/useStorage/useStorage.cjs.map +1 -1
- package/dist/cjs/hooks/useWindowFocus/useWindowFocus.cjs +1 -1
- package/dist/cjs/hooks/useWindowFocus/useWindowFocus.cjs.map +1 -1
- package/dist/esm/hooks/useDropZone/useDropZone.mjs.map +1 -1
- package/dist/esm/hooks/useEventSource/useEventSource.mjs +33 -34
- package/dist/esm/hooks/useEventSource/useEventSource.mjs.map +1 -1
- package/dist/esm/hooks/useField/useField.mjs +2 -1
- package/dist/esm/hooks/useField/useField.mjs.map +1 -1
- package/dist/esm/hooks/useLongPress/useLongPress.mjs +19 -19
- package/dist/esm/hooks/useLongPress/useLongPress.mjs.map +1 -1
- package/dist/esm/hooks/useSpeechRecognition/useSpeechRecognition.mjs +20 -21
- package/dist/esm/hooks/useSpeechRecognition/useSpeechRecognition.mjs.map +1 -1
- package/dist/esm/hooks/useSpeechSynthesis/useSpeechSynthesis.mjs +51 -36
- package/dist/esm/hooks/useSpeechSynthesis/useSpeechSynthesis.mjs.map +1 -1
- package/dist/esm/hooks/useStorage/useStorage.mjs +39 -36
- package/dist/esm/hooks/useStorage/useStorage.mjs.map +1 -1
- package/dist/esm/hooks/useWindowFocus/useWindowFocus.mjs +1 -1
- package/dist/esm/hooks/useWindowFocus/useWindowFocus.mjs.map +1 -1
- package/dist/types/hooks/useEventSource/useEventSource.d.ts +2 -2
- package/dist/types/hooks/useField/useField.d.ts +3 -0
- package/dist/types/hooks/useSpeechSynthesis/useSpeechSynthesis.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEventSource.mjs","sources":["../../../../src/hooks/useEventSource/useEventSource.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nimport { getRetry } from '@/utils/helpers';\n\n/** The use event source options type */\nexport interface UseEventSourceOptions<QueryData, Data> extends EventSourceInit {\n /** Immediately open the connection when calling this hook */\n immediately?: boolean;\n /* The placeholder data for the hook */\n placeholderData?: (() => Data) | Data;\n /* The retry count of requests */\n retry?: boolean | number;\n /* The retry delay of requests */\n retryDelay?: ((retry: number, event: Event) => number) | number;\n /* The onError function to be invoked */\n onError?: (error: Event) => void;\n /* The onMessage function to be invoked */\n onMessage?: (event: Event & { data?: Data }) => void;\n /* The onOpen function to be invoked */\n onOpen?: () => void;\n /* The select function to be invoked */\n select?: (data: QueryData) => Data;\n}\n\n/** The use event source return type */\ninterface UseEventSourceReturn<Data = any> {\n /** The latest data received via the EventSource */\n data?: Data;\n /** The current error */\n error?: Event;\n /** The instance of the EventSource */\n instance?: EventSource;\n /* The connecting state of the query */\n isConnecting: boolean;\n /* The error state of the query */\n isError: boolean;\n /* The open state of the query */\n
|
|
1
|
+
{"version":3,"file":"useEventSource.mjs","sources":["../../../../src/hooks/useEventSource/useEventSource.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nimport { getRetry } from '@/utils/helpers';\n\n/** The use event source options type */\nexport interface UseEventSourceOptions<QueryData, Data> extends EventSourceInit {\n /** Immediately open the connection when calling this hook */\n immediately?: boolean;\n /* The placeholder data for the hook */\n placeholderData?: (() => Data) | Data;\n /* The retry count of requests */\n retry?: boolean | number;\n /* The retry delay of requests */\n retryDelay?: ((retry: number, event: Event) => number) | number;\n /* The onError function to be invoked */\n onError?: (error: Event) => void;\n /* The onMessage function to be invoked */\n onMessage?: (event: Event & { data?: Data }) => void;\n /* The onOpen function to be invoked */\n onOpen?: () => void;\n /* The select function to be invoked */\n select?: (data: QueryData) => Data;\n}\n\n/** The use event source return type */\ninterface UseEventSourceReturn<Data = any> {\n /** The latest data received via the EventSource */\n data?: Data;\n /** The current error */\n error?: Event;\n /** The instance of the EventSource */\n instance?: EventSource;\n /* The connecting state of the query */\n isConnecting: boolean;\n /* The error state of the query */\n isError: boolean;\n /* The open state of the query */\n opened: boolean;\n /** Closes the EventSource connection gracefully */\n close: () => void;\n /** Reopen the EventSource connection */\n open: () => void;\n}\n\n/**\n * @name useEventSource\n * @description - Hook that provides a reactive wrapper for event source\n * @category Browser\n * @usage low\n *\n * @browserapi EventSource https://developer.mozilla.org/en-US/docs/Web/API/EventSource\n *\n * @param {string | URL} url The URL of the EventSource\n * @param {string[]} [events=[]] List of events to listen to\n * @param {UseEventSourceOptions} [options={}] Configuration options\n * @returns {UseEventSourceReturn<Data>} The EventSource state and controls\n *\n * @example\n * const { instance, data, connecting, opened, isError, close, open } = useEventSource('url', ['message']);\n */\nexport const useEventSource = <QueryData = any, Data = QueryData>(\n url: string | URL,\n events: string[] = [],\n options: UseEventSourceOptions<QueryData, Data> = {}\n): UseEventSourceReturn<Data> => {\n const [isConnecting, setIsConnecting] = useState(false);\n const [opened, setOpened] = useState(false);\n const [isError, setIsError] = useState(false);\n\n const retryCountRef = useRef(options?.retry ? getRetry(options.retry) : 0);\n const [error, setError] = useState<Event | undefined>(undefined);\n const [data, setData] = useState<Data | undefined>(options?.placeholderData);\n\n const eventSourceRef = useRef<EventSource>(undefined);\n\n const immediately = options.immediately ?? true;\n\n const onEventRef = useRef((event: Event & { data?: Data }) => setData(event.data));\n\n const close = () => {\n if (!eventSourceRef.current) return;\n\n setOpened(false);\n setIsConnecting(false);\n setIsError(false);\n\n events.forEach((eventName) =>\n eventSourceRef.current!.removeEventListener(eventName, onEventRef.current)\n );\n\n eventSourceRef.current.close();\n eventSourceRef.current = undefined;\n };\n\n const open = () => {\n close();\n\n const eventSource = new EventSource(url, {\n withCredentials: options.withCredentials ?? false\n });\n eventSourceRef.current = eventSource;\n\n setIsConnecting(true);\n\n eventSource.onopen = () => {\n setOpened(true);\n setIsConnecting(false);\n setError(undefined);\n options?.onOpen?.();\n };\n\n eventSource.onerror = (event) => {\n setOpened(false);\n setIsConnecting(false);\n setIsError(true);\n setError(event);\n options?.onError?.(event);\n\n if (retryCountRef.current > 0) {\n retryCountRef.current -= 1;\n\n const retryDelay =\n typeof options?.retryDelay === 'function'\n ? options?.retryDelay(retryCountRef.current, event)\n : options?.retryDelay;\n\n if (retryDelay) {\n setTimeout(open, retryDelay);\n return;\n }\n\n return open();\n }\n\n retryCountRef.current = options?.retry ? getRetry(options.retry) : 0;\n };\n\n eventSource.onmessage = (event) => {\n const data = options?.select ? options?.select(event.data) : event.data;\n setData(data);\n options?.onMessage?.(event);\n };\n\n events.forEach((eventName) => eventSource.addEventListener(eventName, onEventRef.current));\n };\n\n useEffect(() => {\n if (!immediately) return;\n\n open();\n return () => {\n close();\n };\n }, [immediately]);\n\n return {\n instance: eventSourceRef.current,\n data,\n error,\n isConnecting,\n opened,\n isError,\n close,\n open\n };\n};\n"],"names":["useEventSource","url","events","options","isConnecting","setIsConnecting","useState","opened","setOpened","isError","setIsError","retryCountRef","useRef","getRetry","error","setError","data","setData","eventSourceRef","immediately","onEventRef","event","close","eventName","open","eventSource","retryDelay","useEffect"],"mappings":";;AA4DO,MAAMA,IAAiB,CAC5BC,GACAC,IAAmB,CAAA,GACnBC,IAAkD,CAAA,MACnB;AAC/B,QAAM,CAACC,GAAcC,CAAe,IAAIC,EAAS,EAAK,GAChD,CAACC,GAAQC,CAAS,IAAIF,EAAS,EAAK,GACpC,CAACG,GAASC,CAAU,IAAIJ,EAAS,EAAK,GAEtCK,IAAgBC,EAAOT,GAAS,QAAQU,EAASV,EAAQ,KAAK,IAAI,CAAC,GACnE,CAACW,GAAOC,CAAQ,IAAIT,EAA4B,MAAS,GACzD,CAACU,GAAMC,CAAO,IAAIX,EAA2BH,GAAS,eAAe,GAErEe,IAAiBN,EAAoB,MAAS,GAE9CO,IAAchB,EAAQ,eAAe,IAErCiB,IAAaR,EAAO,CAACS,MAAmCJ,EAAQI,EAAM,IAAI,CAAC,GAE3EC,IAAQ,MAAM;AAClB,IAAKJ,EAAe,YAEpBV,EAAU,EAAK,GACfH,EAAgB,EAAK,GACrBK,EAAW,EAAK,GAEhBR,EAAO;AAAA,MAAQ,CAACqB,MACdL,EAAe,QAAS,oBAAoBK,GAAWH,EAAW,OAAO;AAAA,IAAA,GAG3EF,EAAe,QAAQ,MAAA,GACvBA,EAAe,UAAU;AAAA,EAAA,GAGrBM,IAAO,MAAM;AACjB,IAAAF,EAAA;AAEA,UAAMG,IAAc,IAAI,YAAYxB,GAAK;AAAA,MACvC,iBAAiBE,EAAQ,mBAAmB;AAAA,IAAA,CAC7C;AACD,IAAAe,EAAe,UAAUO,GAEzBpB,EAAgB,EAAI,GAEpBoB,EAAY,SAAS,MAAM;AACzB,MAAAjB,EAAU,EAAI,GACdH,EAAgB,EAAK,GACrBU,EAAS,MAAS,GAClBZ,GAAS,SAAA;AAAA,IAAS,GAGpBsB,EAAY,UAAU,CAACJ,MAAU;AAO/B,UANAb,EAAU,EAAK,GACfH,EAAgB,EAAK,GACrBK,EAAW,EAAI,GACfK,EAASM,CAAK,GACdlB,GAAS,UAAUkB,CAAK,GAEpBV,EAAc,UAAU,GAAG;AAC7B,QAAAA,EAAc,WAAW;AAEzB,cAAMe,IACJ,OAAOvB,GAAS,cAAe,aAC3BA,GAAS,WAAWQ,EAAc,SAASU,CAAK,IAChDlB,GAAS;AAEf,YAAIuB,GAAY;AACd,qBAAWF,GAAME,CAAU;AAC3B;AAAA,QAAA;AAGF,eAAOF,EAAA;AAAA,MAAK;AAGd,MAAAb,EAAc,UAAUR,GAAS,QAAQU,EAASV,EAAQ,KAAK,IAAI;AAAA,IAAA,GAGrEsB,EAAY,YAAY,CAACJ,MAAU;AACjC,YAAML,IAAOb,GAAS,SAASA,GAAS,OAAOkB,EAAM,IAAI,IAAIA,EAAM;AACnE,MAAAJ,EAAQD,CAAI,GACZb,GAAS,YAAYkB,CAAK;AAAA,IAAA,GAG5BnB,EAAO,QAAQ,CAACqB,MAAcE,EAAY,iBAAiBF,GAAWH,EAAW,OAAO,CAAC;AAAA,EAAA;AAG3F,SAAAO,EAAU,MAAM;AACd,QAAKR;AAEL,aAAAK,EAAA,GACO,MAAM;AACX,QAAAF,EAAA;AAAA,MAAM;AAAA,EACR,GACC,CAACH,CAAW,CAAC,GAET;AAAA,IACL,UAAUD,EAAe;AAAA,IACzB,MAAAF;AAAA,IACA,OAAAF;AAAA,IACA,cAAAV;AAAA,IACA,QAAAG;AAAA,IACA,SAAAE;AAAA,IACA,OAAAa;AAAA,IACA,MAAAE;AAAA,EAAA;AAEJ;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useField.mjs","sources":["../../../../src/hooks/useField/useField.ts"],"sourcesContent":["import { useRef, useState } from 'react';\n\nimport { useRerender } from '../useRerender/useRerender';\n\n/** The use field params type */\nexport interface UseFieldParams<Value> {\n /** The auto focus */\n autoFocus?: boolean;\n /** The initial touched */\n initialTouched?: boolean;\n /** The initial value */\n initialValue?: Value;\n /** The validate on blur */\n validateOnBlur?: boolean;\n /** The validate on mount */\n validateOnChange?: boolean;\n /** The validate on mount */\n validateOnMount?: boolean;\n}\n\n/** The use field register params type */\nexport interface UseFieldRegisterParams {\n /** The required validation */\n required?: string;\n /** The custom validation */\n validate?: (value: string) => Promise<string | true>;\n /** The min value validation */\n max?: {\n value: number;\n message: string;\n };\n /** The max length validation */\n maxLength?: {\n value: number;\n message: string;\n };\n /** The max value validation */\n min?: {\n value: number;\n message: string;\n };\n /** The min length validation */\n minLength?: {\n value: number;\n message: string;\n };\n /** The pattern validation */\n pattern?: {\n value: RegExp;\n message: string;\n };\n}\n\n/** The use field return type */\nexport interface UseFieldReturn<Value> {\n /** The dirty state */\n dirty: boolean;\n /** The error state */\n error?: string;\n /** The set error function */\n touched: boolean;\n /** The set error function */\n clearError: () => void;\n /** The focus function */\n focus: () => void;\n /** The get value function */\n getValue: () => Value;\n /** The register function */\n register: (params?: UseFieldRegisterParams) => {\n onBlur: () => void;\n onChange: () => void;\n ref: (\n node: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null | undefined\n ) => void;\n };\n /** The reset function */\n reset: () => void;\n /** The set error function */\n setError: (error: string) => void;\n /** The set value function */\n setValue: (value: Value) => void;\n /** The watch function */\n watch: () => Value;\n}\n\n/**\n * @name useField\n * @description - Hook to manage a form field\n * @category State\n * @usage medium\n *\n * @template Value The input value\n * @template Type The input value type\n * @param {Value} [params.initialValue] Initial value\n * @param {boolean} [params.initialTouched=false] Initial touched state\n * @param {boolean} [params.autoFocus=false] Auto focus\n * @param {boolean} [params.validateOnChange=false] Validate on change\n * @param {boolean} [params.validateOnBlur=false] Validate on blur\n * @param {boolean} [params.validateOnMount=false] Validate on mount\n * @returns {UseFieldReturn<Value>} An object containing input information\n *\n * @example\n * const { register, getValue, setValue, reset, dirty, error, setError, clearError, touched, focus, watch } = useField();\n */\nexport const useField = <\n Value extends boolean | number | string = string,\n Type = Value extends string ? string : Value extends boolean ? boolean : number\n>(\n params?: UseFieldParams<Value>\n): UseFieldReturn<Type> => {\n const initialValue = (params?.initialValue ?? '') as Value;\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const watchingRef = useRef(false);\n const rerender = useRerender();\n\n const [dirty, setDirty] = useState(false);\n const [touched, setTouched] = useState(params?.initialTouched ?? false);\n const [error, setError] = useState<string | undefined>(undefined);\n\n const getValue = () => {\n if (inputRef.current?.type === 'radio' || inputRef.current?.type === 'checkbox')\n return inputRef.current.checked as Type;\n return (inputRef.current?.value ?? initialValue) as Type;\n };\n\n const setValue = (value: Type) => {\n if (inputRef.current?.type === 'radio' || inputRef.current?.type === 'checkbox') {\n inputRef.current.checked = value as boolean;\n if (watchingRef.current) return rerender();\n return;\n }\n\n inputRef.current!.value = value as string;\n if (watchingRef.current) return rerender();\n };\n\n const reset = () => {\n setValue(initialValue as unknown as Type);\n setDirty(false);\n setTouched(false);\n setError(undefined);\n };\n\n const focus = () => inputRef.current!.focus();\n\n const validate = (params: UseFieldRegisterParams) => {\n if (params.required && !inputRef.current!.value) {\n return setError(params.required);\n }\n\n if (params.minLength && inputRef.current!.value.length < params.minLength.value) {\n return setError(params.minLength.message);\n }\n\n if (params.maxLength && inputRef.current!.value.length > params.maxLength.value) {\n return setError(params.maxLength.message);\n }\n\n if (params.min && Number(inputRef.current!.value) < params.min.value) {\n return setError(params.min.message);\n }\n\n if (params.max && Number(inputRef.current!.value) > params.max.value) {\n return setError(params.max.message);\n }\n\n if (params.pattern && !params.pattern.value.test(inputRef.current!.value)) {\n return setError(params.pattern.message);\n }\n\n if (params.validate) {\n const error = params.validate(inputRef.current!.value);\n if (typeof error === 'string') return setError(error);\n }\n\n setError(undefined);\n };\n\n const register = (registerParams?: UseFieldRegisterParams) => ({\n ref: (node: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null | undefined) => {\n if (!inputRef.current && node) {\n if (params?.autoFocus) node.focus();\n inputRef.current = node as HTMLInputElement;\n if (inputRef.current.type === 'radio') {\n inputRef.current.defaultChecked = params?.initialValue === node.value;\n return;\n }\n if (inputRef.current.type === 'checkbox') {\n inputRef.current.defaultChecked = !!params?.initialValue;\n return;\n }\n inputRef.current.defaultValue = String(initialValue);\n\n if (registerParams && params?.validateOnMount) validate(registerParams);\n }\n },\n onChange: async () => {\n if (watchingRef.current) return rerender();\n if (inputRef.current!.value !== initialValue) setDirty(true);\n if (dirty && inputRef.current!.value === initialValue) setDirty(false);\n if (registerParams && params?.validateOnChange) await validate(registerParams);\n if (registerParams && params?.validateOnBlur) setError(undefined);\n },\n onBlur: async () => {\n if (registerParams && params?.validateOnBlur) await validate(registerParams);\n setTouched(true);\n }\n });\n\n const watch = () => {\n watchingRef.current = true;\n return getValue();\n };\n\n const clearError = () => setError(undefined);\n\n return {\n register,\n dirty,\n touched,\n error,\n setError,\n clearError,\n getValue,\n setValue,\n reset,\n watch,\n focus\n };\n};\n"],"names":["useField","params","initialValue","inputRef","useRef","watchingRef","rerender","useRerender","dirty","setDirty","useState","touched","setTouched","error","setError","getValue","setValue","value","reset","focus","validate","registerParams","node"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useField.mjs","sources":["../../../../src/hooks/useField/useField.ts"],"sourcesContent":["import type { RefObject } from 'react';\n\nimport { useRef, useState } from 'react';\n\nimport { useRerender } from '../useRerender/useRerender';\n\n/** The use field params type */\nexport interface UseFieldParams<Value> {\n /** The auto focus */\n autoFocus?: boolean;\n /** The initial touched */\n initialTouched?: boolean;\n /** The initial value */\n initialValue?: Value;\n /** The validate on blur */\n validateOnBlur?: boolean;\n /** The validate on mount */\n validateOnChange?: boolean;\n /** The validate on mount */\n validateOnMount?: boolean;\n}\n\n/** The use field register params type */\nexport interface UseFieldRegisterParams {\n /** The required validation */\n required?: string;\n /** The custom validation */\n validate?: (value: string) => Promise<string | true>;\n /** The min value validation */\n max?: {\n value: number;\n message: string;\n };\n /** The max length validation */\n maxLength?: {\n value: number;\n message: string;\n };\n /** The max value validation */\n min?: {\n value: number;\n message: string;\n };\n /** The min length validation */\n minLength?: {\n value: number;\n message: string;\n };\n /** The pattern validation */\n pattern?: {\n value: RegExp;\n message: string;\n };\n}\n\n/** The use field return type */\nexport interface UseFieldReturn<Value> {\n /** The dirty state */\n dirty: boolean;\n /** The error state */\n error?: string;\n /** The input ref */\n ref: RefObject<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null>;\n /** The set error function */\n touched: boolean;\n /** The set error function */\n clearError: () => void;\n /** The focus function */\n focus: () => void;\n /** The get value function */\n getValue: () => Value;\n /** The register function */\n register: (params?: UseFieldRegisterParams) => {\n onBlur: () => void;\n onChange: () => void;\n ref: (\n node: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null | undefined\n ) => void;\n };\n /** The reset function */\n reset: () => void;\n /** The set error function */\n setError: (error: string) => void;\n /** The set value function */\n setValue: (value: Value) => void;\n /** The watch function */\n watch: () => Value;\n}\n\n/**\n * @name useField\n * @description - Hook to manage a form field\n * @category State\n * @usage medium\n *\n * @template Value The input value\n * @template Type The input value type\n * @param {Value} [params.initialValue] Initial value\n * @param {boolean} [params.initialTouched=false] Initial touched state\n * @param {boolean} [params.autoFocus=false] Auto focus\n * @param {boolean} [params.validateOnChange=false] Validate on change\n * @param {boolean} [params.validateOnBlur=false] Validate on blur\n * @param {boolean} [params.validateOnMount=false] Validate on mount\n * @returns {UseFieldReturn<Value>} An object containing input information\n *\n * @example\n * const { register, getValue, setValue, reset, dirty, error, setError, clearError, touched, focus, watch } = useField();\n */\nexport const useField = <\n Value extends boolean | number | string = string,\n Type = Value extends string ? string : Value extends boolean ? boolean : number\n>(\n params?: UseFieldParams<Value>\n): UseFieldReturn<Type> => {\n const initialValue = (params?.initialValue ?? '') as Value;\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const watchingRef = useRef(false);\n const rerender = useRerender();\n\n const [dirty, setDirty] = useState(false);\n const [touched, setTouched] = useState(params?.initialTouched ?? false);\n const [error, setError] = useState<string | undefined>(undefined);\n\n const getValue = () => {\n if (inputRef.current?.type === 'radio' || inputRef.current?.type === 'checkbox')\n return inputRef.current.checked as Type;\n return (inputRef.current?.value ?? initialValue) as Type;\n };\n\n const setValue = (value: Type) => {\n if (inputRef.current?.type === 'radio' || inputRef.current?.type === 'checkbox') {\n inputRef.current.checked = value as boolean;\n if (watchingRef.current) return rerender();\n return;\n }\n\n inputRef.current!.value = value as string;\n if (watchingRef.current) return rerender();\n };\n\n const reset = () => {\n setValue(initialValue as unknown as Type);\n setDirty(false);\n setTouched(false);\n setError(undefined);\n };\n\n const focus = () => inputRef.current!.focus();\n\n const validate = (params: UseFieldRegisterParams) => {\n if (params.required && !inputRef.current!.value) {\n return setError(params.required);\n }\n\n if (params.minLength && inputRef.current!.value.length < params.minLength.value) {\n return setError(params.minLength.message);\n }\n\n if (params.maxLength && inputRef.current!.value.length > params.maxLength.value) {\n return setError(params.maxLength.message);\n }\n\n if (params.min && Number(inputRef.current!.value) < params.min.value) {\n return setError(params.min.message);\n }\n\n if (params.max && Number(inputRef.current!.value) > params.max.value) {\n return setError(params.max.message);\n }\n\n if (params.pattern && !params.pattern.value.test(inputRef.current!.value)) {\n return setError(params.pattern.message);\n }\n\n if (params.validate) {\n const error = params.validate(inputRef.current!.value);\n if (typeof error === 'string') return setError(error);\n }\n\n setError(undefined);\n };\n\n const register = (registerParams?: UseFieldRegisterParams) => ({\n ref: (node: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null | undefined) => {\n if (!inputRef.current && node) {\n if (params?.autoFocus) node.focus();\n inputRef.current = node as HTMLInputElement;\n if (inputRef.current.type === 'radio') {\n inputRef.current.defaultChecked = params?.initialValue === node.value;\n return;\n }\n if (inputRef.current.type === 'checkbox') {\n inputRef.current.defaultChecked = !!params?.initialValue;\n return;\n }\n inputRef.current.defaultValue = String(initialValue);\n\n if (registerParams && params?.validateOnMount) validate(registerParams);\n }\n },\n onChange: async () => {\n if (watchingRef.current) return rerender();\n if (inputRef.current!.value !== initialValue) setDirty(true);\n if (dirty && inputRef.current!.value === initialValue) setDirty(false);\n if (registerParams && params?.validateOnChange) await validate(registerParams);\n if (registerParams && params?.validateOnBlur) setError(undefined);\n },\n onBlur: async () => {\n if (registerParams && params?.validateOnBlur) await validate(registerParams);\n setTouched(true);\n }\n });\n\n const watch = () => {\n watchingRef.current = true;\n return getValue();\n };\n\n const clearError = () => setError(undefined);\n\n return {\n register,\n dirty,\n touched,\n error,\n setError,\n clearError,\n getValue,\n setValue,\n reset,\n watch,\n focus,\n ref: inputRef\n };\n};\n"],"names":["useField","params","initialValue","inputRef","useRef","watchingRef","rerender","useRerender","dirty","setDirty","useState","touched","setTouched","error","setError","getValue","setValue","value","reset","focus","validate","registerParams","node"],"mappings":";;AA4GO,MAAMA,IAAW,CAItBC,MACyB;AACzB,QAAMC,IAAgBD,GAAQ,gBAAgB,IAExCE,IAAWC,EAAgC,IAAI,GAC/CC,IAAcD,EAAO,EAAK,GAC1BE,IAAWC,EAAA,GAEX,CAACC,GAAOC,CAAQ,IAAIC,EAAS,EAAK,GAClC,CAACC,GAASC,CAAU,IAAIF,EAAST,GAAQ,kBAAkB,EAAK,GAChE,CAACY,GAAOC,CAAQ,IAAIJ,EAA6B,MAAS,GAE1DK,IAAW,MACXZ,EAAS,SAAS,SAAS,WAAWA,EAAS,SAAS,SAAS,aAC5DA,EAAS,QAAQ,UAClBA,EAAS,SAAS,SAASD,GAG/Bc,IAAW,CAACC,MAAgB;AAChC,QAAId,EAAS,SAAS,SAAS,WAAWA,EAAS,SAAS,SAAS;AAEnE,aADAA,EAAS,QAAQ,UAAUc,GACvBZ,EAAY,UAAgBC,EAAA,IAChC;AAIF,QADAH,EAAS,QAAS,QAAQc,GACtBZ,EAAY,QAAS,QAAOC,EAAA;AAAA,EAAS,GAGrCY,IAAQ,MAAM;AAClB,IAAAF,EAASd,CAA+B,GACxCO,EAAS,EAAK,GACdG,EAAW,EAAK,GAChBE,EAAS,MAAS;AAAA,EAAA,GAGdK,IAAQ,MAAMhB,EAAS,QAAS,MAAA,GAEhCiB,IAAW,CAACnB,MAAmC;AACnD,QAAIA,EAAO,YAAY,CAACE,EAAS,QAAS;AACxC,aAAOW,EAASb,EAAO,QAAQ;AAGjC,QAAIA,EAAO,aAAaE,EAAS,QAAS,MAAM,SAASF,EAAO,UAAU;AACxE,aAAOa,EAASb,EAAO,UAAU,OAAO;AAG1C,QAAIA,EAAO,aAAaE,EAAS,QAAS,MAAM,SAASF,EAAO,UAAU;AACxE,aAAOa,EAASb,EAAO,UAAU,OAAO;AAG1C,QAAIA,EAAO,OAAO,OAAOE,EAAS,QAAS,KAAK,IAAIF,EAAO,IAAI;AAC7D,aAAOa,EAASb,EAAO,IAAI,OAAO;AAGpC,QAAIA,EAAO,OAAO,OAAOE,EAAS,QAAS,KAAK,IAAIF,EAAO,IAAI;AAC7D,aAAOa,EAASb,EAAO,IAAI,OAAO;AAGpC,QAAIA,EAAO,WAAW,CAACA,EAAO,QAAQ,MAAM,KAAKE,EAAS,QAAS,KAAK;AACtE,aAAOW,EAASb,EAAO,QAAQ,OAAO;AAGxC,QAAIA,EAAO,UAAU;AACnB,YAAMY,IAAQZ,EAAO,SAASE,EAAS,QAAS,KAAK;AACrD,UAAI,OAAOU,KAAU,SAAU,QAAOC,EAASD,CAAK;AAAA,IAAA;AAGtD,IAAAC,EAAS,MAAS;AAAA,EAAA;AAyCpB,SAAO;AAAA,IACL,UAvCe,CAACO,OAA6C;AAAA,MAC7D,KAAK,CAACC,MAAwF;AAC5F,YAAI,CAACnB,EAAS,WAAWmB,GAAM;AAG7B,cAFIrB,GAAQ,aAAWqB,EAAK,MAAA,GAC5BnB,EAAS,UAAUmB,GACfnB,EAAS,QAAQ,SAAS,SAAS;AACrC,YAAAA,EAAS,QAAQ,iBAAiBF,GAAQ,iBAAiBqB,EAAK;AAChE;AAAA,UAAA;AAEF,cAAInB,EAAS,QAAQ,SAAS,YAAY;AACxC,YAAAA,EAAS,QAAQ,iBAAiB,CAAC,CAACF,GAAQ;AAC5C;AAAA,UAAA;AAEF,UAAAE,EAAS,QAAQ,eAAe,OAAOD,CAAY,GAE/CmB,KAAkBpB,GAAQ,mBAAiBmB,EAASC,CAAc;AAAA,QAAA;AAAA,MACxE;AAAA,MAEF,UAAU,YAAY;AACpB,YAAIhB,EAAY,QAAS,QAAOC,EAAA;AAChC,QAAIH,EAAS,QAAS,UAAUD,OAAuB,EAAI,GACvDM,KAASL,EAAS,QAAS,UAAUD,OAAuB,EAAK,GACjEmB,KAAkBpB,GAAQ,oBAAkB,MAAMmB,EAASC,CAAc,GACzEA,KAAkBpB,GAAQ,kBAAgBa,EAAS,MAAS;AAAA,MAAA;AAAA,MAElE,QAAQ,YAAY;AAClB,QAAIO,KAAkBpB,GAAQ,kBAAgB,MAAMmB,EAASC,CAAc,GAC3ET,EAAW,EAAI;AAAA,MAAA;AAAA,IACjB;AAAA,IAYA,OAAAJ;AAAA,IACA,SAAAG;AAAA,IACA,OAAAE;AAAA,IACA,UAAAC;AAAA,IACA,YARiB,MAAMA,EAAS,MAAS;AAAA,IASzC,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,OAAAE;AAAA,IACA,OAjBY,OACZb,EAAY,UAAU,IACfU,EAAA;AAAA,IAgBP,OAAAI;AAAA,IACA,KAAKhB;AAAA,EAAA;AAET;"}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { useState as
|
|
1
|
+
import { useState as R, useRef as f, useEffect as h } from "react";
|
|
2
2
|
import { useRefState as T } from "../useRefState/useRefState.mjs";
|
|
3
3
|
import { isTarget as a } from "../../utils/helpers/isTarget.mjs";
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const S = 400, P = ((...t) => {
|
|
5
|
+
const e = a(t[0]) ? t[0] : void 0, l = e ? t[1] : t[0], m = e ? t[2] : t[1], [E, v] = R(!1), n = f(void 0), d = f(!1), u = T(), L = f(l);
|
|
6
6
|
L.current = l;
|
|
7
|
-
const
|
|
8
|
-
return
|
|
9
|
-
if (!
|
|
10
|
-
const
|
|
11
|
-
if (!
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
L.current(
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
|
|
7
|
+
const r = f(m);
|
|
8
|
+
return r.current = m, h(() => {
|
|
9
|
+
if (!e && !u.state) return;
|
|
10
|
+
const o = e ? a.getElement(e) : u.current;
|
|
11
|
+
if (!o) return;
|
|
12
|
+
const c = (s) => {
|
|
13
|
+
r.current?.onStart?.(s), d.current = !0, n.current = setTimeout(() => {
|
|
14
|
+
L.current(s), v(!0);
|
|
15
|
+
}, r.current?.threshold ?? S);
|
|
16
|
+
}, i = (s) => {
|
|
17
|
+
v((w) => (w ? r.current?.onFinish?.(s) : d.current && r.current?.onCancel?.(s), d.current = !1, n.current && clearTimeout(n.current), !1));
|
|
18
18
|
};
|
|
19
|
-
return
|
|
20
|
-
|
|
19
|
+
return o.addEventListener("mousedown", c), window.addEventListener("mouseup", i), o.addEventListener("touchstart", c), window.addEventListener("touchend", i), () => {
|
|
20
|
+
o.removeEventListener("mousedown", c), window.removeEventListener("mouseup", i), o.removeEventListener("touchstart", c), window.removeEventListener("touchend", i), n.current && clearTimeout(n.current);
|
|
21
21
|
};
|
|
22
|
-
}, [
|
|
23
|
-
ref:
|
|
24
|
-
pressed:
|
|
22
|
+
}, [e, u.state, a.getRefState(e)]), e ? E : {
|
|
23
|
+
ref: u,
|
|
24
|
+
pressed: E
|
|
25
25
|
};
|
|
26
26
|
});
|
|
27
27
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLongPress.mjs","sources":["../../../../src/hooks/useLongPress/useLongPress.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nimport type { HookTarget } from '@/utils/helpers';\n\nimport { isTarget } from '@/utils/helpers';\n\nimport type { StateRef } from '../useRefState/useRefState';\n\nimport { useRefState } from '../useRefState/useRefState';\n\nexport type LongPressEvents = MouseEvent | TouchEvent;\n\n// * The use long press options type */\nexport interface UseLongPressOptions {\n // * The threshold time in milliseconds\n threshold?: number;\n // * The callback function to be invoked on long press cancel\n onCancel?: (event: LongPressEvents) => void;\n // * The callback function to be invoked on long press end\n onFinish?: (event: LongPressEvents) => void;\n // * The callback function to be invoked on long press start\n onStart?: (event: LongPressEvents) => void;\n}\n\nexport interface UseLongPress {\n (\n target: HookTarget,\n callback: (event: LongPressEvents) => void,\n options?: UseLongPressOptions\n ): boolean;\n\n <Target extends Element>(\n callback: (event: LongPressEvents) => void,\n options?: UseLongPressOptions,\n target?: never\n ): {\n ref: StateRef<Target>;\n pressed: boolean;\n };\n}\n\nconst DEFAULT_THRESHOLD_TIME = 400;\n\n/**\n * @name useLongPress\n * @description - Hook that defines the logic when long pressing an element\n * @category Elements\n * @usage medium\n *\n * @overload\n * @param {HookTarget} target The target element to be long pressed\n * @param {(event: LongPressEvents) => void} callback The callback function to be invoked on long press\n * @param {UseLongPressOptions} [options] The options for the long press\n * @returns {boolean} The long pressing state\n *\n * @example\n * const pressed = useLongPress(ref, () => console.log('callback'));\n *\n * @overload\n * @template Target The target element\n * @param {(event: LongPressEvents) => void} callback The callback function to be invoked on long press\n * @param {UseLongPressOptions} [options] The options for the long press\n * @returns {boolean} The long pressing state\n *\n * @example\n * const { ref, pressed } = useLongPress(() => console.log('callback'));\n */\nexport const useLongPress = ((...params: any[]): any => {\n const target = (isTarget(params[0]) ? params[0] : undefined) as HookTarget | undefined;\n const callback = (target ? params[1] : params[0]) as (event: LongPressEvents) => void;\n const options = (target ? params[2] : params[1]) as UseLongPressOptions | undefined;\n\n const [pressed, setPressed] = useState(false);\n const timeoutIdRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n const isPressedRef = useRef(false);\n const internalRef = useRefState<Element>();\n\n const internalCallbackRef = useRef(callback);\n internalCallbackRef.current = callback;\n const internalOptionsRef = useRef(options);\n internalOptionsRef.current = options;\n\n useEffect(() => {\n if (!target && !internalRef.state) return;\n\n const element = target ? isTarget.getElement(target) : internalRef.current;\n if (!element) return;\n\n const onStart = (event: LongPressEvents) => {\n internalOptionsRef.current?.onStart?.(event);\n\n isPressedRef.current = true;\n timeoutIdRef.current = setTimeout(() => {\n internalCallbackRef.current(event);\n setPressed(true);\n }, internalOptionsRef.current?.threshold ?? DEFAULT_THRESHOLD_TIME);\n };\n\n const onCancel = (event: LongPressEvents) => {\n setPressed((prevPressed) => {\n if (prevPressed) {\n internalOptionsRef.current?.onFinish?.(event);\n } else if (isPressedRef.current) {\n internalOptionsRef.current?.onCancel?.(event);\n }\n\n
|
|
1
|
+
{"version":3,"file":"useLongPress.mjs","sources":["../../../../src/hooks/useLongPress/useLongPress.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nimport type { HookTarget } from '@/utils/helpers';\n\nimport { isTarget } from '@/utils/helpers';\n\nimport type { StateRef } from '../useRefState/useRefState';\n\nimport { useRefState } from '../useRefState/useRefState';\n\nexport type LongPressEvents = MouseEvent | TouchEvent;\n\n// * The use long press options type */\nexport interface UseLongPressOptions {\n // * The threshold time in milliseconds\n threshold?: number;\n // * The callback function to be invoked on long press cancel\n onCancel?: (event: LongPressEvents) => void;\n // * The callback function to be invoked on long press end\n onFinish?: (event: LongPressEvents) => void;\n // * The callback function to be invoked on long press start\n onStart?: (event: LongPressEvents) => void;\n}\n\nexport interface UseLongPress {\n (\n target: HookTarget,\n callback: (event: LongPressEvents) => void,\n options?: UseLongPressOptions\n ): boolean;\n\n <Target extends Element>(\n callback: (event: LongPressEvents) => void,\n options?: UseLongPressOptions,\n target?: never\n ): {\n ref: StateRef<Target>;\n pressed: boolean;\n };\n}\n\nconst DEFAULT_THRESHOLD_TIME = 400;\n\n/**\n * @name useLongPress\n * @description - Hook that defines the logic when long pressing an element\n * @category Elements\n * @usage medium\n *\n * @overload\n * @param {HookTarget} target The target element to be long pressed\n * @param {(event: LongPressEvents) => void} callback The callback function to be invoked on long press\n * @param {UseLongPressOptions} [options] The options for the long press\n * @returns {boolean} The long pressing state\n *\n * @example\n * const pressed = useLongPress(ref, () => console.log('callback'));\n *\n * @overload\n * @template Target The target element\n * @param {(event: LongPressEvents) => void} callback The callback function to be invoked on long press\n * @param {UseLongPressOptions} [options] The options for the long press\n * @returns {boolean} The long pressing state\n *\n * @example\n * const { ref, pressed } = useLongPress(() => console.log('callback'));\n */\nexport const useLongPress = ((...params: any[]): any => {\n const target = (isTarget(params[0]) ? params[0] : undefined) as HookTarget | undefined;\n const callback = (target ? params[1] : params[0]) as (event: LongPressEvents) => void;\n const options = (target ? params[2] : params[1]) as UseLongPressOptions | undefined;\n\n const [pressed, setPressed] = useState(false);\n const timeoutIdRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n const isPressedRef = useRef(false);\n const internalRef = useRefState<Element>();\n\n const internalCallbackRef = useRef(callback);\n internalCallbackRef.current = callback;\n const internalOptionsRef = useRef(options);\n internalOptionsRef.current = options;\n\n useEffect(() => {\n if (!target && !internalRef.state) return;\n\n const element = target ? isTarget.getElement(target) : internalRef.current;\n if (!element) return;\n\n const onStart = (event: LongPressEvents) => {\n internalOptionsRef.current?.onStart?.(event);\n\n isPressedRef.current = true;\n timeoutIdRef.current = setTimeout(() => {\n internalCallbackRef.current(event);\n setPressed(true);\n }, internalOptionsRef.current?.threshold ?? DEFAULT_THRESHOLD_TIME);\n };\n\n const onCancel = (event: LongPressEvents) => {\n setPressed((prevPressed) => {\n if (prevPressed) {\n internalOptionsRef.current?.onFinish?.(event);\n } else if (isPressedRef.current) {\n internalOptionsRef.current?.onCancel?.(event);\n }\n\n isPressedRef.current = false;\n if (timeoutIdRef.current) clearTimeout(timeoutIdRef.current);\n\n return false;\n });\n };\n\n element.addEventListener('mousedown', onStart as EventListener);\n window.addEventListener('mouseup', onCancel as EventListener);\n\n element.addEventListener('touchstart', onStart as EventListener);\n window.addEventListener('touchend', onCancel as EventListener);\n\n return () => {\n element.removeEventListener('mousedown', onStart as EventListener);\n window.removeEventListener('mouseup', onCancel as EventListener);\n\n element.removeEventListener('touchstart', onStart as EventListener);\n window.removeEventListener('touchend', onCancel as EventListener);\n\n if (timeoutIdRef.current) clearTimeout(timeoutIdRef.current);\n };\n }, [target, internalRef.state, isTarget.getRefState(target)]);\n\n if (target) return pressed;\n return {\n ref: internalRef,\n pressed\n };\n}) as UseLongPress;\n"],"names":["DEFAULT_THRESHOLD_TIME","useLongPress","params","target","isTarget","callback","options","pressed","setPressed","useState","timeoutIdRef","useRef","isPressedRef","internalRef","useRefState","internalCallbackRef","internalOptionsRef","useEffect","element","onStart","event","onCancel","prevPressed"],"mappings":";;;AAyCA,MAAMA,IAAyB,KA0BlBC,KAAgB,IAAIC,MAAuB;AACtD,QAAMC,IAAUC,EAASF,EAAO,CAAC,CAAC,IAAIA,EAAO,CAAC,IAAI,QAC5CG,IAAYF,IAASD,EAAO,CAAC,IAAIA,EAAO,CAAC,GACzCI,IAAWH,IAASD,EAAO,CAAC,IAAIA,EAAO,CAAC,GAExC,CAACK,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtCC,IAAeC,EAAsC,MAAS,GAC9DC,IAAeD,EAAO,EAAK,GAC3BE,IAAcC,EAAA,GAEdC,IAAsBJ,EAAON,CAAQ;AAC3C,EAAAU,EAAoB,UAAUV;AAC9B,QAAMW,IAAqBL,EAAOL,CAAO;AAmDzC,SAlDAU,EAAmB,UAAUV,GAE7BW,EAAU,MAAM;AACd,QAAI,CAACd,KAAU,CAACU,EAAY,MAAO;AAEnC,UAAMK,IAAUf,IAASC,EAAS,WAAWD,CAAM,IAAIU,EAAY;AACnE,QAAI,CAACK,EAAS;AAEd,UAAMC,IAAU,CAACC,MAA2B;AAC1C,MAAAJ,EAAmB,SAAS,UAAUI,CAAK,GAE3CR,EAAa,UAAU,IACvBF,EAAa,UAAU,WAAW,MAAM;AACtC,QAAAK,EAAoB,QAAQK,CAAK,GACjCZ,EAAW,EAAI;AAAA,MAAA,GACdQ,EAAmB,SAAS,aAAahB,CAAsB;AAAA,IAAA,GAG9DqB,IAAW,CAACD,MAA2B;AAC3C,MAAAZ,EAAW,CAACc,OACNA,IACFN,EAAmB,SAAS,WAAWI,CAAK,IACnCR,EAAa,WACtBI,EAAmB,SAAS,WAAWI,CAAK,GAG9CR,EAAa,UAAU,IACnBF,EAAa,WAAS,aAAaA,EAAa,OAAO,GAEpD,GACR;AAAA,IAAA;AAGH,WAAAQ,EAAQ,iBAAiB,aAAaC,CAAwB,GAC9D,OAAO,iBAAiB,WAAWE,CAAyB,GAE5DH,EAAQ,iBAAiB,cAAcC,CAAwB,GAC/D,OAAO,iBAAiB,YAAYE,CAAyB,GAEtD,MAAM;AACX,MAAAH,EAAQ,oBAAoB,aAAaC,CAAwB,GACjE,OAAO,oBAAoB,WAAWE,CAAyB,GAE/DH,EAAQ,oBAAoB,cAAcC,CAAwB,GAClE,OAAO,oBAAoB,YAAYE,CAAyB,GAE5DX,EAAa,WAAS,aAAaA,EAAa,OAAO;AAAA,IAAA;AAAA,EAC7D,GACC,CAACP,GAAQU,EAAY,OAAOT,EAAS,YAAYD,CAAM,CAAC,CAAC,GAExDA,IAAeI,IACZ;AAAA,IACL,KAAKM;AAAA,IACL,SAAAN;AAAA,EAAA;AAEJ;"}
|
|
@@ -4,41 +4,40 @@ const f = () => window?.SpeechRecognition ?? window?.webkitSpeechRecognition, q
|
|
|
4
4
|
continuous: m = !1,
|
|
5
5
|
interimResults: R = !1,
|
|
6
6
|
language: c = "en-US",
|
|
7
|
-
grammars:
|
|
7
|
+
grammars: a,
|
|
8
8
|
maxAlternatives: w = 1,
|
|
9
9
|
onStart: S,
|
|
10
10
|
onEnd: h,
|
|
11
11
|
onError: x,
|
|
12
12
|
onResult: E
|
|
13
|
-
} = d, [
|
|
13
|
+
} = d, [l, s] = e(!1), [A, b] = e(""), [k, y] = e(!1), [F, u] = e(null), [o] = e(() => {
|
|
14
14
|
if (!i) return {};
|
|
15
|
-
const r = f(),
|
|
16
|
-
return
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
u(
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}, n;
|
|
15
|
+
const r = f(), t = new r();
|
|
16
|
+
return t.continuous = m, a && (t.grammars = a), t.interimResults = R, t.lang = c, t.maxAlternatives = w, t.onstart = () => {
|
|
17
|
+
s(!0), y(!1), S?.();
|
|
18
|
+
}, t.onend = () => {
|
|
19
|
+
s(!1), h?.();
|
|
20
|
+
}, t.onerror = (n) => {
|
|
21
|
+
u(n), s(!1), x?.(n);
|
|
22
|
+
}, t.onresult = (n) => {
|
|
23
|
+
const I = n.results[n.resultIndex], { transcript: L } = I[0];
|
|
24
|
+
b(L), u(null), E?.(n);
|
|
25
|
+
}, t.onend = () => {
|
|
26
|
+
s(!1), t.lang = c;
|
|
27
|
+
}, t;
|
|
29
28
|
});
|
|
30
|
-
T(() => () =>
|
|
31
|
-
const g = () =>
|
|
29
|
+
T(() => () => o.stop(), []);
|
|
30
|
+
const g = () => o.start(), p = () => o.stop();
|
|
32
31
|
return {
|
|
33
32
|
supported: i,
|
|
34
33
|
transcript: A,
|
|
35
|
-
recognition:
|
|
34
|
+
recognition: o,
|
|
36
35
|
final: k,
|
|
37
|
-
listening:
|
|
36
|
+
listening: l,
|
|
38
37
|
error: F,
|
|
39
38
|
start: g,
|
|
40
39
|
stop: p,
|
|
41
|
-
toggle: (r = !
|
|
40
|
+
toggle: (r = !l) => {
|
|
42
41
|
if (r) return g();
|
|
43
42
|
p();
|
|
44
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSpeechRecognition.mjs","sources":["../../../../src/hooks/useSpeechRecognition/useSpeechRecognition.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/** The use speech recognition hook options type */\ninterface UseSpeechRecognitionOptions {\n /** If true, recognition continues even after pauses in speech. Default is false */\n continuous?: SpeechRecognition['continuous'];\n /** A list of grammar rules */\n grammars?: SpeechRecognition['grammars'];\n /** If true, interim (non-final) results are provided as the user speaks */\n interimResults?: SpeechRecognition['interimResults'];\n /** The language in which recognition should occur. Must be a valid BCP 47 language tag (e.g., \"en-US\", \"ru-RU\") */\n language?: SpeechRecognition['lang'];\n /** The maximum number of alternative transcripts returned for a given recognition result. Must be a positive integer */\n maxAlternatives?: SpeechRecognition['maxAlternatives'];\n /** Callback invoked when speech recognition ends */\n onEnd?: () => void;\n /** Callback invoked when an error occurs during recognition */\n onError?: (error: SpeechRecognitionErrorEvent) => void;\n /** Callback invoked when recognition produces a result */\n onResult?: (event: SpeechRecognitionEvent) => void;\n /** Callback invoked when speech recognition starts */\n onStart?: () => void;\n}\n\n/** The return type of the useSpeechRecognition hook. */\ninterface UseSpeechRecognitionReturn {\n /** The error state */\n error: SpeechRecognitionErrorEvent | null;\n /** The final transcript */\n final: boolean;\n /** Whether the hook is currently listening for speech */\n listening: boolean;\n /** The speech recognition instance */\n recognition: SpeechRecognition;\n /** Whether the current browser supports the Web Speech API */\n supported: boolean;\n /** The current transcript */\n transcript: string;\n /** Begins speech recognition */\n start: () => void;\n /** Ends speech recognition, finalizing results */\n stop: () => void;\n /** Toggles the listening state */\n toggle: (value?: boolean) => void;\n}\n\nexport const getSpeechRecognition = () =>\n window?.SpeechRecognition ?? window?.webkitSpeechRecognition;\n\n/**\n * @name useSpeechRecognition\n * @description - Hook that provides a streamlined interface for incorporating speech-to-text functionality\n * @category Browser\n * @usage low\n *\n * @browserapi window.SpeechRecognition https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition\n *\n * @param {boolean} [options.continuous=false] Whether recognition should continue after pauses\n * @param {boolean} [options.interimResults=false] Whether interim results should be provided\n * @param {string} [options.language=\"en-US\"] The language for recognition, as a valid BCP 47 tag\n * @param {number} [options.maxAlternatives=1] The maximum number of alternative transcripts to return\n * @param {SpeechGrammarList} [options.grammars] A list of grammar rules\n * @param {() => void} [options.onStart] Callback invoked when speech recognition starts\n * @param {() => void} [options.onEnd] Callback invoked when speech recognition ends\n * @param {(error: SpeechRecognitionErrorEvent) => void} [options.onError] Callback invoked when an error occurs during recognition\n * @param {(event: SpeechRecognitionEvent) => void} [options.onResult] Callback invoked when recognition produces a result\n * @returns {UseSpeechRecognitionReturn} An object containing the speech recognition functionality\n *\n * @example\n * const { supported, value, recognition, listening, error, start, stop, toggle } = useSpeechRecognition();\n */\nexport const useSpeechRecognition = (\n options: UseSpeechRecognitionOptions = {}\n): UseSpeechRecognitionReturn => {\n const supported = typeof window !== 'undefined' && !!getSpeechRecognition();\n\n const {\n continuous = false,\n interimResults = false,\n language = 'en-US',\n grammars,\n maxAlternatives = 1,\n onStart,\n onEnd,\n onError,\n onResult\n } = options;\n\n const [listening, setListening] = useState(false);\n const [transcript, setTranscript] = useState('');\n const [final, setFinal] = useState(false);\n const [error, setError] = useState<SpeechRecognitionErrorEvent | null>(null);\n const [recognition] = useState<SpeechRecognition>(() => {\n if (!supported) return {} as SpeechRecognition;\n\n const SpeechRecognition = getSpeechRecognition();\n const speechRecognition = new SpeechRecognition();\n\n speechRecognition.continuous = continuous;\n if (grammars) speechRecognition.grammars = grammars;\n speechRecognition.interimResults = interimResults;\n speechRecognition.lang = language;\n speechRecognition.maxAlternatives = maxAlternatives;\n\n speechRecognition.onstart = () => {\n setListening(true);\n setFinal(false);\n onStart?.();\n };\n speechRecognition.onend = () => {\n setListening(false);\n onEnd?.();\n };\n speechRecognition.onerror = (event) => {\n setError(event);\n setListening(false);\n onError?.(event);\n };\n speechRecognition.onresult = (event) => {\n
|
|
1
|
+
{"version":3,"file":"useSpeechRecognition.mjs","sources":["../../../../src/hooks/useSpeechRecognition/useSpeechRecognition.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/** The use speech recognition hook options type */\ninterface UseSpeechRecognitionOptions {\n /** If true, recognition continues even after pauses in speech. Default is false */\n continuous?: SpeechRecognition['continuous'];\n /** A list of grammar rules */\n grammars?: SpeechRecognition['grammars'];\n /** If true, interim (non-final) results are provided as the user speaks */\n interimResults?: SpeechRecognition['interimResults'];\n /** The language in which recognition should occur. Must be a valid BCP 47 language tag (e.g., \"en-US\", \"ru-RU\") */\n language?: SpeechRecognition['lang'];\n /** The maximum number of alternative transcripts returned for a given recognition result. Must be a positive integer */\n maxAlternatives?: SpeechRecognition['maxAlternatives'];\n /** Callback invoked when speech recognition ends */\n onEnd?: () => void;\n /** Callback invoked when an error occurs during recognition */\n onError?: (error: SpeechRecognitionErrorEvent) => void;\n /** Callback invoked when recognition produces a result */\n onResult?: (event: SpeechRecognitionEvent) => void;\n /** Callback invoked when speech recognition starts */\n onStart?: () => void;\n}\n\n/** The return type of the useSpeechRecognition hook. */\ninterface UseSpeechRecognitionReturn {\n /** The error state */\n error: SpeechRecognitionErrorEvent | null;\n /** The final transcript */\n final: boolean;\n /** Whether the hook is currently listening for speech */\n listening: boolean;\n /** The speech recognition instance */\n recognition: SpeechRecognition;\n /** Whether the current browser supports the Web Speech API */\n supported: boolean;\n /** The current transcript */\n transcript: string;\n /** Begins speech recognition */\n start: () => void;\n /** Ends speech recognition, finalizing results */\n stop: () => void;\n /** Toggles the listening state */\n toggle: (value?: boolean) => void;\n}\n\nexport const getSpeechRecognition = () =>\n window?.SpeechRecognition ?? window?.webkitSpeechRecognition;\n\n/**\n * @name useSpeechRecognition\n * @description - Hook that provides a streamlined interface for incorporating speech-to-text functionality\n * @category Browser\n * @usage low\n *\n * @browserapi window.SpeechRecognition https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition\n *\n * @param {boolean} [options.continuous=false] Whether recognition should continue after pauses\n * @param {boolean} [options.interimResults=false] Whether interim results should be provided\n * @param {string} [options.language=\"en-US\"] The language for recognition, as a valid BCP 47 tag\n * @param {number} [options.maxAlternatives=1] The maximum number of alternative transcripts to return\n * @param {SpeechGrammarList} [options.grammars] A list of grammar rules\n * @param {() => void} [options.onStart] Callback invoked when speech recognition starts\n * @param {() => void} [options.onEnd] Callback invoked when speech recognition ends\n * @param {(error: SpeechRecognitionErrorEvent) => void} [options.onError] Callback invoked when an error occurs during recognition\n * @param {(event: SpeechRecognitionEvent) => void} [options.onResult] Callback invoked when recognition produces a result\n * @returns {UseSpeechRecognitionReturn} An object containing the speech recognition functionality\n *\n * @example\n * const { supported, value, recognition, listening, error, start, stop, toggle } = useSpeechRecognition();\n */\nexport const useSpeechRecognition = (\n options: UseSpeechRecognitionOptions = {}\n): UseSpeechRecognitionReturn => {\n const supported = typeof window !== 'undefined' && !!getSpeechRecognition();\n\n const {\n continuous = false,\n interimResults = false,\n language = 'en-US',\n grammars,\n maxAlternatives = 1,\n onStart,\n onEnd,\n onError,\n onResult\n } = options;\n\n const [listening, setListening] = useState(false);\n const [transcript, setTranscript] = useState('');\n const [final, setFinal] = useState(false);\n const [error, setError] = useState<SpeechRecognitionErrorEvent | null>(null);\n const [recognition] = useState<SpeechRecognition>(() => {\n if (!supported) return {} as SpeechRecognition;\n\n const SpeechRecognition = getSpeechRecognition();\n const speechRecognition = new SpeechRecognition();\n\n speechRecognition.continuous = continuous;\n if (grammars) speechRecognition.grammars = grammars;\n speechRecognition.interimResults = interimResults;\n speechRecognition.lang = language;\n speechRecognition.maxAlternatives = maxAlternatives;\n\n speechRecognition.onstart = () => {\n setListening(true);\n setFinal(false);\n onStart?.();\n };\n speechRecognition.onend = () => {\n setListening(false);\n onEnd?.();\n };\n speechRecognition.onerror = (event) => {\n setError(event);\n setListening(false);\n onError?.(event);\n };\n speechRecognition.onresult = (event) => {\n const currentResult = event.results[event.resultIndex];\n const { transcript } = currentResult[0];\n\n setTranscript(transcript);\n setError(null);\n onResult?.(event);\n };\n speechRecognition.onend = () => {\n setListening(false);\n speechRecognition.lang = language;\n };\n\n return speechRecognition;\n });\n\n useEffect(() => () => recognition.stop(), []);\n\n const start = () => recognition.start();\n const stop = () => recognition.stop();\n\n const toggle = (value = !listening) => {\n if (value) return start();\n stop();\n };\n\n return {\n supported,\n transcript,\n recognition,\n final,\n listening,\n error,\n start,\n stop,\n toggle\n };\n};\n"],"names":["getSpeechRecognition","useSpeechRecognition","options","supported","continuous","interimResults","language","grammars","maxAlternatives","onStart","onEnd","onError","onResult","listening","setListening","useState","transcript","setTranscript","final","setFinal","error","setError","recognition","SpeechRecognition","speechRecognition","event","currentResult","useEffect","start","stop","value"],"mappings":";AA8CO,MAAMA,IAAuB,MAClC,QAAQ,qBAAqB,QAAQ,yBAwB1BC,IAAuB,CAClCC,IAAuC,OACR;AAC/B,QAAMC,IAAY,OAAO,SAAW,OAAe,CAAC,CAACH,EAAA,GAE/C;AAAA,IACJ,YAAAI,IAAa;AAAA,IACb,gBAAAC,IAAiB;AAAA,IACjB,UAAAC,IAAW;AAAA,IACX,UAAAC;AAAA,IACA,iBAAAC,IAAkB;AAAA,IAClB,SAAAC;AAAA,IACA,OAAAC;AAAA,IACA,SAAAC;AAAA,IACA,UAAAC;AAAA,EAAA,IACEV,GAEE,CAACW,GAAWC,CAAY,IAAIC,EAAS,EAAK,GAC1C,CAACC,GAAYC,CAAa,IAAIF,EAAS,EAAE,GACzC,CAACG,GAAOC,CAAQ,IAAIJ,EAAS,EAAK,GAClC,CAACK,GAAOC,CAAQ,IAAIN,EAA6C,IAAI,GACrE,CAACO,CAAW,IAAIP,EAA4B,MAAM;AACtD,QAAI,CAACZ,EAAW,QAAO,CAAA;AAEvB,UAAMoB,IAAoBvB,EAAA,GACpBwB,IAAoB,IAAID,EAAA;AAE9B,WAAAC,EAAkB,aAAapB,GAC3BG,QAA4B,WAAWA,IAC3CiB,EAAkB,iBAAiBnB,GACnCmB,EAAkB,OAAOlB,GACzBkB,EAAkB,kBAAkBhB,GAEpCgB,EAAkB,UAAU,MAAM;AAChC,MAAAV,EAAa,EAAI,GACjBK,EAAS,EAAK,GACdV,IAAA;AAAA,IAAU,GAEZe,EAAkB,QAAQ,MAAM;AAC9B,MAAAV,EAAa,EAAK,GAClBJ,IAAA;AAAA,IAAQ,GAEVc,EAAkB,UAAU,CAACC,MAAU;AACrC,MAAAJ,EAASI,CAAK,GACdX,EAAa,EAAK,GAClBH,IAAUc,CAAK;AAAA,IAAA,GAEjBD,EAAkB,WAAW,CAACC,MAAU;AACtC,YAAMC,IAAgBD,EAAM,QAAQA,EAAM,WAAW,GAC/C,EAAE,YAAAT,MAAeU,EAAc,CAAC;AAEtC,MAAAT,EAAcD,CAAU,GACxBK,EAAS,IAAI,GACbT,IAAWa,CAAK;AAAA,IAAA,GAElBD,EAAkB,QAAQ,MAAM;AAC9B,MAAAV,EAAa,EAAK,GAClBU,EAAkB,OAAOlB;AAAA,IAAA,GAGpBkB;AAAA,EAAA,CACR;AAED,EAAAG,EAAU,MAAM,MAAML,EAAY,KAAA,GAAQ,CAAA,CAAE;AAE5C,QAAMM,IAAQ,MAAMN,EAAY,MAAA,GAC1BO,IAAO,MAAMP,EAAY,KAAA;AAO/B,SAAO;AAAA,IACL,WAAAnB;AAAA,IACA,YAAAa;AAAA,IACA,aAAAM;AAAA,IACA,OAAAJ;AAAA,IACA,WAAAL;AAAA,IACA,OAAAO;AAAA,IACA,OAAAQ;AAAA,IACA,MAAAC;AAAA,IACA,QAda,CAACC,IAAQ,CAACjB,MAAc;AACrC,UAAIiB,UAAcF,EAAA;AAClB,MAAAC,EAAA;AAAA,IAAK;AAAA,EAYL;AAEJ;"}
|
|
@@ -1,50 +1,65 @@
|
|
|
1
|
-
import { useState as r,
|
|
2
|
-
const
|
|
3
|
-
const t = typeof window < "u" && "speechSynthesis" in window && !!window.speechSynthesis, { text:
|
|
4
|
-
e.lang =
|
|
5
|
-
|
|
1
|
+
import { useState as r, useEffect as v } from "react";
|
|
2
|
+
const R = (S = {}) => {
|
|
3
|
+
const t = typeof window < "u" && "speechSynthesis" in window && !!window.speechSynthesis, { text: u = "", lang: a = "en-US", pitch: p = 1, rate: l = 1, voice: n = null, volume: w = 1 } = S, [f, s] = r(!1), [y, o] = r("init"), [m, g] = r(), [c, d] = r(), h = (e) => {
|
|
4
|
+
e.lang = a, e.pitch = p, e.rate = l, e.volume = w, e.voice = n, e.onstart = () => {
|
|
5
|
+
s(!0), o("play");
|
|
6
6
|
}, e.onpause = () => {
|
|
7
|
-
|
|
7
|
+
s(!1), o("pause");
|
|
8
8
|
}, e.onresume = () => {
|
|
9
|
-
|
|
9
|
+
s(!0), o("play");
|
|
10
10
|
}, e.onend = () => {
|
|
11
|
-
|
|
12
|
-
}, e.onerror = (
|
|
13
|
-
|
|
11
|
+
s(!1), o("end");
|
|
12
|
+
}, e.onerror = (i) => {
|
|
13
|
+
s(!1), g(i);
|
|
14
14
|
};
|
|
15
15
|
};
|
|
16
|
-
|
|
16
|
+
return v(() => {
|
|
17
17
|
if (!t) return;
|
|
18
|
-
const e = new SpeechSynthesisUtterance(
|
|
19
|
-
return
|
|
18
|
+
const e = new SpeechSynthesisUtterance(u);
|
|
19
|
+
return h(e), d(e), () => {
|
|
20
20
|
window.speechSynthesis?.cancel();
|
|
21
21
|
};
|
|
22
|
-
}, [
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
n
|
|
31
|
-
|
|
32
|
-
n
|
|
33
|
-
|
|
34
|
-
return {
|
|
22
|
+
}, [
|
|
23
|
+
u,
|
|
24
|
+
a,
|
|
25
|
+
p,
|
|
26
|
+
l,
|
|
27
|
+
w,
|
|
28
|
+
n?.default,
|
|
29
|
+
n?.lang,
|
|
30
|
+
n?.localService,
|
|
31
|
+
n?.name,
|
|
32
|
+
n?.voiceURI
|
|
33
|
+
]), {
|
|
35
34
|
supported: t,
|
|
36
|
-
playing:
|
|
37
|
-
status:
|
|
38
|
-
utterance:
|
|
39
|
-
error:
|
|
40
|
-
stop:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
playing: f,
|
|
36
|
+
status: y,
|
|
37
|
+
utterance: c,
|
|
38
|
+
error: m,
|
|
39
|
+
stop: () => {
|
|
40
|
+
t && (window.speechSynthesis?.cancel(), s(!1));
|
|
41
|
+
},
|
|
42
|
+
toggle: (e = !f) => {
|
|
43
|
+
t && (e ? window.speechSynthesis?.resume() : window.speechSynthesis?.pause(), s(e));
|
|
44
|
+
},
|
|
45
|
+
speak: (e) => {
|
|
46
|
+
if (t) {
|
|
47
|
+
if (e) {
|
|
48
|
+
const i = new SpeechSynthesisUtterance(e);
|
|
49
|
+
d(i), h(i);
|
|
50
|
+
}
|
|
51
|
+
window.speechSynthesis?.cancel(), c && window.speechSynthesis?.speak(c), s(!0);
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
resume: () => {
|
|
55
|
+
s(!0), window.speechSynthesis?.resume();
|
|
56
|
+
},
|
|
57
|
+
pause: () => {
|
|
58
|
+
s(!1), window.speechSynthesis?.pause();
|
|
59
|
+
}
|
|
45
60
|
};
|
|
46
61
|
};
|
|
47
62
|
export {
|
|
48
|
-
|
|
63
|
+
R as useSpeechSynthesis
|
|
49
64
|
};
|
|
50
65
|
//# sourceMappingURL=useSpeechSynthesis.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSpeechSynthesis.mjs","sources":["../../../../src/hooks/useSpeechSynthesis/useSpeechSynthesis.ts"],"sourcesContent":["import { useEffect,
|
|
1
|
+
{"version":3,"file":"useSpeechSynthesis.mjs","sources":["../../../../src/hooks/useSpeechSynthesis/useSpeechSynthesis.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/** The use speech synthesis status type */\nexport type UseSpeechSynthesisStatus = 'end' | 'init' | 'pause' | 'play';\n\n/** The use speech synthesis options type */\nexport interface UseSpeechSynthesisOptions {\n /** Language for SpeechSynthesis */\n lang?: string;\n /** Gets and sets the pitch at which the utterance will be spoken at. */\n pitch?: number;\n /** Gets and sets the speed at which the utterance will be spoken at. */\n rate?: number;\n /** The text to be spoken */\n text?: string;\n /** Gets and sets the voice that will be used to speak the utterance. */\n voice?: SpeechSynthesisVoice | null;\n /** Gets and sets the volume that the utterance will be spoken at. */\n volume?: number;\n}\n\n/** The use speech synthesis return type */\nexport interface UseSpeechSynthesisReturn {\n /** Any error that occurred during speech synthesis. */\n error: SpeechSynthesisErrorEvent | undefined;\n /** Indicates if speech is currently playing. */\n playing: boolean;\n /** The current status of speech synthesis. */\n status: UseSpeechSynthesisStatus;\n /** Indicates if the SpeechSynthesis API is supported in the current environment. */\n supported: boolean;\n /** The SpeechSynthesisUtterance instance. */\n utterance: SpeechSynthesisUtterance | undefined;\n /** Function to pause speech synthesis. */\n pause: () => void;\n /** Function to resume speech synthesis. */\n resume: () => void;\n /** Function to start speech synthesis. */\n speak: () => void;\n /** Function to stop speech synthesis. */\n stop: () => void;\n /** Function to toggle between play and pause. */\n toggle: (value?: boolean) => void;\n}\n\n/**\n * @name useSpeechSynthesis\n * @description - Hook that provides speech synthesis functionality\n * @category Browser\n * @usage low\n *\n * @browserapi SpeechSynthesis https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis\n *\n * @params {string} [options.text] - The text to be spoken\n * @params {string} [options.lang] - The language to be spoken\n * @params {number} [options.pitch] - The pitch to be spoken\n * @params {number} [options.rate] - The rate to be spoken\n * @params {SpeechSynthesisVoice} [options.voice] - The voice to be spoken\n * @params {number} [options.volume] - The volume to be spoken\n * @returns {UseSpeechSynthesisReturn} An object containing the speech synthesis state and control methods\n *\n * @example\n * const { supported, playing, status, utterance, error, stop, toggle, speak, resume, pause } = useSpeechSynthesis();\n */\nexport const useSpeechSynthesis = (\n options: UseSpeechSynthesisOptions = {}\n): UseSpeechSynthesisReturn => {\n const supported =\n typeof window !== 'undefined' && 'speechSynthesis' in window && !!window.speechSynthesis;\n\n const { text = '', lang = 'en-US', pitch = 1, rate = 1, voice = null, volume = 1 } = options;\n\n const [playing, setPlaying] = useState(false);\n const [status, setStatus] = useState<UseSpeechSynthesisStatus>('init');\n const [error, setError] = useState<SpeechSynthesisErrorEvent>();\n\n const [utterance, setUtterance] = useState<SpeechSynthesisUtterance>();\n\n const bindSpeechSynthesisUtterance = (speechSynthesisUtterance: SpeechSynthesisUtterance) => {\n speechSynthesisUtterance.lang = lang;\n speechSynthesisUtterance.pitch = pitch;\n speechSynthesisUtterance.rate = rate;\n speechSynthesisUtterance.volume = volume;\n speechSynthesisUtterance.voice = voice;\n\n speechSynthesisUtterance.onstart = () => {\n setPlaying(true);\n setStatus('play');\n };\n\n speechSynthesisUtterance.onpause = () => {\n setPlaying(false);\n setStatus('pause');\n };\n\n speechSynthesisUtterance.onresume = () => {\n setPlaying(true);\n setStatus('play');\n };\n\n speechSynthesisUtterance.onend = () => {\n setPlaying(false);\n setStatus('end');\n };\n\n speechSynthesisUtterance.onerror = (event) => {\n setPlaying(false);\n setError(event);\n };\n };\n\n useEffect(() => {\n if (!supported) return;\n\n const speechSynthesisUtterance = new SpeechSynthesisUtterance(text);\n\n bindSpeechSynthesisUtterance(speechSynthesisUtterance);\n setUtterance(speechSynthesisUtterance);\n\n return () => {\n window.speechSynthesis?.cancel();\n };\n }, [\n text,\n lang,\n pitch,\n rate,\n volume,\n voice?.default,\n voice?.lang,\n voice?.localService,\n voice?.name,\n voice?.voiceURI\n ]);\n\n const speak = (text?: string) => {\n if (!supported) return;\n\n if (text) {\n const utterance = new SpeechSynthesisUtterance(text);\n setUtterance(utterance);\n bindSpeechSynthesisUtterance(utterance);\n }\n\n window.speechSynthesis?.cancel();\n if (utterance) window.speechSynthesis?.speak(utterance);\n setPlaying(true);\n };\n\n const stop = () => {\n if (!supported) return;\n\n window.speechSynthesis?.cancel();\n setPlaying(false);\n };\n\n const toggle = (value = !playing) => {\n if (!supported) return;\n\n if (value) {\n window.speechSynthesis?.resume();\n } else {\n window.speechSynthesis?.pause();\n }\n setPlaying(value);\n };\n\n const resume = () => {\n setPlaying(true);\n window.speechSynthesis?.resume();\n };\n\n const pause = () => {\n setPlaying(false);\n window.speechSynthesis?.pause();\n };\n\n return {\n supported,\n playing,\n status,\n utterance,\n error,\n stop,\n toggle,\n speak,\n resume,\n pause\n };\n};\n"],"names":["useSpeechSynthesis","options","supported","text","lang","pitch","rate","voice","volume","playing","setPlaying","useState","status","setStatus","error","setError","utterance","setUtterance","bindSpeechSynthesisUtterance","speechSynthesisUtterance","event","useEffect","value"],"mappings":";AAgEO,MAAMA,IAAqB,CAChCC,IAAqC,OACR;AAC7B,QAAMC,IACJ,OAAO,SAAW,OAAe,qBAAqB,UAAU,CAAC,CAAC,OAAO,iBAErE,EAAE,MAAAC,IAAO,IAAI,MAAAC,IAAO,SAAS,OAAAC,IAAQ,GAAG,MAAAC,IAAO,GAAG,OAAAC,IAAQ,MAAM,QAAAC,IAAS,MAAMP,GAE/E,CAACQ,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtC,CAACC,GAAQC,CAAS,IAAIF,EAAmC,MAAM,GAC/D,CAACG,GAAOC,CAAQ,IAAIJ,EAAA,GAEpB,CAACK,GAAWC,CAAY,IAAIN,EAAA,GAE5BO,IAA+B,CAACC,MAAuD;AAC3F,IAAAA,EAAyB,OAAOf,GAChCe,EAAyB,QAAQd,GACjCc,EAAyB,OAAOb,GAChCa,EAAyB,SAASX,GAClCW,EAAyB,QAAQZ,GAEjCY,EAAyB,UAAU,MAAM;AACvC,MAAAT,EAAW,EAAI,GACfG,EAAU,MAAM;AAAA,IAAA,GAGlBM,EAAyB,UAAU,MAAM;AACvC,MAAAT,EAAW,EAAK,GAChBG,EAAU,OAAO;AAAA,IAAA,GAGnBM,EAAyB,WAAW,MAAM;AACxC,MAAAT,EAAW,EAAI,GACfG,EAAU,MAAM;AAAA,IAAA,GAGlBM,EAAyB,QAAQ,MAAM;AACrC,MAAAT,EAAW,EAAK,GAChBG,EAAU,KAAK;AAAA,IAAA,GAGjBM,EAAyB,UAAU,CAACC,MAAU;AAC5C,MAAAV,EAAW,EAAK,GAChBK,EAASK,CAAK;AAAA,IAAA;AAAA,EAChB;AAGF,SAAAC,EAAU,MAAM;AACd,QAAI,CAACnB,EAAW;AAEhB,UAAMiB,IAA2B,IAAI,yBAAyBhB,CAAI;AAElE,WAAAe,EAA6BC,CAAwB,GACrDF,EAAaE,CAAwB,GAE9B,MAAM;AACX,aAAO,iBAAiB,OAAA;AAAA,IAAO;AAAA,EACjC,GACC;AAAA,IACDhB;AAAA,IACAC;AAAA,IACAC;AAAA,IACAC;AAAA,IACAE;AAAA,IACAD,GAAO;AAAA,IACPA,GAAO;AAAA,IACPA,GAAO;AAAA,IACPA,GAAO;AAAA,IACPA,GAAO;AAAA,EAAA,CACR,GA4CM;AAAA,IACL,WAAAL;AAAA,IACA,SAAAO;AAAA,IACA,QAAAG;AAAA,IACA,WAAAI;AAAA,IACA,OAAAF;AAAA,IACA,MAlCW,MAAM;AACjB,MAAKZ,MAEL,OAAO,iBAAiB,OAAA,GACxBQ,EAAW,EAAK;AAAA,IAAA;AAAA,IA+BhB,QA5Ba,CAACY,IAAQ,CAACb,MAAY;AACnC,MAAKP,MAEDoB,IACF,OAAO,iBAAiB,OAAA,IAExB,OAAO,iBAAiB,MAAA,GAE1BZ,EAAWY,CAAK;AAAA,IAAA;AAAA,IAqBhB,OAlDY,CAACnB,MAAkB;AAC/B,UAAKD,GAEL;AAAA,YAAIC,GAAM;AACR,gBAAMa,IAAY,IAAI,yBAAyBb,CAAI;AACnD,UAAAc,EAAaD,CAAS,GACtBE,EAA6BF,CAAS;AAAA,QAAA;AAGxC,eAAO,iBAAiB,OAAA,GACpBA,KAAW,OAAO,iBAAiB,MAAMA,CAAS,GACtDN,EAAW,EAAI;AAAA;AAAA,IAAA;AAAA,IAwCf,QAnBa,MAAM;AACnB,MAAAA,EAAW,EAAI,GACf,OAAO,iBAAiB,OAAA;AAAA,IAAO;AAAA,IAkB/B,OAfY,MAAM;AAClB,MAAAA,EAAW,EAAK,GAChB,OAAO,iBAAiB,MAAA;AAAA,IAAM;AAAA,EAa9B;AAEJ;"}
|
|
@@ -1,60 +1,63 @@
|
|
|
1
|
-
import { useState as V, useEffect as
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
t.setItem(n,
|
|
1
|
+
import { useState as V, useEffect as m } from "react";
|
|
2
|
+
const u = "reactuse-storage", g = (t) => window.dispatchEvent(new StorageEvent(u, t)), l = (t, n, r) => {
|
|
3
|
+
const o = t.getItem(n);
|
|
4
|
+
t.setItem(n, r), g({
|
|
5
5
|
key: n,
|
|
6
|
-
oldValue:
|
|
7
|
-
newValue:
|
|
6
|
+
oldValue: o,
|
|
7
|
+
newValue: r,
|
|
8
8
|
storageArea: t
|
|
9
9
|
});
|
|
10
|
-
},
|
|
11
|
-
const
|
|
12
|
-
t.removeItem(n),
|
|
13
|
-
},
|
|
14
|
-
const
|
|
15
|
-
if (
|
|
16
|
-
return
|
|
17
|
-
},
|
|
18
|
-
const
|
|
10
|
+
}, z = (t, n) => {
|
|
11
|
+
const r = t.getItem(n);
|
|
12
|
+
t.removeItem(n), g({ key: n, oldValue: r, newValue: null, storageArea: t });
|
|
13
|
+
}, f = (t, n) => {
|
|
14
|
+
const r = t.getItem(n);
|
|
15
|
+
if (r)
|
|
16
|
+
return r;
|
|
17
|
+
}, p = ((t, n) => {
|
|
18
|
+
const r = typeof n == "object" && n && ("serializer" in n || "deserializer" in n || "initialValue" in n || "storage" in n) ? n : void 0, o = r ? r?.initialValue : n;
|
|
19
19
|
if (typeof window > "u")
|
|
20
20
|
return {
|
|
21
|
-
value: typeof
|
|
21
|
+
value: typeof o == "function" ? o() : o,
|
|
22
22
|
set: () => {
|
|
23
23
|
},
|
|
24
24
|
remove: () => {
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
|
-
const
|
|
28
|
-
if (
|
|
27
|
+
const a = (e) => r?.serializer ? r.serializer(e) : typeof e == "string" ? e : JSON.stringify(e), i = r?.storage ?? window?.localStorage, v = (e) => l(i, t, a(e)), w = () => z(i, t), c = (e) => {
|
|
28
|
+
if (r?.deserializer) return r.deserializer(e);
|
|
29
29
|
if (e !== "undefined")
|
|
30
30
|
try {
|
|
31
31
|
return JSON.parse(e);
|
|
32
32
|
} catch {
|
|
33
33
|
return e;
|
|
34
34
|
}
|
|
35
|
-
}, [
|
|
36
|
-
const e =
|
|
37
|
-
if (e === void 0 &&
|
|
38
|
-
const s = typeof
|
|
39
|
-
return
|
|
35
|
+
}, [E, S] = V(() => {
|
|
36
|
+
const e = f(i, t);
|
|
37
|
+
if (e === void 0 && o !== void 0) {
|
|
38
|
+
const s = typeof o == "function" ? o() : o;
|
|
39
|
+
return l(i, t, a(s)), s;
|
|
40
40
|
}
|
|
41
|
-
return e ?
|
|
41
|
+
return e ? c(e) : void 0;
|
|
42
42
|
});
|
|
43
|
-
return
|
|
44
|
-
const e = () => {
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
return m(() => {
|
|
44
|
+
const e = (s) => {
|
|
45
|
+
if (s && s.storageArea !== i || s && s.key !== t) return;
|
|
46
|
+
const d = f(i, t);
|
|
47
|
+
S(d ? c(d) : void 0);
|
|
48
|
+
};
|
|
49
|
+
return window.addEventListener(u, e), window.addEventListener("storage", e, { passive: !0 }), () => {
|
|
50
|
+
window.removeEventListener(u, e), window.removeEventListener("storage", e);
|
|
47
51
|
};
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
remove: v
|
|
52
|
+
}, [t, i]), {
|
|
53
|
+
value: E,
|
|
54
|
+
set: v,
|
|
55
|
+
remove: w
|
|
53
56
|
};
|
|
54
57
|
});
|
|
55
58
|
export {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
u as STORAGE_EVENT,
|
|
60
|
+
g as dispatchStorageEvent,
|
|
61
|
+
p as useStorage
|
|
59
62
|
};
|
|
60
63
|
//# sourceMappingURL=useStorage.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStorage.mjs","sources":["../../../../src/hooks/useStorage/useStorage.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/* The use storage initial value type */\nexport type UseStorageInitialValue<Value> = (() => Value) | Value;\n\n/* The use storage options type */\nexport interface UseStorageOptions<Value> {\n /* The initial value of the storage */\n initialValue?: UseStorageInitialValue<Value>;\n /* The storage to be used */\n storage?: Storage;\n /* The deserializer function to be invoked */\n deserializer?: (value: string) => Value;\n /* The serializer function to be invoked */\n serializer?: (value: Value) => string;\n}\n\n/* The use storage return type */\nexport interface UseStorageReturn<Value> {\n /* The value of the storage */\n value: Value;\n /* The error state of the storage */\n remove: () => void;\n /* The loading state of the storage */\n set: (value: Value) => void;\n}\n\nexport interface UseStorage {\n <Value>(key: string, options?: UseStorageOptions<Value>): UseStorageReturn<Value | undefined>;\n\n <Value>(\n key: string,\n initialValue?: UseStorageInitialValue<Value>\n ): UseStorageReturn<Value | undefined>;\n}\n\nexport const STORAGE_EVENT = 'reactuse-storage';\n\nexport const dispatchStorageEvent = (params: Partial<StorageEvent>) =>\n window.dispatchEvent(new StorageEvent(STORAGE_EVENT, params));\n\nconst setStorageItem = (storage: Storage, key: string, value: string) => {\n const oldValue = storage.getItem(key);\n\n storage.setItem(key, value);\n dispatchStorageEvent({\n key,\n oldValue,\n newValue: value,\n storageArea: storage\n });\n};\n\nconst removeStorageItem = (storage: Storage, key: string) => {\n const oldValue = storage.getItem(key);\n\n storage.removeItem(key);\n dispatchStorageEvent({ key, oldValue, newValue: null, storageArea: storage });\n};\n\nconst getStorageItem = (storage: Storage, key: string) => {\n const value = storage.getItem(key);\n if (!value) return undefined;\n return value;\n};\n\n/**\n * @name useStorage\n * @description - Hook that manages storage value\n * @category State\n * @usage high\n *\n * @overload\n * @param {string} key The key of the storage\n * @param {UseStorageInitialValue<Value>} [initialValue] The initial value of the storage\n * @returns {UseStorageReturn<Value>} The value and the set function\n *\n * @overload\n * @param {string} key The key of the storage\n * @param {(value: Value) => string} [params.serializer] The serializer function\n * @param {(value: string) => Value} [params.deserializer] The deserializer function\n * @param {Storage} [params.storage] The storage\n * @param {UseStorageInitialValue<Value>} [params.initialValue] The initial value of the storage\n * @returns {UseStorageReturn<Value>} The value and the set function\n *\n * @example\n * const { value, set, remove } = useStorage('key', 'value');\n */\nexport const useStorage = (<Value>(key: string, params?: any): UseStorageReturn<Value> => {\n const options = (\n typeof params === 'object' &&\n params &&\n ('serializer' in params ||\n 'deserializer' in params ||\n 'initialValue' in params ||\n 'storage' in params)\n ? params\n : undefined\n ) as UseStorageOptions<Value>;\n\n const initialValue = (options ? options?.initialValue : params) as UseStorageInitialValue<Value>;\n\n if (typeof window === 'undefined') {\n const value = typeof initialValue === 'function' ? (initialValue as () => any)() : initialValue;\n return {\n value,\n set: () => {},\n remove: () => {}\n };\n }\n\n const serializer = (value: Value) => {\n if (options?.serializer) return options.serializer(value);\n if (typeof value === 'string') return value;\n return JSON.stringify(value);\n };\n\n const storage = options?.storage ?? window?.localStorage;\n\n const set = (value: Value) => setStorageItem(storage, key, serializer(value));\n const remove = () => removeStorageItem(storage, key);\n\n const deserializer = (value: string) => {\n if (options?.deserializer) return options.deserializer(value);\n if (value === 'undefined') return undefined as unknown as Value;\n\n try {\n return JSON.parse(value) as Value;\n } catch {\n return value as Value;\n }\n };\n\n const [value, setValue] = useState<Value | undefined>(() => {\n const storageValue = getStorageItem(storage, key);\n if (storageValue === undefined && initialValue !== undefined) {\n const value =\n typeof initialValue === 'function' ? (initialValue as () => Value)() : initialValue;\n setStorageItem(storage, key, serializer(value));\n return value;\n }\n return storageValue ? deserializer(storageValue) : undefined;\n });\n\n useEffect(() => {\n const onChange = () => {\n const storageValue = getStorageItem(storage, key);\n setValue(storageValue ? deserializer(storageValue) : undefined);\n };\n window.addEventListener(STORAGE_EVENT, onChange);\n return () => window.removeEventListener(STORAGE_EVENT, onChange);\n }, [key]);\n\n return {\n value: value as Value,\n set,\n remove\n };\n}) as UseStorage;\n"],"names":["STORAGE_EVENT","dispatchStorageEvent","params","setStorageItem","storage","key","value","oldValue","removeStorageItem","getStorageItem","useStorage","options","initialValue","serializer","set","remove","deserializer","setValue","useState","storageValue","useEffect","onChange"],"mappings":";AAoCO,MAAMA,IAAgB,oBAEhBC,IAAuB,CAACC,MACnC,OAAO,cAAc,IAAI,aAAaF,GAAeE,CAAM,CAAC,GAExDC,IAAiB,CAACC,GAAkBC,GAAaC,MAAkB;AACvE,QAAMC,IAAWH,EAAQ,QAAQC,CAAG;AAEpC,EAAAD,EAAQ,QAAQC,GAAKC,CAAK,GAC1BL,EAAqB;AAAA,IACnB,KAAAI;AAAA,IACA,UAAAE;AAAA,IACA,UAAUD;AAAA,IACV,aAAaF;AAAA,EAAA,CACd;AACH,GAEMI,IAAoB,CAACJ,GAAkBC,MAAgB;AAC3D,QAAME,IAAWH,EAAQ,QAAQC,CAAG;AAEpC,EAAAD,EAAQ,WAAWC,CAAG,GACtBJ,EAAqB,EAAE,KAAAI,GAAK,UAAAE,GAAU,UAAU,MAAM,aAAaH,GAAS;AAC9E,GAEMK,IAAiB,CAACL,GAAkBC,MAAgB;AACxD,QAAMC,IAAQF,EAAQ,QAAQC,CAAG;AACjC,MAAKC;AACL,WAAOA;AACT,GAwBaI,KAAc,CAAQL,GAAaH,MAA0C;AACxF,QAAMS,IACJ,OAAOT,KAAW,YAClBA,MACC,gBAAgBA,KACf,kBAAkBA,KAClB,kBAAkBA,KAClB,aAAaA,KACXA,IACA,QAGAU,IAAgBD,IAAUA,GAAS,eAAeT;AAExD,MAAI,OAAO,SAAW;AAEpB,WAAO;AAAA,MACL,OAFY,OAAOU,KAAiB,aAAcA,MAA+BA;AAAA,MAGjF,KAAK,MAAM;AAAA,MAAA;AAAA,MACX,QAAQ,MAAM;AAAA,MAAA;AAAA,IAAC;AAInB,QAAMC,IAAa,CAACP,MACdK,GAAS,aAAmBA,EAAQ,WAAWL,CAAK,IACpD,OAAOA,KAAU,WAAiBA,IAC/B,KAAK,UAAUA,CAAK,GAGvBF,IAAUO,GAAS,WAAW,QAAQ,cAEtCG,IAAM,CAACR,MAAiBH,EAAeC,GAASC,GAAKQ,EAAWP,CAAK,CAAC,GACtES,IAAS,MAAMP,EAAkBJ,GAASC,CAAG,GAE7CW,IAAe,CAACV,MAAkB;AACtC,QAAIK,GAAS,aAAc,QAAOA,EAAQ,aAAaL,CAAK;AAC5D,QAAIA,MAAU;AAEd,UAAI;AACF,eAAO,KAAK,MAAMA,CAAK;AAAA,MAAA,QACjB;AACN,eAAOA;AAAAA,MAAA;AAAA,EACT,GAGI,CAACA,GAAOW,CAAQ,IAAIC,EAA4B,MAAM;AAC1D,UAAMC,IAAeV,EAAeL,GAASC,CAAG;AAChD,QAAIc,MAAiB,UAAaP,MAAiB,QAAW;AAC5D,YAAMN,IACJ,OAAOM,KAAiB,aAAcA,MAAiCA;AACzE,aAAAT,EAAeC,GAASC,GAAKQ,EAAWP,CAAK,CAAC,GACvCA;AAAAA,IAAA;AAET,WAAOa,IAAeH,EAAaG,CAAY,IAAI;AAAA,EAAA,CACpD;AAED,SAAAC,EAAU,MAAM;AACd,UAAMC,IAAW,
|
|
1
|
+
{"version":3,"file":"useStorage.mjs","sources":["../../../../src/hooks/useStorage/useStorage.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/* The use storage initial value type */\nexport type UseStorageInitialValue<Value> = (() => Value) | Value;\n\n/* The use storage options type */\nexport interface UseStorageOptions<Value> {\n /* The initial value of the storage */\n initialValue?: UseStorageInitialValue<Value>;\n /* The storage to be used */\n storage?: Storage;\n /* The deserializer function to be invoked */\n deserializer?: (value: string) => Value;\n /* The serializer function to be invoked */\n serializer?: (value: Value) => string;\n}\n\n/* The use storage return type */\nexport interface UseStorageReturn<Value> {\n /* The value of the storage */\n value: Value;\n /* The error state of the storage */\n remove: () => void;\n /* The loading state of the storage */\n set: (value: Value) => void;\n}\n\nexport interface UseStorage {\n <Value>(key: string, options?: UseStorageOptions<Value>): UseStorageReturn<Value | undefined>;\n\n <Value>(\n key: string,\n initialValue?: UseStorageInitialValue<Value>\n ): UseStorageReturn<Value | undefined>;\n}\n\nexport const STORAGE_EVENT = 'reactuse-storage';\n\nexport const dispatchStorageEvent = (params: Partial<StorageEvent>) =>\n window.dispatchEvent(new StorageEvent(STORAGE_EVENT, params));\n\nconst setStorageItem = (storage: Storage, key: string, value: string) => {\n const oldValue = storage.getItem(key);\n\n storage.setItem(key, value);\n dispatchStorageEvent({\n key,\n oldValue,\n newValue: value,\n storageArea: storage\n });\n};\n\nconst removeStorageItem = (storage: Storage, key: string) => {\n const oldValue = storage.getItem(key);\n\n storage.removeItem(key);\n dispatchStorageEvent({ key, oldValue, newValue: null, storageArea: storage });\n};\n\nconst getStorageItem = (storage: Storage, key: string) => {\n const value = storage.getItem(key);\n if (!value) return undefined;\n return value;\n};\n\n/**\n * @name useStorage\n * @description - Hook that manages storage value\n * @category State\n * @usage high\n *\n * @overload\n * @param {string} key The key of the storage\n * @param {UseStorageInitialValue<Value>} [initialValue] The initial value of the storage\n * @returns {UseStorageReturn<Value>} The value and the set function\n *\n * @overload\n * @param {string} key The key of the storage\n * @param {(value: Value) => string} [params.serializer] The serializer function\n * @param {(value: string) => Value} [params.deserializer] The deserializer function\n * @param {Storage} [params.storage] The storage\n * @param {UseStorageInitialValue<Value>} [params.initialValue] The initial value of the storage\n * @returns {UseStorageReturn<Value>} The value and the set function\n *\n * @example\n * const { value, set, remove } = useStorage('key', 'value');\n */\nexport const useStorage = (<Value>(key: string, params?: any): UseStorageReturn<Value> => {\n const options = (\n typeof params === 'object' &&\n params &&\n ('serializer' in params ||\n 'deserializer' in params ||\n 'initialValue' in params ||\n 'storage' in params)\n ? params\n : undefined\n ) as UseStorageOptions<Value>;\n\n const initialValue = (options ? options?.initialValue : params) as UseStorageInitialValue<Value>;\n\n if (typeof window === 'undefined') {\n const value = typeof initialValue === 'function' ? (initialValue as () => any)() : initialValue;\n return {\n value,\n set: () => {},\n remove: () => {}\n };\n }\n\n const serializer = (value: Value) => {\n if (options?.serializer) return options.serializer(value);\n if (typeof value === 'string') return value;\n return JSON.stringify(value);\n };\n\n const storage = options?.storage ?? window?.localStorage;\n\n const set = (value: Value) => setStorageItem(storage, key, serializer(value));\n const remove = () => removeStorageItem(storage, key);\n\n const deserializer = (value: string) => {\n if (options?.deserializer) return options.deserializer(value);\n if (value === 'undefined') return undefined as unknown as Value;\n\n try {\n return JSON.parse(value) as Value;\n } catch {\n return value as Value;\n }\n };\n\n const [value, setValue] = useState<Value | undefined>(() => {\n const storageValue = getStorageItem(storage, key);\n if (storageValue === undefined && initialValue !== undefined) {\n const value =\n typeof initialValue === 'function' ? (initialValue as () => Value)() : initialValue;\n setStorageItem(storage, key, serializer(value));\n return value;\n }\n return storageValue ? deserializer(storageValue) : undefined;\n });\n\n useEffect(() => {\n const onChange = (event?: StorageEvent) => {\n if (event && event.storageArea !== storage) return;\n if (event && event.key !== key) return;\n\n const storageValue = getStorageItem(storage, key);\n setValue(storageValue ? deserializer(storageValue) : undefined);\n };\n\n window.addEventListener(STORAGE_EVENT, onChange as EventListener);\n window.addEventListener('storage', onChange, { passive: true });\n\n return () => {\n window.removeEventListener(STORAGE_EVENT, onChange as EventListener);\n window.removeEventListener('storage', onChange);\n };\n }, [key, storage]);\n\n return {\n value: value as Value,\n set,\n remove\n };\n}) as UseStorage;\n"],"names":["STORAGE_EVENT","dispatchStorageEvent","params","setStorageItem","storage","key","value","oldValue","removeStorageItem","getStorageItem","useStorage","options","initialValue","serializer","set","remove","deserializer","setValue","useState","storageValue","useEffect","onChange","event"],"mappings":";AAoCO,MAAMA,IAAgB,oBAEhBC,IAAuB,CAACC,MACnC,OAAO,cAAc,IAAI,aAAaF,GAAeE,CAAM,CAAC,GAExDC,IAAiB,CAACC,GAAkBC,GAAaC,MAAkB;AACvE,QAAMC,IAAWH,EAAQ,QAAQC,CAAG;AAEpC,EAAAD,EAAQ,QAAQC,GAAKC,CAAK,GAC1BL,EAAqB;AAAA,IACnB,KAAAI;AAAA,IACA,UAAAE;AAAA,IACA,UAAUD;AAAA,IACV,aAAaF;AAAA,EAAA,CACd;AACH,GAEMI,IAAoB,CAACJ,GAAkBC,MAAgB;AAC3D,QAAME,IAAWH,EAAQ,QAAQC,CAAG;AAEpC,EAAAD,EAAQ,WAAWC,CAAG,GACtBJ,EAAqB,EAAE,KAAAI,GAAK,UAAAE,GAAU,UAAU,MAAM,aAAaH,GAAS;AAC9E,GAEMK,IAAiB,CAACL,GAAkBC,MAAgB;AACxD,QAAMC,IAAQF,EAAQ,QAAQC,CAAG;AACjC,MAAKC;AACL,WAAOA;AACT,GAwBaI,KAAc,CAAQL,GAAaH,MAA0C;AACxF,QAAMS,IACJ,OAAOT,KAAW,YAClBA,MACC,gBAAgBA,KACf,kBAAkBA,KAClB,kBAAkBA,KAClB,aAAaA,KACXA,IACA,QAGAU,IAAgBD,IAAUA,GAAS,eAAeT;AAExD,MAAI,OAAO,SAAW;AAEpB,WAAO;AAAA,MACL,OAFY,OAAOU,KAAiB,aAAcA,MAA+BA;AAAA,MAGjF,KAAK,MAAM;AAAA,MAAA;AAAA,MACX,QAAQ,MAAM;AAAA,MAAA;AAAA,IAAC;AAInB,QAAMC,IAAa,CAACP,MACdK,GAAS,aAAmBA,EAAQ,WAAWL,CAAK,IACpD,OAAOA,KAAU,WAAiBA,IAC/B,KAAK,UAAUA,CAAK,GAGvBF,IAAUO,GAAS,WAAW,QAAQ,cAEtCG,IAAM,CAACR,MAAiBH,EAAeC,GAASC,GAAKQ,EAAWP,CAAK,CAAC,GACtES,IAAS,MAAMP,EAAkBJ,GAASC,CAAG,GAE7CW,IAAe,CAACV,MAAkB;AACtC,QAAIK,GAAS,aAAc,QAAOA,EAAQ,aAAaL,CAAK;AAC5D,QAAIA,MAAU;AAEd,UAAI;AACF,eAAO,KAAK,MAAMA,CAAK;AAAA,MAAA,QACjB;AACN,eAAOA;AAAAA,MAAA;AAAA,EACT,GAGI,CAACA,GAAOW,CAAQ,IAAIC,EAA4B,MAAM;AAC1D,UAAMC,IAAeV,EAAeL,GAASC,CAAG;AAChD,QAAIc,MAAiB,UAAaP,MAAiB,QAAW;AAC5D,YAAMN,IACJ,OAAOM,KAAiB,aAAcA,MAAiCA;AACzE,aAAAT,EAAeC,GAASC,GAAKQ,EAAWP,CAAK,CAAC,GACvCA;AAAAA,IAAA;AAET,WAAOa,IAAeH,EAAaG,CAAY,IAAI;AAAA,EAAA,CACpD;AAED,SAAAC,EAAU,MAAM;AACd,UAAMC,IAAW,CAACC,MAAyB;AAEzC,UADIA,KAASA,EAAM,gBAAgBlB,KAC/BkB,KAASA,EAAM,QAAQjB,EAAK;AAEhC,YAAMc,IAAeV,EAAeL,GAASC,CAAG;AAChD,MAAAY,EAASE,IAAeH,EAAaG,CAAY,IAAI,MAAS;AAAA,IAAA;AAGhE,kBAAO,iBAAiBnB,GAAeqB,CAAyB,GAChE,OAAO,iBAAiB,WAAWA,GAAU,EAAE,SAAS,IAAM,GAEvD,MAAM;AACX,aAAO,oBAAoBrB,GAAeqB,CAAyB,GACnE,OAAO,oBAAoB,WAAWA,CAAQ;AAAA,IAAA;AAAA,EAChD,GACC,CAAChB,GAAKD,CAAO,CAAC,GAEV;AAAA,IACL,OAAAE;AAAA,IACA,KAAAQ;AAAA,IACA,QAAAC;AAAA,EAAA;AAEJ;"}
|