The simple files uploader applied Render Props
pattern. (You can read more about this pattern here).
This approach allows you to fully control UI component and behaviours.
This is a modified version of react-images-uploading for files uploading.
npm
npm install --save react-files-uploading
yarn
yarn add react-files-uploading
Basic
import * as React from 'react';
import FileUploading from 'react-files-uploading';
export const App = () => {
const [files, setFiles] = React.useState<File[]>([]);
const onChange = (fileList: File[]) => {
setFiles(fileList);
};
return (
<div className="App">
<FileUploading multiple value={files} maxNumber={10} onChange={onChange}>
{({
fileList,
errors,
isDragging,
onFileUpload,
onFileRemoveAll,
onFileUpdate,
onFileRemove,
dragProps,
}) => {
return (
<div className="upload__file-wrapper">
{errors && errors.maxNumber && (
<span>Number of selected files exceed maxNumber</span>
)}
<button
id="btn-upload"
type="button"
style={isDragging ? { color: 'red' } : undefined}
onClick={onFileUpload}
{...dragProps}
>
Click or Drop here
</button>
<button id="btn-remove" type="button" onClick={onFileRemoveAll}>
Remove all files
</button>
<div id="list-files">
{fileList.map((file, index) => (
<div key={`file-${index}`} className="file-item">
<p>{file.name}</p>
<div className="file-item__btn-wrapper">
<button
id={`update_${index}`}
type="button"
onClick={() => onFileUpdate(index)}
>
{`Update ${index}`}
</button>
<button
id={`remove_${index}`}
type="button"
onClick={() => onFileRemove(index)}
>
{`Remove ${index}`}
</button>
</div>
</div>
))}
</div>
</div>
);
}}
</FileUploading>
</div>
);
};
Validation
...
{({ fileList, onFileUpload, onFileRemoveAll, errors }) => (
errors && <div>
{errors.maxNumber && <span>Number of selected files exceed maxNumber</span>}
{errors.acceptType && <span>Your selected file type is not allow</span>}
{errors.maxFileSize && <span>Selected file size exceed maxFileSize</span>}
</div>
)}
...
Drag and Drop
...
{({ fileList, dragProps, isDragging }) => (
<div {...dragProps}>
{isDragging ? "Drop here please" : "Upload space"}
{fileList.map((file, index) => (
<p>{file.name}</p>
))}
</div>
)}
...
parameter | type | options | default | description |
---|---|---|---|---|
value | array | [] | List of files | |
onChange | function | (fileList, addUpdateIndex) => void | Called when add, update or delete action is called | |
multiple | boolean | false | Set true for multiple chooses |
|
maxNumber | number | 1000 | Number of files user can select if mode = multiple |
|
onError | function | (errors, files) => void | Called when it has errors | |
acceptType | array | ['mp4', 'webm', 'png', 'pdf] | [] | The file extension(s) to upload |
maxFileSize | number | Max file size (Byte) and it is used in validation | ||
inputProps | React.HTMLProps<HTMLInputElement> |
parameter | type | description |
---|---|---|
fileList | array | List of files to render. |
onFileUpload | function | Called when an element is clicks and triggers to open a file dialog |
onFileRemoveAll | function | Called when removing all files |
onFileUpdate | (updateIndex: number) => void | Called when updating a file at updateIndex . |
onFileRemove | (deleteIndex: number | number[]) => void | Called when removing one or list of files. |
errors | object | Exported object of validation |
dragProps | object | Native element props for drag and drop feature |
isDragging | boolean | "true" if a file is being dragged |
Thanks goes to these wonderful people (emoji key):
vutoan266 💻 🤔 📖 🚧 |
David Nguyen 💻 🤔 📖 👀 |
DK 💻 🚇 🤔 👀 📖 |
Isaac Maseruka 💻 |
Vu Nguyen 💻 |
This project follows the all-contributors specification. Contributions of any kind welcome!