parent
7ad4ad725e
commit
cbad0ebf5e
1 changed files with 86 additions and 0 deletions
@ -0,0 +1,86 @@ |
|||||||
|
import { ForwardedRef, forwardRef, useImperativeHandle, useState } from 'react'; |
||||||
|
|
||||||
|
import createInputOnChangeHandler, { |
||||||
|
CreateInputOnChangeHandlerOptions, |
||||||
|
MapToStateSetter, |
||||||
|
} from '../lib/createInputOnChangeHandler'; |
||||||
|
import OutlinedInputWithLabel, { |
||||||
|
OutlinedInputWithLabelProps, |
||||||
|
} from './OutlinedInputWithLabel'; |
||||||
|
|
||||||
|
type InputWithRefOptionalProps<TypeName extends keyof MapToType> = { |
||||||
|
createInputOnChangeHandlerOptions?: Omit< |
||||||
|
CreateInputOnChangeHandlerOptions<TypeName>, |
||||||
|
'set' |
||||||
|
>; |
||||||
|
valueType?: TypeName | 'string'; |
||||||
|
}; |
||||||
|
|
||||||
|
type InputWithRefProps<TypeName extends keyof MapToType> = |
||||||
|
OutlinedInputWithLabelProps & InputWithRefOptionalProps<TypeName>; |
||||||
|
|
||||||
|
type InputForwardedRefContent<TypeName extends keyof MapToType> = { |
||||||
|
isChangedByUser?: boolean; |
||||||
|
setValue?: MapToStateSetter[TypeName]; |
||||||
|
value?: MapToType[TypeName]; |
||||||
|
}; |
||||||
|
|
||||||
|
const MAP_TO_INITIAL_VALUE: MapToType = { |
||||||
|
number: 0, |
||||||
|
string: '', |
||||||
|
}; |
||||||
|
|
||||||
|
const INPUT_WITH_REF_DEFAULT_PROPS: Required< |
||||||
|
InputWithRefOptionalProps<'string'> |
||||||
|
> = { |
||||||
|
createInputOnChangeHandlerOptions: {}, |
||||||
|
valueType: 'string', |
||||||
|
}; |
||||||
|
|
||||||
|
const InputWithRef = forwardRef( |
||||||
|
<TypeName extends keyof MapToType>( |
||||||
|
{ |
||||||
|
createInputOnChangeHandlerOptions: { |
||||||
|
postSet: postSetAppend, |
||||||
|
...restCreateInputOnChangeHandlerOptions |
||||||
|
} = INPUT_WITH_REF_DEFAULT_PROPS.createInputOnChangeHandlerOptions, |
||||||
|
valueType = INPUT_WITH_REF_DEFAULT_PROPS.valueType, |
||||||
|
...restProps |
||||||
|
}: InputWithRefProps<TypeName>, |
||||||
|
ref: ForwardedRef<InputForwardedRefContent<TypeName>>, |
||||||
|
) => { |
||||||
|
const [value, setValue] = useState<MapToType[TypeName]>( |
||||||
|
MAP_TO_INITIAL_VALUE[valueType] as MapToType[TypeName], |
||||||
|
) as [MapToType[TypeName], MapToStateSetter[TypeName]]; |
||||||
|
const [isChangedByUser, setIsChangedByUser] = useState<boolean>(false); |
||||||
|
|
||||||
|
const onChange = createInputOnChangeHandler<TypeName>({ |
||||||
|
postSet: (...args) => { |
||||||
|
setIsChangedByUser(true); |
||||||
|
postSetAppend?.call(null, ...args); |
||||||
|
}, |
||||||
|
set: setValue, |
||||||
|
setType: valueType, |
||||||
|
...restCreateInputOnChangeHandlerOptions, |
||||||
|
}); |
||||||
|
|
||||||
|
useImperativeHandle( |
||||||
|
ref, |
||||||
|
() => ({ |
||||||
|
isChangedByUser, |
||||||
|
setValue, |
||||||
|
value, |
||||||
|
}), |
||||||
|
[isChangedByUser, value], |
||||||
|
); |
||||||
|
|
||||||
|
return <OutlinedInputWithLabel {...{ onChange, value, ...restProps }} />; |
||||||
|
}, |
||||||
|
); |
||||||
|
|
||||||
|
InputWithRef.defaultProps = INPUT_WITH_REF_DEFAULT_PROPS; |
||||||
|
InputWithRef.displayName = 'InputWithRef'; |
||||||
|
|
||||||
|
export type { InputForwardedRefContent, InputWithRefProps }; |
||||||
|
|
||||||
|
export default InputWithRef; |
Loading…
Reference in new issue