feat(striker-ui): add InputWithRef

main
Tsu-ba-me 2 years ago
parent 7ad4ad725e
commit cbad0ebf5e
  1. 86
      striker-ui/components/InputWithRef.tsx

@ -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…
Cancel
Save