import tw from "twin.macro"; import { Accept, FileError, useDropzone } from "react-dropzone"; import { HTMLAttributes, useMemo } from "react"; /** * NejDropzone component for handling file uploads. * @param {Object} props - Component props. * @param {(files: T[], event: DropEvent) => void} props.onDrop - Callback function triggered when files are dropped. * @param {string[]} props.accept - Array of supported file extensions. * @param {Array} props.value - The files to be uploaded. * @param {boolean} props.single - Whether to allow only one file to be uploaded. * @param {(file: T) => FileError | FileError[] | null} props.validator - The validator function to be used. * @param {string} props.text - The text to be displayed in the dropzone. * @returns {JSX.Element} - NejDropzone component. */ export default function NejDropzone({ value, accept, onDrop, validator, single, text, css, children, ...props }: HTMLAttributes & { value: File | File[], accept?: Accept | string, onDrop: (files: File[]) => void, validator?: (file: File) => FileError | FileError[] | null, single?: boolean, text?: string, css?: any, children?: any }) { const { getRootProps, getInputProps, isFocused, isDragAccept, isDragReject } = useDropzone({ //validator: validator, onDropAccepted: onDrop, accept: typeof (accept) === "string" ? { [accept]: ["*.*"] } : accept, validator: validator, maxFiles: single ? 1 : undefined, }); const style = useMemo( () => ({ ...tw`flex flex-col items-center min-h-32 justify-center text-primary p-2 border rounded-xl border-2 border-dashed bg-primary`, ...(isFocused && tw`bg-secondary`), ...(isDragAccept && tw`border-accent`), ...(isDragReject && tw`border-red-600`), ...css }), [isFocused, isDragAccept, isDragReject, css] ); //if file is not array, make it 1 item array const array = Array.isArray(value) ? value : [value]; const fil = value == null ? null : array; return (
{children ?? (fil?.length > 0 ? ( fil.map((file) => (

{file.name}

)) ) : ( <>

{text ?? "Drag 'n' drop some files here, or click to select files"}

))}
); }