fix(striker-ui): make InputWithRef compatible with Switch

main
Tsu-ba-me 2 years ago committed by digimer
parent 4376fdbc10
commit dbd642e857
  1. 41
      striker-ui/components/InputWithRef.tsx
  2. 7
      striker-ui/lib/createInputOnChangeHandler.ts
  3. 6
      striker-ui/types/CreateInputOnChangeHandlerFunction.d.ts

@ -20,17 +20,19 @@ type InputWithRefOptionalPropsWithDefault<
> = { > = {
createInputOnChangeHandlerOptions?: CreateInputOnChangeHandlerOptions<TypeName>; createInputOnChangeHandlerOptions?: CreateInputOnChangeHandlerOptions<TypeName>;
required?: boolean; required?: boolean;
valueKey?: string;
valueType?: TypeName; valueType?: TypeName;
}; };
type InputWithRefOptionalPropsWithoutDefault = { type InputWithRefOptionalPropsWithoutDefault<
TypeName extends keyof MapToInputType,
> = {
inputTestBatch?: InputTestBatch; inputTestBatch?: InputTestBatch;
onFirstRender?: (args: { isRequired: boolean }) => void; onFirstRender?: (args: { isRequired: boolean }) => void;
valueKey?: CreateInputOnChangeHandlerOptions<TypeName>['valueKey'];
}; };
type InputWithRefOptionalProps<TypeName extends keyof MapToInputType> = type InputWithRefOptionalProps<TypeName extends keyof MapToInputType> =
InputWithRefOptionalPropsWithDefault<TypeName> & InputWithRefOptionalPropsWithDefault<TypeName> &
InputWithRefOptionalPropsWithoutDefault; InputWithRefOptionalPropsWithoutDefault<TypeName>;
type InputWithRefProps< type InputWithRefProps<
TypeName extends keyof MapToInputType, TypeName extends keyof MapToInputType,
@ -48,6 +50,7 @@ type InputForwardedRefContent<TypeName extends keyof MapToInputType> = {
const INPUT_TEST_ID = 'input'; const INPUT_TEST_ID = 'input';
const MAP_TO_INITIAL_VALUE: MapToInputType = { const MAP_TO_INITIAL_VALUE: MapToInputType = {
boolean: false,
number: 0, number: 0,
string: '', string: '',
}; };
@ -55,38 +58,44 @@ const MAP_TO_INITIAL_VALUE: MapToInputType = {
const INPUT_WITH_REF_DEFAULT_PROPS: Required< const INPUT_WITH_REF_DEFAULT_PROPS: Required<
InputWithRefOptionalPropsWithDefault<'string'> InputWithRefOptionalPropsWithDefault<'string'>
> & > &
InputWithRefOptionalPropsWithoutDefault = { InputWithRefOptionalPropsWithoutDefault<'string'> = {
createInputOnChangeHandlerOptions: {}, createInputOnChangeHandlerOptions: {},
required: false, required: false,
valueKey: 'value',
valueType: 'string', valueType: 'string',
}; };
const InputWithRef = forwardRef( const InputWithRef = forwardRef(
<TypeName extends keyof MapToInputType, InputComponent extends ReactElement>( <TypeName extends keyof MapToInputType, InputComponent extends ReactElement>(
{ {
createInputOnChangeHandlerOptions: {
postSet: postSetAppend,
...restCreateInputOnChangeHandlerOptions
} = INPUT_WITH_REF_DEFAULT_PROPS.createInputOnChangeHandlerOptions as CreateInputOnChangeHandlerOptions<TypeName>,
input, input,
inputTestBatch, inputTestBatch,
onFirstRender, onFirstRender,
required: isRequired = INPUT_WITH_REF_DEFAULT_PROPS.required, required: isRequired = INPUT_WITH_REF_DEFAULT_PROPS.required,
valueKey = INPUT_WITH_REF_DEFAULT_PROPS.valueKey, valueKey,
valueType = INPUT_WITH_REF_DEFAULT_PROPS.valueType as TypeName, valueType = INPUT_WITH_REF_DEFAULT_PROPS.valueType as TypeName,
// Props with initial value that depend on others.
createInputOnChangeHandlerOptions: {
postSet: postSetAppend,
valueKey: onChangeValueKey = valueKey,
...restCreateInputOnChangeHandlerOptions
} = INPUT_WITH_REF_DEFAULT_PROPS.createInputOnChangeHandlerOptions as CreateInputOnChangeHandlerOptions<TypeName>,
}: InputWithRefProps<TypeName, InputComponent>, }: InputWithRefProps<TypeName, InputComponent>,
ref: ForwardedRef<InputForwardedRefContent<TypeName>>, ref: ForwardedRef<InputForwardedRefContent<TypeName>>,
) => { ) => {
const { props: inputProps } = input;
const vKey = useMemo(
() => onChangeValueKey ?? ('checked' in inputProps ? 'checked' : 'value'),
[inputProps, onChangeValueKey],
);
const { const {
props: {
onBlur: initOnBlur, onBlur: initOnBlur,
onChange: initOnChange, onChange: initOnChange,
onFocus: initOnFocus, onFocus: initOnFocus,
value: initValue = MAP_TO_INITIAL_VALUE[valueType], [vKey]: initValue = MAP_TO_INITIAL_VALUE[valueType],
...restInitProps ...restInitProps
}, } = inputProps;
} = input;
const isFirstRender = useIsFirstRender(); const isFirstRender = useIsFirstRender();
@ -136,6 +145,7 @@ const InputWithRef = forwardRef(
}, },
set: setValue, set: setValue,
setType: valueType, setType: valueType,
valueKey: vKey,
...restCreateInputOnChangeHandlerOptions, ...restCreateInputOnChangeHandlerOptions,
}), }),
[ [
@ -143,6 +153,7 @@ const InputWithRef = forwardRef(
postSetAppend, postSetAppend,
restCreateInputOnChangeHandlerOptions, restCreateInputOnChangeHandlerOptions,
setValue, setValue,
vKey,
valueType, valueType,
], ],
); );
@ -179,7 +190,7 @@ const InputWithRef = forwardRef(
onChange, onChange,
onFocus, onFocus,
required: isRequired, required: isRequired,
[valueKey]: inputValue, [vKey]: inputValue,
}); });
}, },
); );

