Coder Social home page Coder Social logo

kimmelsg / cj-upload Goto Github PK

View Code? Open in Web Editor NEW
586.0 12.0 33.0 1.14 MB

Higher order React components for file uploading (with progress) react file upload

License: MIT License

JavaScript 100.00%
react file-upload xhr progress file upload react-components upload-dialog

cj-upload's Introduction

Deprecated

Please look at react-use-upload for the same functionality, updated using React hooks.

CircleCI Coverage Status

@navjobs/upload

v4

I'm working on a v4 soon that simplfies the api and removes the children-as-a-function paradigm to something more extendable. Also revamping the test suit. It'll be a complete rewrite.

What

A set of React components for handling file uploads. If you simply want to turn any component into a file upload dialog, wrap it in our <UploadField/> component that exposes the files after selection. Need to process a file upload and receive the upload progress? Wrap <UploadField/> with <Uploader/>. You can see examples inside our storybook.

Why this?

  • Any component can be an upload dialog. Wrap it in <UploadField/>. This means you have ultimate styling control.
  • Simple component API for upload progress. Pass headers, extra fields, anything.
  • Zero dependencies (other than React!)

Install

yarn add @navjobs/upload

In this library

  • UploadField gives access to files after drag and drop / clicking on the area wrapped
  • Uploader triggers an xhr upload to a url with file progress
  • SignedUploader same as above, but helps generate a signed url from your api.
  • Imperative api that lets you trigger a file upload with progress outside of react.

UploadField

