🦋 Component for building file fields - from basic file inputs to drag and drop image galleries.

Overview

🦋 react-butterfiles

Build Status Coverage Status code style: prettier All Contributors PRs Welcome

A small component for building file upload fields of any type, for example a simple file upload button or an image gallery field with drag and drop support and preview of selected images.

Install

npm install --save react-butterfiles

Or if you prefer yarn:

yarn add react-butterfiles

Quick Example:

Create a simple file field which consists of a drop zone and a file upload button (for cases where drag and drop is not convenient). Multiple PDF / JPG files are accepted, but with the following restrictions:

  • 3 files max
  • max 2MB in size per file
  • max 10MB in size for the whole selection
import Files from "react-butterfiles";
<Files
    multiple={true} 
    maxSize="2mb"
    multipleMaxSize="10mb"
    multipleMaxCount={3}
    accept={["application/pdf","image/jpg","image/jpeg"]}
    onSuccess={files => this.setState({ files })}
    onError={errors => this.setState({ errors })}
>
    {({ browseFiles, getDropZoneProps, getLabelProps }) => (
        <>
            <label {...getLabelProps()}>Your files</label>
            <div {...getDropZoneProps({ className: "myDropZone" })}/>
            <button onClick={browseFiles}>Select files...</button>
            <ol>
                {this.state.files.map(file => (
                    <li key={file.name}>{file.name}</li>
                ))}
                {this.state.errors.map(error => (
                    <li key={error.file.name}>
                        {error.file.name} - {error.type}
                    </li>
                ))}
            </ol>
        </>
    )}
</Files>

More examples on https://react-butterfiles.netlify.com.

Props

