|
|
@ -4,23 +4,19 @@ import { |
|
|
|
ForwardedRef, |
|
|
|
ForwardedRef, |
|
|
|
forwardRef, |
|
|
|
forwardRef, |
|
|
|
ReactElement, |
|
|
|
ReactElement, |
|
|
|
|
|
|
|
useCallback, |
|
|
|
useEffect, |
|
|
|
useEffect, |
|
|
|
useImperativeHandle, |
|
|
|
useImperativeHandle, |
|
|
|
useMemo, |
|
|
|
useMemo, |
|
|
|
useState, |
|
|
|
useState, |
|
|
|
} from 'react'; |
|
|
|
} from 'react'; |
|
|
|
|
|
|
|
|
|
|
|
import createInputOnChangeHandler, { |
|
|
|
import createInputOnChangeHandler from '../lib/createInputOnChangeHandler'; |
|
|
|
CreateInputOnChangeHandlerOptions, |
|
|
|
|
|
|
|
MapToStateSetter, |
|
|
|
|
|
|
|
} from '../lib/createInputOnChangeHandler'; |
|
|
|
|
|
|
|
import { createTestInputFunction } from '../lib/test_input'; |
|
|
|
import { createTestInputFunction } from '../lib/test_input'; |
|
|
|
import useIsFirstRender from '../hooks/useIsFirstRender'; |
|
|
|
import useIsFirstRender from '../hooks/useIsFirstRender'; |
|
|
|
|
|
|
|
|
|
|
|
type InputWithRefTypeMap = Pick<MapToType, 'number' | 'string'>; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type InputWithRefOptionalPropsWithDefault< |
|
|
|
type InputWithRefOptionalPropsWithDefault< |
|
|
|
TypeName extends keyof InputWithRefTypeMap, |
|
|
|
TypeName extends keyof MapToInputType, |
|
|
|
> = { |
|
|
|
> = { |
|
|
|
createInputOnChangeHandlerOptions?: CreateInputOnChangeHandlerOptions<TypeName>; |
|
|
|
createInputOnChangeHandlerOptions?: CreateInputOnChangeHandlerOptions<TypeName>; |
|
|
|
required?: boolean; |
|
|
|
required?: boolean; |
|
|
@ -31,26 +27,26 @@ type InputWithRefOptionalPropsWithoutDefault = { |
|
|
|
onFirstRender?: (args: { isRequired: boolean }) => void; |
|
|
|
onFirstRender?: (args: { isRequired: boolean }) => void; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
type InputWithRefOptionalProps<TypeName extends keyof InputWithRefTypeMap> = |
|
|
|
type InputWithRefOptionalProps<TypeName extends keyof MapToInputType> = |
|
|
|
InputWithRefOptionalPropsWithDefault<TypeName> & |
|
|
|
InputWithRefOptionalPropsWithDefault<TypeName> & |
|
|
|
InputWithRefOptionalPropsWithoutDefault; |
|
|
|
InputWithRefOptionalPropsWithoutDefault; |
|
|
|
|
|
|
|
|
|
|
|
type InputWithRefProps< |
|
|
|
type InputWithRefProps< |
|
|
|
TypeName extends keyof InputWithRefTypeMap, |
|
|
|
TypeName extends keyof MapToInputType, |
|
|
|
InputComponent extends ReactElement, |
|
|
|
InputComponent extends ReactElement, |
|
|
|
> = InputWithRefOptionalProps<TypeName> & { |
|
|
|
> = InputWithRefOptionalProps<TypeName> & { |
|
|
|
input: InputComponent; |
|
|
|
input: InputComponent; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
type InputForwardedRefContent<TypeName extends keyof InputWithRefTypeMap> = { |
|
|
|
type InputForwardedRefContent<TypeName extends keyof MapToInputType> = { |
|
|
|
getIsChangedByUser?: () => boolean; |
|
|
|
getIsChangedByUser?: () => boolean; |
|
|
|
getValue?: () => InputWithRefTypeMap[TypeName]; |
|
|
|
getValue?: () => MapToInputType[TypeName]; |
|
|
|
isValid?: () => boolean; |
|
|
|
isValid?: () => boolean; |
|
|
|
setValue?: MapToStateSetter[TypeName]; |
|
|
|
setValue?: StateSetter; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const INPUT_TEST_ID = 'input'; |
|
|
|
const INPUT_TEST_ID = 'input'; |
|
|
|
const MAP_TO_INITIAL_VALUE: InputWithRefTypeMap = { |
|
|
|
const MAP_TO_INITIAL_VALUE: MapToInputType = { |
|
|
|
number: 0, |
|
|
|
number: 0, |
|
|
|
string: '', |
|
|
|
string: '', |
|
|
|
}; |
|
|
|
}; |
|
|
@ -65,10 +61,7 @@ const INPUT_WITH_REF_DEFAULT_PROPS: Required< |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const InputWithRef = forwardRef( |
|
|
|
const InputWithRef = forwardRef( |
|
|
|
< |
|
|
|
<TypeName extends keyof MapToInputType, InputComponent extends ReactElement>( |
|
|
|
TypeName extends keyof InputWithRefTypeMap, |
|
|
|
|
|
|
|
InputComponent extends ReactElement, |
|
|
|
|
|
|
|
>( |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
createInputOnChangeHandlerOptions: { |
|
|
|
createInputOnChangeHandlerOptions: { |
|
|
|
postSet: postSetAppend, |
|
|
|
postSet: postSetAppend, |
|
|
@ -94,12 +87,15 @@ const InputWithRef = forwardRef( |
|
|
|
|
|
|
|
|
|
|
|
const isFirstRender = useIsFirstRender(); |
|
|
|
const isFirstRender = useIsFirstRender(); |
|
|
|
|
|
|
|
|
|
|
|
const [inputValue, setInputValue] = useState<InputWithRefTypeMap[TypeName]>( |
|
|
|
const [inputValue, setInputValue] = |
|
|
|
initValue, |
|
|
|
useState<MapToInputType[TypeName]>(initValue); |
|
|
|
) as [InputWithRefTypeMap[TypeName], MapToStateSetter[TypeName]]; |
|
|
|
|
|
|
|
const [isChangedByUser, setIsChangedByUser] = useState<boolean>(false); |
|
|
|
const [isChangedByUser, setIsChangedByUser] = useState<boolean>(false); |
|
|
|
const [isInputValid, setIsInputValid] = useState<boolean>(false); |
|
|
|
const [isInputValid, setIsInputValid] = useState<boolean>(false); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const setValue: StateSetter = useCallback((value) => { |
|
|
|
|
|
|
|
setInputValue(value as MapToInputType[TypeName]); |
|
|
|
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
|
|
const testInput: TestInputFunction | undefined = useMemo(() => { |
|
|
|
const testInput: TestInputFunction | undefined = useMemo(() => { |
|
|
|
let result; |
|
|
|
let result; |
|
|
|
|
|
|
|
|
|
|
@ -143,7 +139,7 @@ const InputWithRef = forwardRef( |
|
|
|
initOnChange?.call(null, ...args); |
|
|
|
initOnChange?.call(null, ...args); |
|
|
|
postSetAppend?.call(null, ...args); |
|
|
|
postSetAppend?.call(null, ...args); |
|
|
|
}, |
|
|
|
}, |
|
|
|
set: setInputValue, |
|
|
|
set: setValue, |
|
|
|
setType: valueType, |
|
|
|
setType: valueType, |
|
|
|
...restCreateInputOnChangeHandlerOptions, |
|
|
|
...restCreateInputOnChangeHandlerOptions, |
|
|
|
}); |
|
|
|
}); |
|
|
@ -160,9 +156,9 @@ const InputWithRef = forwardRef( |
|
|
|
getIsChangedByUser: () => isChangedByUser, |
|
|
|
getIsChangedByUser: () => isChangedByUser, |
|
|
|
getValue: () => inputValue, |
|
|
|
getValue: () => inputValue, |
|
|
|
isValid: () => isInputValid, |
|
|
|
isValid: () => isInputValid, |
|
|
|
setValue: setInputValue, |
|
|
|
setValue, |
|
|
|
}), |
|
|
|
}), |
|
|
|
[inputValue, isChangedByUser, isInputValid], |
|
|
|
[inputValue, isChangedByUser, isInputValid, setValue], |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
return cloneElement(input, { |
|
|
|
return cloneElement(input, { |
|
|
|