Typescript: Chips are not visible in Textfield

Viewed 22

In my project, there is a field that shows multiple address chips. Now I am facing a problem. When you copy and paste multiple address values into the field, it will not show in the field, but the value will be updated and displayed in the console:

enter image description here

enter image description here

But after that situation press any key (Not enter) which shows the values like this:

enter image description here

I want to avoid this delay. My requirement is to paste multiple values and then press "enter" key, the values will appear in the field.I tried to correct this situation but failed. Please give me some suggestions to solve this problem

import { faCircleQuestion, faXmark } from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Chip, TextField } from "@mui/material";
import { JSXElementConstructor, Key, ReactElement, ReactFragment, useRef, useState } from "react";
import validator from "validator";

import styles from "./index.module.scss";

type Props = {
  LabelName?: string;
  optional?: string;
  tooltip?: string;
  placeholder?: string;
  className?: string;
  upload?: boolean;
  items?: any;
  setItem: (items: any) => void;
};
const TagActions = (props: Props) => {
  // const [items, setItem] = useState<string[]>([]);
  const [value, setValue] = useState("");
  const [error, setError] = useState("");
  const divRef = useRef<HTMLDivElement>(null);
  const [flag, setFlag] = useState(false);

  const {
    LabelName,
    optional,
    tooltip,
    placeholder,
    className,
    upload,
    items,
    setItem,
  } = props;

  const handleDelete = (item: any) => {
    const result = items.filter((i: any) => i !== item);
    setItem(result);
  };

  const handleItemEdit = (item: any) => {
    const result = items.filter((i: any) => i !== item);
    setItem(result);
    setValue(item);
  };

  const handleKeyDown = (evt: any) => {
    if (["Enter", "Tab", ","].includes(evt.key)) {
      evt.preventDefault();

      const test = value.trim();

      if (test && isValid(test)) {
        items.push(test);
        setValue("");
      }
    }
  };

  const isValid = (email: any) => {
    let error = null;

    if (isInList(email)) {
      error = `${email} has already been added.`;
    }

    if (!validator.isEmail(email)) {
      setFlag(true);
    }

    if (error) {
      setError(error);

      return false;
    }

    return true;
  };

  const isInList = (email: any) => {
    return items.includes(email);
  };

  const handleChange = (evt: any) => {
    setValue(evt.target.value);
  };

  const handlePaste = (evt: any) => {
    evt.preventDefault();

    const paste = evt.clipboardData.getData("text");
    const emails = paste.match(/[\w\d\\.-]+@[\w\d\\.-]+\.[\w\d\\.-]+/g);

    if (emails) {
      const toBeAdded = emails.filter((email: any) => !isInList(email));

      console.log("items inside", items);
      toBeAdded.map((i: any) => {
        items.push(i);
      });
      console.log("items after", items);
    }
  };

  return (
    <>
      <div className="formSection">
        {LabelName && (
          <div className={`control-label ${styles.label}`}>
            <label>
              <span className={styles.alignLeft}>
                <span className={styles.labelText}>{LabelName}</span>
              </span>
            </label>

            <span className={styles.alignRight}>
              {upload && (
                <label htmlFor="uploadCSV">
                  <span className={styles.upload}>Upload CSV</span>
                </label>
              )}

              {optional && <span className={styles.light}>Optional</span>}

              {tooltip && (
                <span className={styles.tooltip_ic} title={tooltip}>
                  <FontAwesomeIcon icon={faCircleQuestion} size="xs" />
                </span>
              )}
            </span>
          </div>
        )}
        <input
          type="file"
          accept=".csv"
          style={{ display: "none" }}
          id="uploadCSV"
        />
        <div className={styles.inputGroup}>
          <TextField
            className={` textfield-emailchip test ${className}`}
            InputProps={{
              startAdornment: items.map(
                (
                  item:
                    | boolean
                    | Key
                    | ReactElement<any, string | JSXElementConstructor<any>>
                    | ReactFragment
                    | null
                    | undefined
                    | any
                    | string
                ) => (
                  <Chip
                    className={
                      !validator.isEmail(item)
                        ? styles.chipTagError
                        : styles.chipTag
                    }
                    key={item}
                    tabIndex={-1}
                    label={item}
                    onDelete={() => handleDelete(item)}
                    onClick={() => handleItemEdit(item)}
                    deleteIcon={<FontAwesomeIcon icon={faXmark} size="xs" />}
                  />
                )
              ),
            }}
            ref={divRef}
            value={value}
            placeholder={placeholder}
            onKeyDown={(e) => handleKeyDown(e)}
            onChange={(e) => handleChange(e)}
            onPaste={(e) => handlePaste(e)}
          />
        </div>

        {error && <p className="error">{error}</p>}
      </div>
    </>
  );
};

export default TagActions;


0 Answers
Related