cashflowy / switchless

component library using mui/joy
2 stars 0 forks source link

Drag and Drop File Upload #17

Open Fahimansari opened 1 month ago

Fahimansari commented 1 month ago

Specs

image https://www.loom.com/share/b2f99ae0367a432dba4fe6fdb63dc609

Sample component (working)

const UploadFileArea = () => {
    const fileInputRef = useRef<HTMLInputElement>(null);
    const formRef = useRef<HTMLFormElement>(null);
    const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();
      const files = Array.from(e.dataTransfer.files);
      console.log('Files dropped:', files);

      if (fileInputRef.current) {
        const dataTransfer = new DataTransfer();
        files.forEach(file => dataTransfer.items.add(file));
        fileInputRef.current.files = dataTransfer.files;
        formRef.current?.submit();
      }
    };

    const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      const files = Array.from(e.target.files || []);
      console.log('Files selected:', files);

      if (files.length > 0) {
        formRef.current?.submit();
      }
    };

    return (
      <>
        <form id="file_upload_form" ref={formRef} action={<passed as props>} method="post" encType="multipart/form-data">
          <input type="file" id="file_upload"  ref={fileInputRef} name="files" multiple style={{ display: 'none' }} onChange={handleFileChange} />
        </form>
        <Box
          component="div"
          sx={{ border: '2px dashed', borderColor: 'neutral.outlinedBorder', borderRadius: 'sm', p: 4, mb: 2, mt: 2, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', transition: 'all 0.2s', '&:hover': { borderColor: 'primary.500', bgcolor: 'primary.50' } }}
          onDragOver={(e) => { e.preventDefault(); e.stopPropagation(); }}
          onDrop={handleDrop}
          onClick={() => fileInputRef.current?.click()}
        >
          <Upload sx={{ fontSize: 48, color: 'neutral.500', mb: 2 }} />
          <Typography level="body-lg" sx={{ mb: 1 }}>
            Drag and drop files here
          </Typography>
          <Typography level="body-sm" sx={{ color: 'neutral.500' }}>
            or click to select files
          </Typography>
        </Box>
      </>
    )
  }