| | import debounce from 'lodash/debounce'; |
| | import React, { useState, useCallback, useMemo } from 'react'; |
| | import type { SetterOrUpdater } from 'recoil'; |
| | import type { TSetOption } from '~/common'; |
| | import { defaultDebouncedDelay } from '~/common'; |
| |
|
| | |
| | |
| | |
| | function useDebouncedInput<T = unknown>({ |
| | setOption, |
| | setter, |
| | optionKey, |
| | initialValue, |
| | delay = defaultDebouncedDelay, |
| | }: { |
| | setOption?: TSetOption; |
| | setter?: SetterOrUpdater<T>; |
| | optionKey?: string | number; |
| | initialValue: T; |
| | delay?: number; |
| | }): [ |
| | (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | T, numeric?: boolean) => void, |
| | T, |
| | SetterOrUpdater<T>, |
| | |
| | ] { |
| | const [value, setValue] = useState<T>(initialValue); |
| |
|
| | |
| | |
| | |
| | const setDebouncedOption = useMemo( |
| | () => debounce(setOption && optionKey ? setOption(optionKey) : setter || (() => {}), delay), |
| | [setOption, optionKey, setter, delay], |
| | ); |
| |
|
| | |
| | const onChange = useCallback( |
| | (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | T, numeric?: boolean) => { |
| | let newValue: T = |
| | typeof e !== 'object' |
| | ? e |
| | : ((e as React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>).target |
| | .value as unknown as T); |
| | |
| | if (numeric === true && newValue !== undefined && newValue !== '') { |
| | newValue = Number(newValue) as unknown as T; |
| | } |
| | setValue(newValue); |
| | setDebouncedOption(newValue); |
| | }, |
| | [setDebouncedOption], |
| | ); |
| | return [onChange, value, setValue]; |
| | } |
| |
|
| | export default useDebouncedInput; |
| |
|