Skip to content

Commit

Permalink
ensures numeric input values stored in formik as numbers (#758)
Browse files Browse the repository at this point in the history
  • Loading branch information
scandycuz authored Oct 23, 2024
1 parent 0e135af commit 01ae18f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 46 deletions.
41 changes: 4 additions & 37 deletions packages/elements/src/lib/NumericInput.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,21 @@
import {
ChangeEvent,
ForwardRefRenderFunction,
InputHTMLAttributes,
forwardRef,
} from "react";
import { NumericFormat } from "react-number-format";
import { ForwardRefRenderFunction, forwardRef } from "react";
import { NumericFormat, NumericFormatProps } from "react-number-format";
import StyledInput from "./styled/Input";

interface NumericInputProps
extends Omit<
InputHTMLAttributes<HTMLInputElement>,
"value" | "defaultValue"
> {
readonly defaultValue: string | number | null | undefined;
readonly value: string | number | null | undefined;
}

/**
* Replacement for an input component with a type of "number"
* that handles formatting the displayed value.
*/
export const NumericInput: ForwardRefRenderFunction<
HTMLInputElement,
NumericInputProps
> = ({ type, onChange, ...props }, ref) => {
/**
* Converts the event target's value to a number
* and calls the onChange prop.
*/
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
if (onChange) {
const value = event.target.value;
const numberValue = value ? Number(value.replace(/,/g, "")) : null;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const newTarget = event.target as any;
newTarget.value = numberValue;
event.target = newTarget;

onChange(event);
}
};

NumericFormatProps
> = ({ type, ...props }, ref) => {
return (
<NumericFormat
{ ...props }
customInput={ StyledInput }
getInputRef={ ref }
thousandSeparator=","
onChange={ handleChange }
/>
);
};
Expand Down
40 changes: 31 additions & 9 deletions packages/elements/src/lib/form/TextInputField.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ForwardRefRenderFunction, forwardRef } from "react";
import { ChangeEvent, ForwardRefRenderFunction, forwardRef } from "react";
import { Field, FieldProps } from "formik";
import TextInput, { TextInputProps } from "../TextInput";

Expand All @@ -8,14 +8,36 @@ const TextInputField: ForwardRefRenderFunction<
> = (props, ref) => {
return (
<Field name={ props.name }>
{ ({ field, meta }: FieldProps) => (
<TextInput
errorMessage={ meta.touched ? meta.error : "" }
ref={ ref }
{ ...field }
{ ...props }
/>
) }
{ ({ field, form, meta }: FieldProps) => {
const convertNumberStringToNumber = (value: string) => {
return !isNaN(parseFloat(value))
? Number(value.replace(/,/g, ""))
: value;
};

/**
* Necessary for the "react-number-format" library's
* NumericInput component in order to store number input
* values as numbers instead of strings.
*/
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
const formattedValue = convertNumberStringToNumber(
event.target.value
);

form.setFieldValue(field.name, formattedValue);
};

return (
<TextInput
errorMessage={ meta.touched ? meta.error : "" }
ref={ ref }
{ ...field }
{ ...props }
onChange={ handleChange }
/>
);
} }
</Field>
);
};
Expand Down

0 comments on commit 01ae18f

Please sign in to comment.