import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { formatNumberWithMask, isNil, normalizeToNumberString } from '../utils'; import type { NativeSyntheticEvent, TextInputFocusEventData } from 'react-native'; import usePrevious from './usePrevious'; export type NumberMaskConfig = { prefix?: string; suffix?: string; delimiter?: string; separator?: string; precision?: number; allowNegative?: boolean; }; type DefaultPropsT = { [key: string]: any }; export type UseHandleNumberFormatProps = T & { value: number | null; onChangeText: (newValue: number | null) => void; config?: NumberMaskConfig; onBlur?: (e: NativeSyntheticEvent) => void; onFocus?: (e: NativeSyntheticEvent) => void; formatInitialValue?: boolean; }; const useHandleNumberFormat = ({ value: valueProp, onChangeText: onChangeTextProp, config, onFocus: onFocusProp, onBlur: onBlurProp, formatInitialValue = true, ...rest }: UseHandleNumberFormatProps) => { const [displayValue, setDisplayValue] = useState(() => !isNil(valueProp) ? formatInitialValue ? `${formatNumberWithMask({ number: valueProp, ...config })}` : `${valueProp}` : '', ); const [isBlur, setIsBlur] = useState(true); const firstRenderRef = useRef(true); const isFirstRender = usePrevious(firstRenderRef.current); const onChangeText = useCallback( (text: string) => { const normalizedNumberString = normalizeToNumberString({ text, ...config }); onChangeTextProp( normalizedNumberString === '' ? null : +normalizeToNumberString({ text, ...config }), ); setDisplayValue(text); }, [config, onChangeTextProp], ); const onBlur = useCallback( (e: NativeSyntheticEvent) => { onBlurProp?.(e); setDisplayValue(`${formatNumberWithMask({ number: valueProp, ...config })}`); setIsBlur(true); }, [config, onBlurProp, valueProp], ); const onFocus = useCallback( (e: NativeSyntheticEvent) => { onFocusProp?.(e); setIsBlur(false); }, [onFocusProp], ); useEffect(() => { firstRenderRef.current = false; }); useEffect(() => { if (!isBlur || isFirstRender.current) return; setDisplayValue(`${formatNumberWithMask({ number: valueProp, ...config })}`); }, [config, formatInitialValue, isBlur, isFirstRender, valueProp]); return useMemo( () => ({ value: displayValue, onChangeText: onChangeText, onFocus, onBlur, ...rest, }), [displayValue, onBlur, onChangeText, onFocus, rest], ); }; export default useHandleNumberFormat;