Dropzone Prevent Multiple Uploads With Ctrl Click

react-dropzone logo

react-dropzone

npm Tests codecov Open Collective Backers Open Collective Sponsors Gitpod Contributor Covenant

Simple React claw to create a HTML5-compliant drag'n'drib zone for files.

Documentation and examples at https://react-dropzone.js.org. Source lawmaking at https://github.com/react-dropzone/react-dropzone/.

Installation

Install it from npm and include it in your React build process (using Webpack, Browserify, etc).

npm install --salvage react-dropzone

or:

Usage

You can either apply the hook:

              import              React              ,              {              useCallback              }              from              'react'              import              {              useDropzone              }              from              'react-dropzone'              function              MyDropzone              (              )              {              const              onDrop              =              useCallback              (              acceptedFiles              =>              {              // Practise something with the files              }              ,              [              ]              )              const              {getRootProps,              getInputProps,              isDragActive}              =              useDropzone              (              {onDrop}              )              render              (              <              div              {...getRootProps              (              )              }              >              <              input              {...getInputProps              (              )              }              /              >              {              isDragActive              ?              <              p              >Drib the files here ...<              /              p              >              :              <              p              >Drag 'due north' driblet some files here, or click to select files<              /              p              >              }              <              /              div              >              )              }            

Or the wrapper component for the hook:

              import              React              from              'react'              import              Dropzone              from              'react-dropzone'                            <              Dropzone              onDrop              =              {              acceptedFiles              =>              console              .              log              (              acceptedFiles              )              }              >              {              (              {getRootProps,              getInputProps}              )              =>              (              <              section              >              <              div              {...getRootProps              (              )              }              >              <              input              {...getInputProps              (              )              }              /              >              <              p              >Drag 'northward' drop some files hither, or click to select files<              /              p              >              <              /              div              >              <              /              section              >              )              }              <              /              Dropzone              >            

If you want to access file contents you have to employ the FileReader API:

              import              React              ,              {              useCallback              }              from              'react'              import              {              useDropzone              }              from              'react-dropzone'              function              MyDropzone              (              )              {              const              onDrop              =              useCallback              (              (              acceptedFiles              )              =>              {              acceptedFiles              .              forEach              (              (              file              )              =>              {              const              reader              =              new              FileReader              (              )              reader              .              onabort              =              (              )              =>              console              .              log              (              'file reading was aborted'              )              reader              .              onerror              =              (              )              =>              console              .              log              (              'file reading has failed'              )              reader              .              onload              =              (              )              =>              {              // Do whatever you want with the file contents              const              binaryStr              =              reader              .              result              console              .              log              (              binaryStr              )              }              reader              .              readAsArrayBuffer              (              file              )              }              )              }              ,              [              ]              )              const              {getRootProps,              getInputProps}              =              useDropzone              (              {onDrop}              )              return              (              <              div              {...getRootProps              (              )              }              >              <              input              {...getInputProps              (              )              }              /              >              <              p              >Elevate 'north' drib some files hither, or click to select files<              /              p              >              <              /              div              >              )              }            

Dropzone Props Getters

The dropzone property getters are just two functions that render objects with properties which you need to use to create the elevate 'northward' drop zone. The root backdrop tin exist applied to any element you desire, whereas the input backdrop must be applied to an <input>:

              import              React              from              'react'              import              {              useDropzone              }              from              'react-dropzone'              office              MyDropzone              (              )              {              const              {getRootProps,              getInputProps}              =              useDropzone              (              )              render              (              <              div              {...getRootProps              (              )              }              >              <              input              {...getInputProps              (              )              }              /              >              <              p              >Drag 'n' drop some files here, or click to select files<              /              p              >              <              /              div              >              )              }            

Annotation that whatsoever other props you want to add to the element where the props from getRootProps() are set, you should always pass them through that function rather than applying them on the element itself. This is in lodge to avoid your props beingness overridden (or overriding the props returned by getRootProps()):

              <              div              {...getRootProps              (              {              onClick:              event              =>              console              .              log              (              event              )              ,              function:              'button'              ,              'aria-label':              'drag and drop expanse'              ,              ...              }              )              }              /              >            

In the example above, the provided {onClick} handler volition be invoked before the internal one, therefore, internal callbacks tin be prevented by only using stopPropagation. Run across Events for more examples.

Important: if you omit rendering an <input> and/or bounden the props from getInputProps(), opening a file dialog volition not be possible.

Refs

Both getRootProps and getInputProps accept a custom refKey (defaults to ref) as ane of the attributes passed downward in the parameter.

This tin be useful when the chemical element y'all're trying to apply the props from either one of those fns does non expose a reference to the element, e.g:

              import              React              from              'react'              import              {              useDropzone              }              from              'react-dropzone'              // Annotation: After v4.0.0, styled components exposes a ref using forwardRef,              // therefore, no need for using innerRef as refKey              import              styled              from              'styled-components'              const              StyledDiv              =              styled              .              div              `                              // Some styling here              `              office              Example              (              )              {              const              {getRootProps,              getInputProps}              =              useDropzone              (              )              <              StyledDiv              {...getRootProps              (              {              refKey:              'innerRef'              }              )              }              >              <              input              {...getInputProps              (              )              }              /              >              <              p              >              Drag              'n'              drop              some              files              here              ,              or              click              to              select                            files              <                              /p>                            <              /StyledDiv>              }            

If y'all're working with Material UI v4 and would like to apply the root props on some component that does not betrayal a ref, apply RootRef:

              import              React              from              'react'              import              {              useDropzone              }              from              'react-dropzone'              import              RootRef              from              '@fabric-ui/core/RootRef'              function              PaperDropzone              (              )              {              const              {getRootProps,              getInputProps}              =              useDropzone              (              )              const              {ref,              ...rootProps              }              =              getRootProps              (              )              <              RootRef              rootRef              =              {ref}              >              <              Paper              {...rootProps              }              >              <              input              {...getInputProps              (              )              }              /              >              <              p              >Elevate 'n' drop some files here, or click to select files<              /              p              >              <              /              Paper              >              <                              /RootRef>                            }            

IMPORTANT: exercise not ready the ref prop on the elements where getRootProps()/getInputProps() props are ready, instead, get the refs from the hook itself:

              import              React              from              'react'              import              {              useDropzone              }              from              'react-dropzone'              function              Refs              (              )              {              const              {              getRootProps,              getInputProps,              rootRef,              // Ref to the `<div>`              inputRef              // Ref to the `<input>`              }              =              useDropzone              (              )              <              div              {...getRootProps              (              )              }              >              <              input              {...getInputProps              (              )              }              /              >              <              p              >              Drag              'due north'              drop              some              files              here              ,              or              click              to              select                            files              <                              /p>                              <                /div              >              }            

If y'all're using the <Dropzone> component, though, yous tin set the ref prop on the component itself which volition expose the {open} prop that can exist used to open the file dialog programmatically:

              import              React              ,              {              createRef              }              from              'react'              import              Dropzone              from              'react-dropzone'              const              dropzoneRef              =              createRef              (              )              <              Dropzone              ref              =              {dropzoneRef}              >              {              (              {getRootProps,              getInputProps}              )              =>              (              <              div              {...getRootProps              (              )              }              >              <              input              {...getInputProps              (              )              }              /              >              <              p              >Drag 'north' drop some files here, or click to select files<              /              p              >              <              /              div              >              )              }              <              /              Dropzone              >              dropzoneRef.open up()

Testing

react-dropzone makes some of its drag 'n' driblet callbacks asynchronous to enable promise based getFilesFromEvent() functions. In social club to test components that employ this library, you demand to use the react-testing-library:

              import              React              from              'react'              import              Dropzone              from              'react-dropzone'              import              {              act              ,              fireEvent              ,              render              ,              waitFor              }              from              '@testing-library/react'              test              (              'invoke onDragEnter when dragenter event occurs'              ,              async              (              )              =>              {              const              file              =              new              File              (              [              JSON              .              stringify              (              {              ping:              true              }              )              ]              ,              'ping.json'              ,              {              type:              'application/json'              }              )              const              data              =              mockData              (              [              file              ]              )              const              onDragEnter              =              jest              .              fn              (              )              const              ui              =              (              <              Dropzone              onDragEnter              =              {              onDragEnter              }              >              {              (              {              getRootProps,              getInputProps              }              )              =>              (              <              div              {...getRootProps              (              )              }              >              <              input              {...getInputProps              (              )              }              /              >              <              /              div              >              )              }              <              /              Dropzone              >              )              const              {              container,              rerender              }              =              render              (              ui              )              const              dropzone              =              container              .              querySelector              (              'div'              )              dispatchEvt              (              dropzone              ,              'dragenter'              ,              data              )              look              flushPromises              (              rerender              ,              ui              )              expect              (              onDragEnter              )              .              toHaveBeenCalled              (              )              }              )              async              function              flushPromises              (              rerender              ,              ui              )              {              look              act              (              (              )              =>              waitFor              (              (              )              =>              rerender              (              ui              )              )              )              }              role              dispatchEvt              (              node              ,              type              ,              data              )              {              const              result              =              new              Event              (              type              ,              {              bubbles:              true              }              )              Object              .              assign              (              result              ,              data              )              fireEvent              (              node              ,              event              )              }              function              mockData              (              files              )              {              return              {              dataTransfer:              {              files,              items:              files              .              map              (              file              =>              (              {              kind:              'file'              ,              blazon:              file              .              blazon              ,              getAsFile:              (              )              =>              file              }              )              )              ,              types:              [              'Files'              ]              }              }              }            

Note: using Enzyme for testing is not supported at the moment, see #2011.

More examples for this can be constitute in react-dropzone'south own examination suites.

Caveats

Required React Version

React 16.8 or above is required because we use hooks (the lib itself is a claw).

File Paths

Files returned by the hook or passed every bit arg to the onDrop cb won't have the properties path or fullPath. For more inf bank check this SO question and this issue.

Not a File Uploader

This lib is non a file uploader; equally such, it does not process files or provide any mode to make HTTP requests to some server; if you're looking for that, checkout filepond or uppy.io.

Using <label> as Root

If you use <label> as the root element, the file dialog will be opened twice; run across #1107 why. To avoid this, employ noClick:

              import              React              ,              {              useCallback              }              from              'react'              import              {              useDropzone              }              from              'react-dropzone'              function              MyDropzone              (              )              {              const              {getRootProps,              getInputProps}              =              useDropzone              (              {              noClick:              true              }              )              return              (              <              label              {...getRootProps              (              )              }              >              <              input              {...getInputProps              (              )              }              /              >              <              /              characterization              >              )              }            

Using open() on Click

If you bind a click event on an inner chemical element and use open(), information technology volition trigger a click on the root element also, resulting in the file dialog opening twice. To preclude this, utilise the noClick on the root:

              import              React              ,              {              useCallback              }              from              'react'              import              {              useDropzone              }              from              'react-dropzone'              function              MyDropzone              (              )              {              const              {getRootProps,              getInputProps,              open}              =              useDropzone              (              {              noClick:              true              }              )              return              (              <              div              {...getRootProps              (              )              }              >              <              input              {...getInputProps              (              )              }              /              >              <              push button              type              =              "button"              onClick              =              {              open up              }              >              Open              <              /              push button              >              <              /              div              >              )              }            

File Dialog Cancel Callback

The onFileDialogCancel() cb is unstable in most browsers, pregnant, in that location'southward a good chance of it being triggered even though you lot have selected files.

We rely on using a timeout of 300ms after the window is focused (the window onfocus effect is triggered when the file select dialog is airtight) to check if any files were selected and trigger onFileDialogCancel if none were selected.

As i can imagine, this doesn't really work if in that location's a lot of files or big files equally by the time we trigger the bank check, the browser is nevertheless processing the files and no onchange events are triggered notwithstanding on the input. Check #1031 for more info.

Fortunately, there's the File System Access API, which is currently a working draft and some browsers support information technology (see browser compatibility), that provides a reliable manner to prompt the user for file choice and capture cancellation.

And this lib makes utilise of it if bachelor. Though, there's a small catch: using file extensions for the accept property is not supported; you must utilise MIME types as described in common MIME types. Also check accepting specific file types for more info on the bailiwick of accept limitations.

Also keep in heed that the FS access API can only be used in secure contexts.

NOTE You tin can disable using the FS admission API with the useFsAccessApi property: useDropzone({useFsAccessApi: false}).

Supported Browsers

We use browserslist config to country the browser support for this lib, so check it out on browserslist.dev.

Need epitome editing?

React Dropzone integrates perfectly with Pintura Paradigm Editor, creating a modern image editing experience. Pintura supports crop aspect ratios, resizing, rotating, cropping, annotating, filtering, and much more than.

Checkout the Pintura integration instance.

Support

Backers

Support us with a monthly donation and help united states continue our activities. [Go a backer]

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site. [Go a sponsor]

Hosting

react-dropzone.js.org hosting provided past netlify.

License

MIT

spellmanrouresing77.blogspot.com

Source: https://github.com/react-dropzone/react-dropzone

0 Response to "Dropzone Prevent Multiple Uploads With Ctrl Click"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel