Files

    {files}

);

}

Dropzone with disabled property: Drag 'n' drop some files here, or click to select files

FILES

View Code

import React from 'react'; import {useDropzone} from 'react-dropzone'; function Basic(props) { const {acceptedFiles, getRootProps, getInputProps} = useDropzone({ disabled: true }); const files = acceptedFiles.map(file => (
  • {file.name} - {file.size} bytes
  • )); return (

    Drag 'n' drop some files here, or click to select files

    ); } import React from 'react'; import {useDropzone} from 'react-dropzone'; function Basic(props) { const {acceptedFiles, getRootProps, getInputProps} = useDropzone({

    disabled: true

    });

    const files = acceptedFiles.map(file => ( {file.name} - {file.size} bytes

    ));

    return (

    Drag 'n' drop some files here, or click to select files

    Files

      {files}

    );

    }

    EVENT PROPAGATION

    If you'd like to prevent drag events propagation from the child to parent, you can use the {noDragEventsBubbling} property on the child:

    Inner dropzone

    Outer dropzone

    View Code

    import React from 'react'; import {useDropzone} from 'react-dropzone'; function OuterDropzone(props) { const {getRootProps} = useDropzone({ // Note how this callback is never invoked if drop occurs on the inner dropzone onDrop: files => console.log(files) }); return (

    Outer dropzone

    ); } function InnerDropzone(props) { const {getRootProps} = useDropzone({noDragEventsBubbling: true}); return (

    Inner dropzone

    ); } import React from 'react'; import {useDropzone} from 'react-dropzone'; function OuterDropzone(props) { const {getRootProps} = useDropzone({ // Note how this callback is never invoked if drop occurs on the inner dropzone onDrop: files => console.log(files)

    });

    return (

    Outer dropzone

    );

    }

    function InnerDropzone(props) { const {getRootProps} = useDropzone({noDragEventsBubbling: true});

    return (

    Inner dropzone

    );

    }

    Note that internally we use event.stopPropagation() to achieve the behavior illustrated above, but this comes with its own drawbacks

    .

    If you'd like to selectively turn off the default dropzone behavior for onClick, use the {noClick} property: Dropzone without click events

    FILES

    View Code

    import React from 'react'; import {useDropzone} from 'react-dropzone'; function DropzoneWithoutClick(props) { const {getRootProps, getInputProps, acceptedFiles} = useDropzone({noClick: true}); const files = acceptedFiles.map(file =>
  • {file.path}
  • ); return (

    Dropzone without click events

    ); } import React from 'react'; import {useDropzone} from 'react-dropzone'; function DropzoneWithoutClick(props) { const {getRootProps, getInputProps, acceptedFiles} = useDropzone({noClick: true}); const files = acceptedFiles.map(file => {file.path});

    return (

    Dropzone without click events

    Files

      {files}

    );

    }

    If you'd like to selectively turn off the default dropzone behavior for onKeyDown, onFocus and onBlur, use the {noKeyboard} property: Dropzone without keyboard events _(SPACE/ENTER and focus events are disabled)_

    FILES

    View Code

    import React from 'react'; import {useDropzone} from 'react-dropzone'; function DropzoneWithoutKeyboard(props) { const {getRootProps, getInputProps, acceptedFiles} = useDropzone({noKeyboard: true}); const files = acceptedFiles.map(file =>
  • {file.path}
  • ); return (

    Dropzone without keyboard events

    (SPACE/ENTER and focus events are disabled)
    ); } import React from 'react'; import {useDropzone} from 'react-dropzone'; function DropzoneWithoutKeyboard(props) { const {getRootProps, getInputProps, acceptedFiles} = useDropzone({noKeyboard: true}); const files = acceptedFiles.map(file => {file.path});

    return (

    Dropzone without keyboard events

    (SPACE/ENTER and focus events are disabled)

    Files

      {files}

    );

    }

    Note that you can prevent the default behavior for click and keyboard events if you ommit the input: Dropzone without click events

    FILES

    View Code

    import React from 'react'; import {useDropzone} from 'react-dropzone'; function DropzoneWithoutClick(props) { const {getRootProps, acceptedFiles} = useDropzone(); const files = acceptedFiles.map(file =>
  • {file.path}
  • ); return (

    Dropzone without click events

    ); } import React from 'react'; import {useDropzone} from 'react-dropzone'; function DropzoneWithoutClick(props) { const {getRootProps, acceptedFiles} = useDropzone(); const files = acceptedFiles.map(file => {file.path});

    return (

    Dropzone without click events

    Files

      {files}

    );

    }

    If you'd like to selectively turn off the default dropzone behavior for drag events, use the {noDrag} property: Dropzone with no drag events _(Drag 'n' drop is disabled)_

    FILES

    View Code

    import React from 'react'; import {useDropzone} from 'react-dropzone'; function DropzoneWithoutDrag(props) { const {getRootProps, getInputProps, acceptedFiles} = useDropzone({noDrag: true}); const files = acceptedFiles.map(file =>
  • {file.path}
  • ); return (

    Dropzone with no drag events

    (Drag 'n' drop is disabled)
    ); } import React from 'react'; import {useDropzone} from 'react-dropzone'; function DropzoneWithoutDrag(props) { const {getRootProps, getInputProps, acceptedFiles} = useDropzone({noDrag: true}); const files = acceptedFiles.map(file => {file.path});

    return (

    Dropzone with no drag events

    (Drag 'n' drop is disabled)

    Files

      {files}

    );

    }

    Keep in mind that if you provide your own callback handlers as well and use event.stopPropagation(), it will prevent the default dropzone

    behavior:

    Drag 'n' drop some files here, or click to select files

    View Code

    import React from 'react'; import Dropzone from 'react-dropzone'; // Note that there will be nothing logged when files are dropped console.log(files)}> {({getRootProps, getInputProps}) => (
    event.stopPropagation() })} >

    Drag 'n' drop some files here, or click to select files

    )}

    import React from 'react'; import Dropzone from 'react-dropzone'; // Note that there will be nothing logged when files are dropped  console.log(files)}> {({getRootProps, getInputProps}) => (

    {...getRootProps({

    className: 'dropzone', onDrop: event => event.stopPropagation()

    })}

    >

    Drag 'n' drop some files here, or click to select files

    )}

    STYLING DROPZONE

    The hook fn doesn't set any styles on either of the prop fns (getRootProps()/getInputProps()).

    USING INLINE STYLES

    Drag 'n' drop some files here, or click to select files

    View Code

    import React, {useMemo} from 'react'; import {useDropzone} from 'react-dropzone'; const baseStyle = { flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '20px', borderWidth: 2, borderRadius: 2, borderColor: '#eeeeee', borderStyle: 'dashed', backgroundColor: '#fafafa', color: '#bdbdbd', outline: 'none', transition: 'border .24s ease-in-out' }; const activeStyle = { borderColor: '#2196f3' }; const acceptStyle = { borderColor: '#00e676' }; const rejectStyle = { borderColor: '#ff1744' }; function StyledDropzone(props) { const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject } = useDropzone({accept: 'image/*'}); const style = useMemo(() => ({ ...baseStyle, ...(isDragActive ? activeStyle : {}), ...(isDragAccept ? acceptStyle : {}), ...(isDragReject ? rejectStyle : {}) }), ); return (

    Drag 'n' drop some files here, or click to select files

    ); }

    import React, {useMemo} from 'react'; import {useDropzone} from 'react-dropzone'; const baseStyle = {

    flex: 1,

    display: 'flex',

    flexDirection: 'column', alignItems: 'center',

    padding: '20px',

    borderWidth: 2,

    borderRadius: 2,

    borderColor: '#eeeeee', borderStyle: 'dashed', backgroundColor: '#fafafa',

    color: '#bdbdbd',

    outline: 'none',

    transition: 'border .24s ease-in-out'

    };

    const activeStyle = { borderColor: '#2196f3'

    };

    const acceptStyle = { borderColor: '#00e676'

    };

    const rejectStyle = { borderColor: '#ff1744'

    };

    function StyledDropzone(props) {

    const {

    getRootProps,

    getInputProps,

    isDragActive,

    isDragAccept,

    isDragReject

    } = useDropzone({accept: 'image/*'}); const style = useMemo(() => ({

    ...baseStyle,

    ...(isDragActive ? activeStyle : {}), ...(isDragAccept ? acceptStyle : {}), ...(isDragReject ? rejectStyle : {})

    }), );

    return (

    Drag 'n' drop some files here, or click to select files

    );

    }

    USING STYLED-COMPONENTS Drag 'n' drop some files here, or click to select files

    View Code

    import React from 'react'; import {useDropzone} from 'react-dropzone'; import styled from 'styled-components'; const getColor = (props) => { if (props.isDragAccept) { return '#00e676'; } if (props.isDragReject) { return '#ff1744'; } if (props.isDragActive) { return '#2196f3'; } return '#eeeeee'; } const Container = styled.div` flex: 1; display: flex; flex-direction: column; align-items: center; padding: 20px; border-width: 2px; border-radius: 2px; border-color: ${props => getColor(props)}; border-style: dashed; background-color: #fafafa; color: #bdbdbd; outline: none; transition: border .24s ease-in-out; `; function StyledDropzone(props) { const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject } = useDropzone({accept: 'image/*'}); return (

    Drag 'n' drop some files here, or click to select files

    ); } import React from 'react'; import {useDropzone} from 'react-dropzone'; import styled from 'styled-components'; const getColor = (props) => { if (props.isDragAccept) {

    return '#00e676';

    }

    if (props.isDragReject) {

    return '#ff1744';

    }

    if (props.isDragActive) {

    return '#2196f3';

    }

    return '#eeeeee';

    }

    const Container = styled.div`

    flex: 1;

    display: flex;

    flex-direction: column; align-items: center;

    padding: 20px;

    border-width: 2px;

    border-radius: 2px; border-color: ${props => getColor(props)}; border-style: dashed; background-color: #fafafa;

    color: #bdbdbd;

    outline: none;

    transition: border .24s ease-in-out;

    `;

    function StyledDropzone(props) {

    const {

    getRootProps,

    getInputProps,

    isDragActive,

    isDragAccept,

    isDragReject

    } = useDropzone({accept: 'image/*'});

    return (

    Drag 'n' drop some files here, or click to select files

    );

    }

    ACCEPTING SPECIFIC FILE TYPES By providing accept prop you can make the dropzone accept specific file types and reject the others. The value must be a comma-separated list of unique content type

    specifiers:

    * A file extension starting with the STOP character (U+002E). (e.g.

    .jpg, .png, .doc).

    * A valid MIME type with no extensions. * audio/* representing sound files. * video/* representing video files. * image/* representing image files. For more information see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input Drag 'n' drop some files here, or click to select files _(Only *.jpeg and *.png images will be accepted)_

    ACCEPTED FILES

    REJECTED FILES

    View Code

    import React from 'react'; import {useDropzone} from 'react-dropzone'; function Accept(props) { const {acceptedFiles, rejectedFiles, getRootProps, getInputProps} = useDropzone({ accept: 'image/jpeg, image/png' }); const acceptedFilesItems = acceptedFiles.map(file => (
  • {file.path} - {file.size} bytes
  • )); const rejectedFilesItems = rejectedFiles.map(file => (
  • {file.path} - {file.size} bytes
  • )); return (

    Drag 'n' drop some files here, or click to select files

    (Only *.jpeg and *.png images will be accepted)
    ); } import React from 'react'; import {useDropzone} from 'react-dropzone'; function Accept(props) { const {acceptedFiles, rejectedFiles, getRootProps, getInputProps} = useDropzone({ accept: 'image/jpeg, image/png'

    });

    const acceptedFilesItems = acceptedFiles.map(file => ( {file.path} - {file.size} bytes

    ));

    const rejectedFilesItems = rejectedFiles.map(file => ( {file.path} - {file.size} bytes

    ));

    return (

    Drag 'n' drop some files here, or click to select files

    (Only *.jpeg and *.png images will be accepted)

    Accepted files

      {acceptedFilesItems}

      Rejected files

        {rejectedFilesItems}

        );

        }

        BROWSER LIMITATIONS

        Because of HTML5 File API differences across different browsers during the drag, Dropzone might not be able to detect whether the files are accepted or rejected in Safari nor IE. Furthermore, at this moment it's not possible to read file names (and thus, file extensions) during the drag operation. For that reason, if you want to react on different file types _during_ the drag operation, _you have to use_ mime types and not extensions! For example, the following example won't work even in Chrome: Drop some files here ...

        View Code

        import React from 'react'; import {useDropzone} from 'react-dropzone'; function Accept(props) { const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject } = useDropzone({ accept: '.jpeg,.png' }); return (
        {isDragAccept && (

        All files will be accepted

        )} {isDragReject && (

        Some files will be rejected

        )} {!isDragActive && (

        Drop some files here ...

        )}
        );

        }

        import React from 'react'; import {useDropzone} from 'react-dropzone'; function Accept(props) {

        const {

        getRootProps,

        getInputProps,

        isDragActive,

        isDragAccept,

        isDragReject

        } = useDropzone({

        accept: '.jpeg,.png'

        });

        return (

        {isDragAccept && (

        All files will be accepted

        )} {isDragReject && (

        Some files will be rejected

        )} {!isDragActive && (

        Drop some files here ...

        )}

        );

        }

        but this one will:

        Drop some files here ...

        View Code

        import React from 'react'; import {useDropzone} from 'react-dropzone'; function Accept(props) { const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject } = useDropzone({ accept: 'image/jpeg, image/png' }); return (
        {isDragAccept && (

        All files will be accepted

        )} {isDragReject && (

        Some files will be rejected

        )} {!isDragActive && (

        Drop some files here ...

        )}
        );

        }

        import React from 'react'; import {useDropzone} from 'react-dropzone'; function Accept(props) {

        const {

        getRootProps,

        getInputProps,

        isDragActive,

        isDragAccept,

        isDragReject

        } = useDropzone({

        accept: 'image/jpeg, image/png'

        });

        return (

        {isDragAccept && (

        All files will be accepted

        )} {isDragReject && (

        Some files will be rejected

        )} {!isDragActive && (

        Drop some files here ...

        )}

        );

        }

        NOTES

        Mime type determination is not reliable accross platforms. CSV files, for example, are reported as text/plain under macOS but as application/vnd.ms-excel under Windows. In some cases there might not be a mime type set at all. OPENING FILE DIALOG PROGRAMMATICALLY You can programmatically invoke the default OS file prompt; just use the open method returned by the hook. NOTE that for security reasons most browsers require popups and dialogues to originate from a direct user interaction (i.e. click). If you are calling open() asynchronously, there’s a good chance it’s going to be blocked by the browser. So if you are calling open() asynchronously, be sure there is no more than _1000ms_ delay between user interaction and open() call. Due to the lack of official docs on this (at least we haven’t found any. If you know one, feel free to open PR), there is no guarantee that ALLOWED DELAY DURATION will not be changed in later browser versions. Since implementations may differ between different browsers, avoid calling open asynchronously if possible. Drag 'n' drop some files here

        Open File Dialog

        FILES

        View Code

        import React from 'react'; import {useDropzone} from 'react-dropzone'; function Dropzone(props) { const {getRootProps, getInputProps, open, acceptedFiles} = useDropzone({ // Disable click and keydown behavior noClick: true, noKeyboard: true }); const files = acceptedFiles.map(file => (
      • {file.path} - {file.size} bytes
      • )); return (

        Drag 'n' drop some files here

        ); } />

        import React from 'react'; import {useDropzone} from 'react-dropzone'; function Dropzone(props) { const {getRootProps, getInputProps, open, acceptedFiles} = useDropzone({ // Disable click and keydown behavior

        noClick: true,

        noKeyboard: true

        });

        const files = acceptedFiles.map(file => ( {file.path} - {file.size} bytes

        ));

        return (

        Drag 'n' drop some files here

        Open File Dialog

        Files

          {files}

        );

        }

        Or use the ref exposed by the component: Drag 'n' drop some files here

        Open File Dialog

        FILES

        View Code

        import React, {createRef} from 'react'; import Dropzone from 'react-dropzone'; const dropzoneRef = createRef(); const openDialog = () => { // Note that the ref is set async, // so it might be null at some point if (dropzoneRef.current) { dropzoneRef.current.open() } }; // Disable click and keydown behavior on the {({getRootProps, getInputProps, acceptedFiles}) => { return (

        Drag 'n' drop some files here

        ); }}
        import React, {createRef} from 'react'; import Dropzone from 'react-dropzone'; const dropzoneRef = createRef(); const openDialog = () => { // Note that the ref is set async, // so it might be null at some point if (dropzoneRef.current) { dropzoneRef.current.open()

        }

        };

        // Disable click and keydown behavior on the  {({getRootProps, getInputProps, acceptedFiles}) => {

        return (

        Drag 'n' drop some files here

        type="button"

        onClick={openDialog}

        >

        Open File Dialog

        Files

          {acceptedFiles.map(file => ( {file.path} - {file.size} bytes

          ))}

          );

          }}

          PREVIEWS

          Starting with version 7.0.0, the {preview} property generation on the

          File objects

          and the {disablePreview} property on the have been removed. If you need need the {preview}, it can be easily achieved in the

          onDrop() callback:

          Drag 'n' drop some files here, or click to select files

          View Code

          import React, {useEffect, useState} from 'react'; import {useDropzone} from 'react-dropzone'; const thumbsContainer = { display: 'flex', flexDirection: 'row', flexWrap: 'wrap', marginTop: 16 }; const thumb = { display: 'inline-flex', borderRadius: 2, border: '1px solid #eaeaea', marginBottom: 8, marginRight: 8, width: 100, height: 100, padding: 4, boxSizing: 'border-box' }; const thumbInner = { display: 'flex', minWidth: 0, overflow: 'hidden' }; const img = { display: 'block', width: 'auto', height: '100%' }; function Previews(props) { const = useState(); const {getRootProps, getInputProps} = useDropzone({ accept: 'image/*', onDrop: acceptedFiles => { setFiles(acceptedFiles.map(file => Object.assign(file, { preview: URL.createObjectURL(file) }))); } }); const thumbs = files.map(file => (
          )); useEffect(() => () => { // Make sure to revoke the data uris to avoid memory leaks files.forEach(file => URL.revokeObjectURL(file.preview)); }, ); return (

          Drag 'n' drop some files here, or click to select files

          ); } />import React, {useEffect, useState} from 'react'; import {useDropzone} from 'react-dropzone'; const thumbsContainer = {

          display: 'flex',

          flexDirection: 'row',

          flexWrap: 'wrap',

          marginTop: 16

          };

          const thumb = {

          display: 'inline-flex',

          borderRadius: 2,

          border: '1px solid #eaeaea',

          marginBottom: 8,

          marginRight: 8,

          width: 100,

          height: 100,

          padding: 4,

          boxSizing: 'border-box'

          };

          const thumbInner = {

          display: 'flex',

          minWidth: 0,

          overflow: 'hidden'

          };

          const img = {

          display: 'block',

          width: 'auto',

          height: '100%'

          };

          function Previews(props) { const  = useState(); const {getRootProps, getInputProps} = useDropzone({

          accept: 'image/*',

          onDrop: acceptedFiles => { setFiles(acceptedFiles.map(file => Object.assign(file, { preview: URL.createObjectURL(file)

          })));

          }

          });

          const thumbs = files.map(file => (

          src={file.preview}

          style={img}

          />

          ));

          useEffect(() => () => { // Make sure to revoke the data uris to avoid memory leaks files.forEach(file => URL.revokeObjectURL(file.preview));

          }, );

          return (

          Drag 'n' drop some files here, or click to select files

          {thumbs}

          );

          }

          CLASS COMPONENTS

          If you're still using class components, you can use the component provided by the

          lib:

          Drag 'n' drop some files here, or click to select files

          FILES

          View Code

          import React, {Component} from 'react'; import Dropzone from 'react-dropzone'; class Basic extends Component { constructor() { super(); this.onDrop = (files) => { this.setState({files}) }; this.state = { files: }; } render() { const files = this.state.files.map(file => (
        • {file.name} - {file.size} bytes
        • )); return ( {({getRootProps, getInputProps}) => (

          Drag 'n' drop some files here, or click to select files

          )}
          ); } } import React, {Component} from 'react'; import Dropzone from 'react-dropzone'; class Basic extends Component {

          constructor() {

          super();

          this.onDrop = (files) => { this.setState({files})

          };

          this.state = {

          files:

          };

          }

          render() {

          const files = this.state.files.map(file => ( {file.name} - {file.size} bytes

          ));

          return (

          {({getRootProps, getInputProps}) => (

          Drag 'n' drop some files here, or click to select files

          Files

            {files}

          )}

          );

          }

          }

          EXTENDING DROPZONE

          The hook accepts a getFilesFromEvent prop that enhances the handling of dropped file system objects and allows more flexible use of them e.g. passing a function that accepts drop event of a folder and resolves it to an array of files adds plug-in functionality of folders

          drag-and-drop.

          Though, note that the provided getFilesFromEvent fn must return a Promise with a list of File objects (or DataTransferItem of {kind: 'file'} when data cannot be accessed). Otherwise, the results will be discarded and none of the drag events callbacks will be invoked. In case you need to extend the File with some additional properties, you should use Object.defineProperty() so that the result will still pass through our filter: Drag 'n' drop some files here, or click to select files

          FILES

          View Code

          import React from 'react'; import {useDropzone} from 'react-dropzone'; function Plugin(props) { const {acceptedFiles, getRootProps, getInputProps} = useDropzone({ getFilesFromEvent: event => myCustomFileGetter(event) }); const files = acceptedFiles.map(f => (
        • {f.name} has myProps: {f.myProp === true ? 'YES' : ''}
        • )); return (

          Drag 'n' drop some files here, or click to select files

          ); } async function myCustomFileGetter(event) { const files = ; const fileList = event.dataTransfer ? event.dataTransfer.files : event.target.files; for (var i = 0; i < fileList.length; i++) { const file = fileList.item(i); Object.defineProperty(file, 'myProp', { value: true }); files.push(file); } return files; } import React from 'react'; import {useDropzone} from 'react-dropzone'; function Plugin(props) { const {acceptedFiles, getRootProps, getInputProps} = useDropzone({ getFilesFromEvent: event => myCustomFileGetter(event)

          });

          const files = acceptedFiles.map(f => (

          {f.name} has myProps: {f.myProp === true ? 'YES' : ''}

          ));

          return (

          Drag 'n' drop some files here, or click to select files

          Files

            {files}

          );

          }

          async function myCustomFileGetter(event) {

          const files = ;

          const fileList = event.dataTransfer ? event.dataTransfer.files : event.target.files; for (var i = 0; i < fileList.length; i++) { const file = fileList.item(i); Object.defineProperty(file, 'myProp', {

          value: true

          });

          files.push(file);

          }

          return files;

          }

          Created with React Styleguidist

          Details

          3