import { UploadField } from '@navjobs/upload'

  <UploadField
    onFiles={files => //files object here}
    containerProps={{
      className: 'resume_import'
    }}
    uploadProps={{
      accept: '.pdf,.doc,.docx,.txt,.rtf',
    }}
  >
    <div>
      Click here to upload! This can be an image,
      or any component you can dream of.
    </div>
  </UploadField>

Uploader

Use <UploadField /> inside of this component; pass the files to it and handle the upload!

import { Uploader } from '@navjobs/upload'

<Uploader
  request={{
    fileName: 'file',
    url: 'https://upload.com',
    method: 'POST',
    fields: {
      //extra fields to pass with the request
      full_name: 'Testing extra fields',
    },
    headers: {
      //custom headers to send along
      Authorization: 'Bearer: Test',
    },
    // use credentials for cross-site requests
    withCredentials: false,
  }}
  onComplete={({ response, status }) => /*do something*/}
  //upload on file selection, otherwise use `startUpload`
  uploadOnSelection={true}
>
  {({ onFiles, progress, complete }) => (
    <div>
      <UploadField onFiles={onFiles}>
        <div>
          Click here to select a file!
        </div>
      </UploadField>
      {progress ? `Progress: ${progress}` : null}
      {complete ? 'Complete!' : null}
    </div>
  )}
</Uploader>

Signed Uploader

This is a useful component for generating signed urls on your backend for a service like AWS or Google Cloud. The workflow generally involes hitting your own api, then uploading to the url that your api returns. After the fact, you hit your api again to say that the upload is finished.

import { SignedUploader } from '@navjobs/upload'


<SignedUploader
  //grab this url from your api
  beforeRequest={() => new Promise(resolve => resolve({ url: 'http://storage.googlecloud.com' }))}
  request={({ before, files }) => ({
      url: before.url,
      method: 'PUT',
      headers: {
        'Content-Type': files[0].type
      }
    })}
  afterRequest={({ before, status }) => new Promise(resolve => {
    resolve('finished the upload!');
  })}
>

Imperative API

If you need to upload files and recieve progress, but can't wrap an Uploader around where you receive the files, feel free to use this:

import { UploadRequest } from '@navjobs/upload'

async uploadFiles() {
  let { response, error, aborted } = await UploadRequest(
    {
      request: {
        url: 'blah' //same as above request object
      },
      files, //files array
      progress: value => console.log('progress!', value)
    }  
  )
  //do something with response
}

FAQ

Q: Part of the component I'm wrapping isn't cursor pointer?

A: You may need to set

::-webkit-file-upload-button { cursor:pointer; }

In your css. For some reason file uploads aren't always pointer.

License

This project is licensed under the terms of the MIT license.

cj-upload's People

Contributors

danielberndt avatar dreamorosi avatar edongashi avatar ingro avatar manish-tal avatar manishk3008 avatar mikegolod avatar mjsisley avatar zackify avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cj-upload's Issues

Support multiple files and returning a list of states

Now uploading multiple images at once, will be merged into one request, and some servers do not support this form.
In addition, sometimes we have to upload multiple pictures at the same time. So, I want to detect that when uploading multiple pictures, I divide them into multiple requests and merge them into one return result. What do you think?

Add imperative api

Something like:

await uploadRequest(options, progress => console.log(progress)

onFiles never called.

const Overlay  = ({removeComponent, index, changeImage}) =>
  <View  style={{position: 'absolute'}} >
    <UploadField  onFiles={files=>console.log('dfs')}  >
      <View  style={[s.overlay, s.size]}>
        <Text style={s.replace}>Replace</Text>
      </View>
    </UploadField>
    <CloseIcon index={index} removeComponent={removeComponent}/>
  </View>

TypeError: instance is not a function

Hey, this seems like the most legit uploader lib i've seen so far, but i'm having a little trouble implementing the imperative API version in a redux action, maybe you can shed light on what I'm doing wrong or if there is actually an issue. When I run the UploadRequest on a file I get back this value for instance which is undefined.

screen shot 2017-10-31 at 5 35 39 pm

Which logs the following error:

screen shot 2017-10-31 at 5 44 52 pm

Here is what my call looks like:

screen shot 2017-10-31 at 5 44 02 pm

I've verified all the params url, hash, mimetype, auth etc.

This is for a multipart file uploader (for my work) and there aren't really a whole lot of other nice options to do this out there at the moment, so would love to get this very elegant one to work.

React 16 Upgrade

Hey,

Been using the imperative API for a while now and it works great, just upgraded my app to react 16, tested it out and it runs very smoothly. Still have this dependancy warning from yarn though " > @navjobs/[email protected]" has incorrect peer dependency "react@^15.3.1". It's the only package ive got left in my tree that has the warning, just wanted to say something about it.

cheers

Upload twice same file do not trigger upload

  • Upload a file with UploadField
  • Wait for upload to complete
  • Try to upload the same file

Expected result
Upload is triggered

Actual result
Upload is not triggered

Note:
If a new file is selected upload starts, maybe the issue is in the "onChange" handler of the file input field.

Reset uploader state

Is there a way to reset the uploader state?
More specifically what I mean, is how can I reset progress and complete?
I don't see this implemented. but it would be really helpful IMO.
BTW thank you for this lib :)

Support multiple files at once

Currently, only the first file selected is sent, this library doesn't support multiple. I don't need this at the moment, so if anyone has ideas on how to add this in, let me know.

Styling input[type=file]

Probably due to the css framework or some resetter I have the input with the following styles:

    top: 0px;
    right: 0px;
    opacity: 0;
    width: 100%;
    height: 100%;
    cursor: pointer;
    position: absolute;

This means that wherever I click the upload is triggered.
How can I apply styles over the <input/>?

I tried with <UploadField style={{ width: 0, height: 0 }} without success.

Unable to catch error response details

In Uploader component, in onError prop callback I get as argument of function only one boolean value, instead of full server response (which include validation on additional data sent with files and on the file itself).
With only a true/false flag I can't expose to the user the validation error in order to get a valid submission.
I am missing somenthing in docs or it is a feature not yet implemented ?

How to get files before upload?

I carefully read your source code. The onfils method is passed by uploader,wo cannot change it, so, how to get files before upload?

<Uploader
  request={{
    fileName: 'file',
    url: 'https://upload.com',
    method: 'POST',
    fields: {
      //extra fields to pass with the request
      full_name: 'Testing extra fields',
    },
    headers: {
      //custom headers to send along
      Authorization: 'Bearer: Test',
    },
    // use credentials for cross-site requests
    withCredentials: false,
  }}
  onComplete={({ response, status }) => /*do something*/}
  //upload on file selection, otherwise use `startUpload`
  uploadOnSelection={true}
>
  {({ onFiles, progress, complete }) => (
  // onfile is the inner function 
    <div>
      <UploadField onFiles={onFiles}>
        <div>
          Click here to select a file!
        </div>
      </UploadField>
      {progress ? `Progress: ${progress}` : null}
      {complete ? 'Complete!' : null}
    </div>
  )}
</Uploader>

i want to limit the uploaded flles, i do not kown to code
i have see #27

Access the input ref

Hey,

Thanks for this useful library!

I would like to add a listener on the input for onDragEnter and onDragExit. Would it be possible to accept a inputRef prop, which would be forwarded to the input?

I could make the PR if you would like.

Thanks in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.