next-enterprise/components/Form/FileInput.tsx

68 lines
2 KiB
TypeScript
Raw Normal View History

2024-03-03 22:09:33 -05:00
import { useField, useFormikContext } from "formik";
import React, { useRef } from "react";
import ErrorMessage from "./ErrorMessage";
import RequiredAsterisk from "./RequiredAsterisk";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faFile } from "@fortawesome/free-solid-svg-icons";
interface FileInputProps {
label: string;
required?: boolean;
name:string;
}
const FileInput: React.FC<FileInputProps> = ({ label, ...props }) => {
const { required } = props;
const [field, meta] = useField(props);
const { setFieldValue } = useFormikContext();
const fileInputRef = useRef<HTMLInputElement>(null);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { files } = event.target;
const file = files ? files[0] : null;
setFieldValue(props.name, file); // Directly use setFieldValue to update Formik's state
};
const handleClick = () => {
if (fileInputRef.current) {
fileInputRef.current.click();
}
};
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
const files = event.dataTransfer.files;
if (files && files.length > 0) {
const file = files[0];
setFieldValue(props.name, file);
}
};
return (
<div className="mb-4">
<label className="text-md" htmlFor={props.name}>
{label}
<RequiredAsterisk required={required} />
</label>
<div className="drop-area" onClick={handleClick} onDrop={handleDrop} onDragOver={(e) => e.preventDefault()}>
<div>
<FontAwesomeIcon icon={faFile} />
<h4>Drag & Drop Here or Browse</h4>
</div>
<button type="button">Upload Manifest</button>
</div>
<input
type="file"
className="hidden"
ref={fileInputRef}
onChange={handleChange}
/>
<ErrorMessage touched={meta.touched} error={meta.error} />
</div>
);
};
export default FileInput;