fix(striker-ui): workaround for submit stays disabled until user focuses on every field

main
Tsu-ba-me 1 year ago
parent ed58c57835
commit d528a85cdd
  1. 48
      striker-ui/components/InputWithRef.tsx

@ -1,4 +1,5 @@
import { InputBaseProps } from '@mui/material'; import { InputBaseProps } from '@mui/material';
import { debounce } from 'lodash';
import { import {
cloneElement, cloneElement,
ForwardedRef, ForwardedRef,
@ -24,6 +25,7 @@ type InputWithRefOptionalPropsWithDefault<
type InputWithRefOptionalPropsWithoutDefault< type InputWithRefOptionalPropsWithoutDefault<
TypeName extends keyof MapToInputType, TypeName extends keyof MapToInputType,
> = { > = {
debounceWait?: number;
inputTestBatch?: InputTestBatch; inputTestBatch?: InputTestBatch;
onBlurAppend?: InputBaseProps['onBlur']; onBlurAppend?: InputBaseProps['onBlur'];
onFirstRender?: InputFirstRenderFunction; onFirstRender?: InputFirstRenderFunction;
@ -62,6 +64,7 @@ const INPUT_WITH_REF_DEFAULT_PROPS: Required<
> & > &
InputWithRefOptionalPropsWithoutDefault<'string'> = { InputWithRefOptionalPropsWithoutDefault<'string'> = {
createInputOnChangeHandlerOptions: {}, createInputOnChangeHandlerOptions: {},
debounceWait: 500,
required: false, required: false,
valueType: 'string', valueType: 'string',
}; };
@ -69,6 +72,7 @@ const INPUT_WITH_REF_DEFAULT_PROPS: Required<
const InputWithRef = forwardRef( const InputWithRef = forwardRef(
<TypeName extends keyof MapToInputType, InputComponent extends ReactElement>( <TypeName extends keyof MapToInputType, InputComponent extends ReactElement>(
{ {
debounceWait = INPUT_WITH_REF_DEFAULT_PROPS.debounceWait,
input, input,
inputTestBatch, inputTestBatch,
onBlurAppend, onBlurAppend,
@ -125,6 +129,25 @@ const InputWithRef = forwardRef(
return result; return result;
}, [inputTestBatch, isRequired]); }, [inputTestBatch, isRequired]);
const doTestAndSet = useCallback(
(value: MapToInputType[TypeName]) => {
const valid =
testInput?.call(null, {
inputs: { [INPUT_TEST_ID]: { value } },
isIgnoreOnCallbacks: true,
}) ?? false;
onFirstRender?.call(null, { isValid: valid });
setIsInputValid(valid);
},
[onFirstRender, testInput],
);
const debounceDoTestAndSet = useMemo(
() => debounce(doTestAndSet, debounceWait),
[debounceWait, doTestAndSet],
);
const onBlur = useMemo<InputBaseProps['onBlur']>( const onBlur = useMemo<InputBaseProps['onBlur']>(
() => () =>
initOnBlur ?? initOnBlur ??
@ -152,12 +175,16 @@ const InputWithRef = forwardRef(
initOnChange?.call(null, ...args); initOnChange?.call(null, ...args);
postSetAppend?.call(null, ...args); postSetAppend?.call(null, ...args);
}, },
set: setValue, set: (value) => {
setValue(value);
debounceDoTestAndSet(value as MapToInputType[TypeName]);
},
setType: valueType, setType: valueType,
valueKey: vKey, valueKey: vKey,
...restCreateInputOnChangeHandlerOptions, ...restCreateInputOnChangeHandlerOptions,
}), }),
[ [
debounceDoTestAndSet,
initOnChange, initOnChange,
postSetAppend, postSetAppend,
restCreateInputOnChangeHandlerOptions, restCreateInputOnChangeHandlerOptions,
@ -185,13 +212,7 @@ const InputWithRef = forwardRef(
* render function completes. * render function completes.
*/ */
useEffect(() => { useEffect(() => {
const isValid = doTestAndSet(inputValue);
testInput?.call(null, {
inputs: { [INPUT_TEST_ID]: { value: inputValue } },
isIgnoreOnCallbacks: true,
}) ?? false;
onFirstRender?.call(null, { isValid });
return onUnmount; return onUnmount;
@ -203,17 +224,12 @@ const InputWithRef = forwardRef(
* This allows us to populate the input based on value from other field(s). * This allows us to populate the input based on value from other field(s).
*/ */
useEffect(() => { useEffect(() => {
if (isChangedByUser || !initValue) return; if (isChangedByUser || inputValue === initValue || !initValue) return;
const valid = doTestAndSet(initValue);
testInput?.call(null, {
inputs: { [INPUT_TEST_ID]: { value: initValue } },
isIgnoreOnCallbacks: true,
}) ?? false;
setIsInputValid(valid);
setInputValue(initValue); setInputValue(initValue);
}, [initValue, isChangedByUser, testInput]); }, [doTestAndSet, initValue, inputValue, isChangedByUser]);
useImperativeHandle( useImperativeHandle(
ref, ref,

Loading…
Cancel
Save