@ -1,4 +1,4 @@
import { InputProps as MUIInputProps } from '@mui/material'; import { ChangeEventHandler } from 'react';
import MAP_TO_VALUE_CONVERTER from './consts/MAP_TO_VALUE_CONVERTER'; import MAP_TO_VALUE_CONVERTER from './consts/MAP_TO_VALUE_CONVERTER';
@ -8,10 +8,11 @@ const createInputOnChangeHandler =
preSet, preSet,
set, set,
setType = 'string' as TypeName, setType = 'string' as TypeName,
}: CreateInputOnChangeHandlerOptions<TypeName> = {}): MUIInputProps['onChange'] => valueKey = 'value',
}: CreateInputOnChangeHandlerOptions<TypeName> = {}): ChangeEventHandler<HTMLInputElement> =>
(event) => { (event) => {
const { const {
target: { value }, target: { [valueKey]: value },
} = event; } = event;
const postConvertValue = MAP_TO_VALUE_CONVERTER[setType]( const postConvertValue = MAP_TO_VALUE_CONVERTER[setType](
value, value,

@ -1,4 +1,4 @@
type MapToInputType = Pick<MapToType, 'number' | 'string'>; type MapToInputType = Pick<MapToType, 'boolean' | 'number' | 'string'>;
type InputOnChangeParameters = Parameters< type InputOnChangeParameters = Parameters<
Exclude<import('@mui/material').InputBaseProps['onChange'], undefined> Exclude<import('@mui/material').InputBaseProps['onChange'], undefined>
@ -12,4 +12,8 @@ type CreateInputOnChangeHandlerOptions<TypeName extends keyof MapToInputType> =
preSet?: (...args: InputOnChangeParameters) => void; preSet?: (...args: InputOnChangeParameters) => void;
set?: StateSetter; set?: StateSetter;
setType?: TypeName; setType?: TypeName;
valueKey?: Extract<
keyof import('react').ChangeEvent<HTMLInputElement>['target'],
'checked' | 'value'
>;
}; };

Loading…
Cancel
Save