Skip to content

Commit

Permalink
fix: rerendering
Browse files Browse the repository at this point in the history
  • Loading branch information
SKairinos committed Jun 20, 2023
1 parent d3a37cf commit d08a24c
Showing 1 changed file with 105 additions and 95 deletions.
200 changes: 105 additions & 95 deletions src/components/form/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ type BaseTextFieldProps = Omit<MuiTextFieldProps, 'defaultValue'> & {
type RepeatTextFieldProps = BaseTextFieldProps & {
repeat?: Array<Omit<BaseTextFieldProps, (
'required' |
'split'
)>>;
'split' |
'type'
)> & {
inheritProps?: boolean;
}>;
};

export type TextFieldProps<
Expand All @@ -52,6 +55,94 @@ export type TextFieldProps<
}
);

// Internal TextField.
const _TextField: React.FC<BaseTextFieldProps & {
validate: Validate;
split?: Split;
}> = ({
validate,
split,
name,
type = 'text',
InputProps = {},
onKeyUp,
onBlur,
...otherTextFieldProps
}) => {
const fieldConfig: FieldConfig = {
name,
type,
validate: async (value) => {
if (validate instanceof Schema) {
try {
validate.validateSync(value);
} catch (error) {
if (error instanceof ValidationError) {
return error.errors[0];
}
throw error;
}
} else if (validate !== undefined) {
return await validate(value);
}
}
};

return (
<Field {...fieldConfig}>
{({ meta, form }: FieldProps) => {
const [showError, setShowError] = React.useState(false);

let {
endAdornment,
...otherInputProps
} = InputProps;

if (showError &&
meta.error !== undefined &&
meta.error !== ''
) {
endAdornment = <>
{endAdornment}
<InputAdornment position='end'>
<ClickableTooltip title={meta.error}>
<ErrorOutlineIcon color='error' />
</ClickableTooltip>
</InputAdornment>
</>;
}

onKeyUp = wrap({
after: (event: React.KeyboardEvent<HTMLDivElement>) => {
let value: string | string[] = (event.target as HTMLTextAreaElement).value;
if (split !== undefined) value = value.split(split);
form.setFieldValue(name, value, true);
}
}, onKeyUp);

onBlur = wrap({
after: () => { setShowError(true); }
}, onBlur);

return (
<MuiTextField
defaultValue={meta.initialValue}
name={name}
type={type}
onKeyUp={onKeyUp}
onBlur={onBlur}
InputProps={{
endAdornment,
...otherInputProps
}}
{...otherTextFieldProps}
/>
);
}}
</Field>
);
};

interface ITextField<SingleValue extends boolean> {
// eslint-disable-next-line @typescript-eslint/prefer-function-type
(
Expand Down Expand Up @@ -84,93 +175,6 @@ const TextField: ITextField<true> & ITextField<false> = ({
validate = validate.required();
}

// Internal TextField.
const TextField: React.FC<BaseTextFieldProps & {
validate: Validate;
split?: Split;
}> = ({
validate,
split,
name,
type = 'text',
InputProps = {},
onKeyUp,
onBlur
}) => {
const fieldConfig: FieldConfig = {
name,
type,
validate: async (value) => {
if (validate instanceof Schema) {
try {
validate.validateSync(value);
} catch (error) {
if (error instanceof ValidationError) {
return error.errors[0];
}
throw error;
}
} else if (validate !== undefined) {
return await validate(value);
}
}
};

return (
<Field {...fieldConfig}>
{({ meta, form }: FieldProps) => {
const [showError, setShowError] = React.useState(false);

let {
endAdornment,
...otherInputProps
} = InputProps;

if (showError &&
meta.error !== undefined &&
meta.error !== ''
) {
endAdornment = <>
{endAdornment}
<InputAdornment position='end'>
<ClickableTooltip title={meta.error}>
<ErrorOutlineIcon color='error' />
</ClickableTooltip>
</InputAdornment>
</>;
}

onKeyUp = wrap({
after: (event: React.KeyboardEvent<HTMLDivElement>) => {
let value: string | string[] = (event.target as HTMLTextAreaElement).value;
if (split !== undefined) value = value.split(split);
form.setFieldValue(name, value, true);
}
}, onKeyUp);

onBlur = wrap({
after: () => { setShowError(true); }
}, onBlur);

return (
<MuiTextField
defaultValue={meta.initialValue}
name={name}
type={type}
onKeyUp={onKeyUp}
onBlur={onBlur}
InputProps={{
endAdornment,
...otherInputProps
}}
{...otherTextFieldProps}
/>
);
}}
</Field>
);
};

if (repeat.length > 0) {
onKeyUp = wrap({
after: (event: React.KeyboardEvent<HTMLDivElement>) => {
Expand All @@ -187,19 +191,25 @@ const TextField: ITextField<true> & ITextField<false> = ({
}

return <>
<TextField
<_TextField
validate={validate}
split={split}
name={name}
onKeyUp={onKeyUp}
{...otherTextFieldProps}
/>
{repeat.map(textFieldProps =>
<TextField
key={textFieldProps.name}
{repeat.map(({
name,
inheritProps = true,
...repeatTextFieldProps
}) =>
<_TextField
key={name}
name={name}
validate={validateRepeat}
{...otherTextFieldProps}
{...textFieldProps}
type={otherTextFieldProps.type}
{...(inheritProps && otherTextFieldProps)}
{...repeatTextFieldProps}
/>
)}
</>;
Expand Down

0 comments on commit d08a24c

Please sign in to comment.