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

Loading…
Cancel
Save