shadcn-ui / ui

Beautifully designed components that you can copy and paste into your apps. Accessible. Customizable. Open Source.
https://ui.shadcn.com
MIT License
62.96k stars 3.54k forks source link

[request] Dedicated FileUpload component #1307

Open magnusrodseth opened 10 months ago

magnusrodseth commented 10 months ago

I noticed the Input with type file (docs). However, it would be nice to have a customizable FileUpload with "drag and drop" functionality and everything that comes with that.

NiluK commented 10 months ago

use react-filepond, has most of what you need out of the box

tatwater commented 3 months ago

@NiluK I tried react-filepond, but the only React component they give you is <FilePond /> which sucks for easy styling, because they inject a PILE of new buttons and divs inside, over which you have almost no direct control. I was going to start by copying their CSS files into my project and working on a massive facelift by directly overriding each of their rules, but there's not room on our product's timeline for me to do all that at this point.

The default FilePond experience is just so full of wiggles and bounces and gradients and stuff, that we'd really rather do by ourselves or without entirely. Also, you can set your own labels as strings, but you can't pass elements, so it would be challenging to do the upload-icon-over-text layout our own way for the drop zone. Just a lot of unfortunate things that seem to come from the fact that FilePond is an old package that hasn't had a real release since 2021 and was not built for React.

I also tried my hand at Uppy, but that was a whole pile of separate packages, many of which were for features/ui I didn't want or need, yet were required and had to be manually installed one by one as my app threw one missing-peer-dependency error at a time. It didn't feel well thought-out. Either way, both packages are just a single React component to hold a legacy js library that injects markup & styles you then have to fight. And Uppy takes this further with their Dashboard (that you must install?) that tries to pull uploads from all sorts of non-device sources –a nice feature add that I could see opting into sometime– which is way beyond the scope of what we need for our use-case.

If I had the time, I would love to dig into how either of these work and try to make a more shadcn-like approach where each individual box and button etc are components we can place where we want with minimal default styles in tailwind that can be easily overridden. This seems like a big challenge (like the OG accessible dropdown menu breakthrough that launched Radix), with a huge upside for way better DX on a very common need for tons of apps! I'm very excited about the opportunity here. I just can't get to it myself for a while.

And in the meantime, my company is going to fall back on using react-dropzone and handle the uploads ourselves with no progress bars, image cropping/scaling, file naming, etc on the client. Which is a big bummer, but also a huge relief after this deep-dive.

Hope this can prompt a productive convo! Cheers

tatwater commented 3 months ago

Oh shoot - I just found this linked here: https://ark-ui.com/docs/components/file-upload

cue tires screeching

Edit: It doesn't do the fancy image manipulations that FilePond & Uppy do, which is the same bummer as above, but I'll take it for the better DX than react-dropzone

Edit 2: Ugh, I'm having a super hard time hooking Ark UI's FileUpload into react-hook-form. They don't have a change function that passes a ChangeEvent<HTMLInputElement> (instead they pass their own FileUploadFileAcceptDetails – they seem to use a lot of their own types instead of common ones that would make integration easier), so I've found myself trying to mock one so react-hook-form's onChange() plugs in, and it's gotten really messy.

  const onFileAccept = (details: FileUploadFileAcceptDetails) => {
    const event: ChangeEvent<HTMLInputElement> = {
      target: {
        files: {
          item: () => details.files[0],
          length: 1,
          [Symbol.iterator]: ({ next: () => ({ value: details.files[0], done: true })}),  // falling apart here
        }
      }
    };

    props.onChange(event);
  }

I think it's time to give up on all these dreams and see what react-dropzone has to offer after all

CestDiego commented 1 month ago

I would love to know how y'all implement the FilePond with Shadcn controlled input, it's really splitting my hairs. Would love to either have an official integration or some shadcn file upload component.

leomelzer commented 3 days ago

https://github.com/rpldy/react-uploady could be interesting, too. I've used it with another UI library and found it to be very extensible. It's a headless library but exposes lots of useful primitives / hooks which could be composed. In general uploading tends to be very complex yet important in modern applications.