Prop Type Default Description
accept Array<string> [] Defines which file types will be accepted. Example: ["application/pdf"].
multiple boolean false Allow multiple file selection by setting this prop to `true.
maxSize string "2mb" Defines maximum file size (bytes lib used behind the scenes). Example: "10mb"
multipleMaxSize string "10mb" Useful only if multiple prop is set to true. Defines max. file size of all selected files.
multipleMaxCount number null Useful only if multiple prop is set to true. Defines max. allowed selected files.
convertToBase64 boolean false If true, selected files will also be converted to baser64 format (useful when working with images / thumbnails).
onSuccess (files: Array<SelectedFile>) => void undefined Callback that will get executed once a valid file selection has been made (via browse files dialog or drag and drop). Each file will have a random id assigned to it.
onError (errors: Array<FileError>) => void undefined Callback that will get executed once an invalid file selection has been made. Each error will have a random id assigned to it. More info about possible errors below.

Render (children) prop

Render prop gives you access to three callbacks:

Prop Type Description
browseFiles BrowseFilesParams => void Once executed, file browser will be shown. Useful for file upload buttons. The callback can also accept custom onSuccess and onError callbacks, that will override the main ones.
validate (files: Array<File>) => Array<FileError> Enables manual validation of files. Eg. after editing the selected image in an image editor.
getDropZoneProps (additionalProps: ?Object) => Object Props that need to be spread to a drop zone. Additional props can be passed, for example className or style.
getLabelProps (additionalProps: ?Object) => Object Props that need to be spread to your file field's label. Additional props can be passed, for example className or style.

Note that you don't need to have both upload file and drop zone, you can use only one if that's your requirement. For example, to create a simple file field, you would only need to use the browseFiles callback.

Selection error types

While selecting and dropping files, if there are one or more that do not comply with the rules that were set via props, an onError callback will be triggered, with all of the errors passed as the first argument.

Every error in the array will have one of the following error types.

Type Description
unsupportedFileType This can only happen via drag and drop since file browser dialog won't let users choose files of invalid type.
maxSizeExceeded One or more file sizes are greater than maxSize value.
multipleMaxCountExceeded User selected more files than allowed (more than multipleMaxCount).
multipleMaxSizeExceeded User selected one or more files with their total size greater than allowed (more than multipleMaxSize).
multipleNotAllowed This can only happen via drag and drop since file browser dialog won't let users select two or more files if multiple was not set to true.

Contributors

Thanks goes to these wonderful people (emoji key):

Adrian Smijulj
Adrian Smijulj

💻 📖 💡 👀 ⚠️
readeral
readeral

💻 📖

This project follows the all-contributors specification. Contributions of any kind welcome!

Comments
  • Removing wrapping div

    Removing wrapping div

    Can I propose the removal of the wrapping <div> in favour of a fragment, as it's stopping the <input> from being laid out on on css grid (and any other CSS descendant-reliant situation).

    I don't know what other implications there might be for removing the wrapping div, so happy to have this pull request rejected. I just have found that I couldn't use this library within my grid layout without even more wrapping <div>s because any grid CSS I was passing through props wasn't ultimately able to be applied to the input.

    Related Issue

    Your solution

    How Has This Been Tested?

    Screenshots (if relevant):

    bug released 
    opened by readeral 4
  • Question:: how to get files?

    Question:: how to get files?

    @doitadrian Is it possible to get files from input after upload?

    document.getElementById('selectedFiles').files

    Files array is empty. Is there another way?

    opened by sT0pe 4
  • Incorrect prop in documentation

    Incorrect prop in documentation

    This is:

    • Documentation error

    Specifications

    • version:
    • OS:
    • Browser:

    Expected Behavior

    https://github.com/doitadrian/react-butterfiles#props should have maxSize listed as a prop

    Actual Behavior

    incorrectly has maxFileSize

    Possible Solution

    Pull request submitted

    opened by readeral 3
  • Wrapping div causes styling limitations

    Wrapping div causes styling limitations

    This is:

    • Bug
    • Feature request

    Specifications

    • version:
    • OS:
    • Browser:

    Expected Behavior

    Passing the <input> a grid item property via the getDropZoneProps should result in the <input> being laid out upon the grid

    Actual Behavior

    Due to to the component's wrapping <div>, the <input> is not a direct child of a wrapper with the display: grid property, and so is not placed on the grid.

    Steps to Reproduce the Problem

    1. Place <Files /> component within a wrapping <div> with the css property of display: grid and other grid related syntax
    2. Pass css props via getDropZoneProps placing the input on a grid (e.g. grid-column: 1/2
    3. input will not position correctly

    Detailed Description

    See pull request

    Possible Solution

    See pull request

    opened by readeral 1
  • Update getDropZoneProps to pass the event object

    Update getDropZoneProps to pass the event object

    Currently, any custom handlers for onDragOver and onDrop do not receive the event object. This unobtrusive code change allows developers to access the event object.

    Related Issue

    Well, take it or leave it, this change is so small I'm not going to open an issue. Either merge or delete the PR.

    Your solution

    Just pass the event object. It was probably an oversight.

    How Has This Been Tested?

    Shouldn't need testing

    Screenshots (if relevant):

    N/A

    opened by kensnyder 0
  • chore(deps-dev): bump semantic-release from 15.13.2 to 17.2.3

    chore(deps-dev): bump semantic-release from 15.13.2 to 17.2.3

    Bumps semantic-release from 15.13.2 to 17.2.3.

    Release notes

    Sourced from semantic-release's releases.

    v17.2.3

    17.2.3 (2020-11-16)

    Bug Fixes

    • mask secrets when characters get uri encoded (ca90b34)

    v17.2.2

    17.2.2 (2020-10-29)

    Bug Fixes

    • don't parse port as part of the path in repository URLs (#1671) (77a75f0)
    • use valid git credentials when multiple are provided (#1669) (2bf3771)

    v17.2.1

    17.2.1 (2020-10-12)

    Reverts

    • Revert "feat: throw an Error if package.json has duplicate "repository" key (#1656)" (3abcbaf), closes #1656 #1657

    v17.2.0

    17.2.0 (2020-10-11)

    Features

    • throw an Error if package.json has duplicate "repository" key (#1656) (b8fb35c)

    v17.1.2

    17.1.2 (2020-09-17)

    Bug Fixes

    • add logging for when ssh falls back to http (#1639) (b4c5d0a)

    v17.1.1

    17.1.1 (2020-06-25)

    Bug Fixes

    v17.1.0

    ... (truncated)

    Commits
    • c8d38b6 style: removed line breaks to align with xo rule (#1689)
    • ca90b34 fix: mask secrets when characters get uri encoded
    • 63fa143 docs(plugins): add listing for new plugin (#1686)
    • 2bf3771 fix: use valid git credentials when multiple are provided (#1669)
    • 77a75f0 fix: don't parse port as part of the path in repository URLs (#1671)
    • d74ffef docs: add npm-deprecate-old-versions in plugins list (#1667)
    • 3abcbaf Revert "feat: throw an Error if package.json has duplicate "repository" key (...
    • b8fb35c feat: throw an Error if package.json has duplicate "repository" key (#1656)
    • 18e35b2 docs: reorder default plugins list (#1650)
    • e35e5bb docs(contributing): fix commit message examples (#1648)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Add a filter by file name in regex format

    Add a filter by file name in regex format

    This is:

    • Feature request
    • Idea

    Detailed Description

    For example, Microsoft SharePoint has the following restrictions on the file name: Information about the characters that you cannot use in file names:

    • Do not use: " # % & * : < > ? \ / { | } ~
    • File names cannot be longer than 128 characters
    • Do not use the period character consecutively in the middle of a file name. For example, "file..name.docx" is invalid.
    • You cannot use the period character at the end of a file name. For example, “filename..docx” is invalid.
    • You cannot start a file name with the period character
    • Many other symbols are not recommended such as $^()-_=+[]`! (other international currency symbols and international symbols should be avoided in site names, but some are more acceptable in file names. Ascii is preferred when possible.

    Possible Solution

    Possible property name: filter or regexFilter

    opened by kvvinokurov 0
  • Add a basic look for the drop zone

    Add a basic look for the drop zone

    This is:

    • Bug
    • Question

    Expected Behavior

    It is necessary that when you hover the file over the entire File component, the entire area would be a drop zone with a similar design. example

    Actual Behavior

    Drop zone is presented as in the example, but it does not work because it has zero height. <div {...getDropZoneProps({className: "myDropZone"})}/>

    Steps to Reproduce the Problem

    1. Add the code from the example
    2. Move a file to the zone of the File component
    3. Now this zone by default resembles the eye of a needle

    Possible Solution

    Displaying the drop zone in full size is initially simple, but visually not beautiful, because takes up a lot of space. But if you make a hover effect, in which the entire zone of the File component becomes a drop zone - this is cool.

    opened by kvvinokurov 0
Releases(v1.3.3)
Owner
Adrian Smijulj
Core Developer @webiny
Adrian Smijulj
Drag and drop page builder and CMS for React, Vue, Angular, and more

Drag and drop page builder and CMS for React, Vue, Angular, and more Use your code components and the stack of your choice. No more being pestered for

Builder.io 4.2k Jan 1, 2023
Beautiful and accessible drag and drop for lists with React

react-beautiful-dnd (rbd) Beautiful and accessible drag and drop for lists with React Play with this example if you want! Core characteristics Beautif

Atlassian 28.9k Dec 31, 2022
🔀 Drag and drop for your React lists and tables. Accessible. Tiny.

react-movable See all the other examples and their source code! Installation yarn add react-movable Usage import * as React from 'react'; import { Li

Vojtech Miksu 1.3k Dec 30, 2022
ReactJS drag and drop functionality for mouse and touch devices

DragDropContainer and DropTarget Live demo: peterh32.github.io/react-drag-drop-container Features Very easy to implement and understand. Works on mous

Peter Hollingsworth 142 Sep 26, 2022
React drag and drop sort support flex layout and nested.

react-flex-dnd React drag and drop sort support flex layout and nested. This package using hooks, note that your React version is above 16.8 :) Why fl

lvshihao 7 Nov 14, 2022
Drag and Drop for React

React DnD Drag and Drop for React. See the docs, tutorials and examples on the website: http://react-dnd.github.io/react-dnd/ See the changelog on the

React DnD 18.7k Jan 7, 2023
:ok_hand: Drag and drop so simple it hurts

Drag and drop so simple it hurts Official React wrapper for dragula. Demo Try out the demo! Install You can get it on npm. npm install react-dragula -

Nicolás Bevacqua 976 Nov 26, 2022
Drag and Drop for React

React DnD Drag and Drop for React. See the docs, tutorials and examples on the website: http://react-dnd.github.io/react-dnd/ See the changelog on the

React DnD 18.7k Jan 6, 2023
A modern, lightweight, performant, accessible and extensible drag & drop toolkit for React.

A modern, lightweight, performant, accessible and extensible drag & drop toolkit for React.

Claudéric Demers 6.5k Jan 7, 2023
Drag and Drop for React

Drag and Drop for React

React DnD 18.7k Jan 4, 2023
Light React Drag & Drop files and images library styled by styled-components

Light React Drag & Drop files and images library styled by styled-components

null 143 Dec 28, 2022
A directive based drag and drop container for solid-js

A directive based drag and drop container for solid-js

Isaac Hagoel 52 Dec 8, 2022
React drag and drop framework with inbuilt virtualizing scrollbars.

About us This library was made by Forecast - powered by AI, Forecast is supporting your work process with a complete Resource & Project Management pla

Forecast 51 Sep 21, 2022
Drag and Drop library for React.

react-tiny-dnd Drag and Drop library for React. Demo Install via npm npm install react-tiny-dnd or yarn add react-tiny-dnd Features Vertical lists Eas

Rafael Hovhannisyan 27 Nov 27, 2022
Creating an app using Drag and Drop with React without libraries 🤏

Creating an app using Drag and Drop with React without libraries ?? ! This time, we are going to implement the functionality to do a Drag & Drop with

Franklin Martinez 5 Sep 23, 2022
Simple HTML5 drag-drop zone with React.js.

react-dropzone Simple React hook to create a HTML5-compliant drag'n'drop zone for files. Documentation and examples at https://react-dropzone.js.org.

null 9.4k Jan 2, 2023
example how to use react-dropzone for drag 'n drop uploader

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Hendra_Adri 1 Nov 5, 2021
Taskboard with drag'n drop feature. Built w/ React, TypeScript

Drag & Drop Taskboard A taskboard application with drag and drop feature. Live demo is here. Tech Stack Language: TypeScript UI-Components: Ant Design

Onur Önder 37 Dec 16, 2022
"Drag to resize" (sizing) as React Component.

react-drag-sizing "Drag to resize" (sizing) as React Component Rewritten with TS & React-hooks Polyfill workaround with React < 16.8 Support both mous

Fritz Lin 13 Nov 7, 2022