All files / src/components/common/CustomAmountInput CustomAmountInput.tsx

80% Statements 24/30
48.64% Branches 18/37
100% Functions 7/7
81.81% Lines 18/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93                                                68x 3x   68x                       12x 6x 6x       12x 3x 3x   3x     3x       12x 3x 3x     12x 12x 3x           12x                                              
import React, { memo, useEffect } from "react";
import { Box } from "@mui/material";
import NumberFormat, { NumberFormatValues } from "react-number-format";
import { Input } from "@common/Input";
import { MAX_ALLOWED_AMOUNT } from "@constants/constants";
 
export type CustomAmountInputProps = {
  id?: string;
  min?: number;
  max?: number;
  bounded?: boolean;
  onBlur?: () => void;
  label?: string | React.ReactNode;
  placeholder?: string;
  error?: boolean;
  disabled?: boolean;
  helperText?: string | React.ReactNode;
  currency?: "usd";
  initialValue?: string;
  onChange?: (value: string) => void;
  isDirty?: boolean;
  value?: string;
};
 
const getValueFromString = (value: string) =>
  parseFloat(value.replaceAll(",", ""));
 
const CustomAmountInput = ({
  min = 1,
  max = MAX_ALLOWED_AMOUNT,
  onBlur,
  bounded = true,
  helperText,
  initialValue,
  onChange,
  isDirty,
  value,
  ...props
}: CustomAmountInputProps) => {
  useEffect(() => {
    Eif (initialValue) {
      Eif (onChange) onChange(initialValue);
    }
  }, []);
 
  const handleAmountChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const trueValue = getValueFromString(e.target.value);
    Iif (trueValue < min) {
      if (onChange) onChange(min + ".00");
    } else Iif (trueValue > max && bounded) {
      if (onChange) onChange(max + ".00");
    } else {
      Eif (onChange) onChange(e.target.value);
    }
  };
 
  const formatAmount = () => {
    Eif (onBlur) onBlur();
    Eif (value && !value?.includes(".")) Eif (onChange) onChange(value + ".00");
  };
 
  const getIsAllowed = (max: number) => {
    return (values: NumberFormatValues) => {
      Eif (!bounded) return true;
      const { value } = values;
      return +value >= 0 && +value <= max;
    };
  };
 
  return (
    <Box sx={{ width: "100%" }}>
      <NumberFormat
        {...props}
        customInput={Input}
        value={value}
        thousandSeparator
        onBlur={formatAmount}
        allowNegative={false}
        decimalScale={2}
        isAllowed={getIsAllowed(max)}
        fullWidth
        maxLength={2}
        max={bounded ? max : undefined}
        {...(typeof helperText === "string" && { helperText: helperText })}
        onChange={handleAmountChange}
      />
      {typeof helperText !== "string" && helperText}
    </Box>
  );
};
 
export default memo(CustomAmountInput);