File upload component that allow users to upload their own content. They are commonly used within forms but may also exist on their own.
@react-magma/dropzone
which must be installed as a peer dependency.Basic Usage
import React from 'react';import { Dropzone } from '@react-magma/dropzone';export function Example() {return (<Dropzonethumbnails={false}accept={['.png', '.jpg', '.svg']}maxFiles={5}maxSize={1024 * 1024}labelText="Upload files (Drag and Drop)"helperMessage="Only PNG, JPG, and SVG files with a max size of 1MB"/>);}
No Dragging
import React from 'react';import { Dropzone } from '@react-magma/dropzone';export function Example() {return (<Dropzonethumbnails={false}noDraglabelText="Upload files (Button only)"helperMessage="No limits on file types, size, or quantity."/>);}
Inverse
import React from 'react';import { Dropzone } from '@react-magma/dropzone';import { Card, CardBody } from 'react-magma-dom';export function Example() {return (<Card isInverse><CardBody><DropzoneisInversethumbnails={false}accept={['.png', '.jpg', '.svg']}maxFiles={5}maxSize={1024 * 1024}labelText="Upload files (Drag and Drop)"helperMessage="Only PNG, JPG, and SVG files with a max size of 1MB"/></CardBody></Card>);}
Handle File Processing
The File Uploader uses onSendFile
to process each file.
Each instance of onSendFile
will be passed a file
prop and onProgress
, onSuccess
and onError
callbacks.
The file
prop can be manipulated with the FileReader API.
The files added to the dropzone will be sent processed when by the onSendFile
function passed
when the sendFiles
is set to true. If the files should be immediately passed then sendFiles
can be
initally set to true. If the files should be queued until some action then it can be initally false and
then switched to true when needed.
import React from 'react';import { Dropzone } from '@react-magma/dropzone';import { Button, Spacer } from 'react-magma-dom';export function Example() {const [sendFiles, setSendFiles] = React.useState<boolean>(false);const onSendFile = (props: OnSendFileProps) => {const { onProgress, onError, onFinish, file } = props;let percent = 1;const interval = setInterval(() => {percent++;onProgress && onProgress({ percent, file });if (percent >= 100) {clearInterval(interval);onFinish && onFinish({ file });}if (Math.random() * 100 > 99.99) {clearInterval(interval);onError &&onError({errors: [{code: 'upload-err',message: 'The destination server has returned an error.',},],file,});}}, 100 * Math.random());};return (<div><Dropzonedisabled={sendFiles}helperMessage="Any files allowed, click to upload"labelText="Upload files (example processing)"onSendFile={onSendFile}sendFiles={sendFiles}/><Spacer size={12} /><Button disabled={sendFiles} onClick={() => setSendFiles(true)}>Upload files</Button></div>);}
Deleting Files
The File Uploader has two methods for undoing adding a file. onRemoveFile
will run before the file is processed with onSendFile
and the cross icon is clicked.
Since the files have been processed and require more cleanup onDeleteFile
is ran after the file is processed and the trashcan icon is clicked.
Processing Examples
Here are some examples of the dropzone. Omitted from the following is uploading the file to some service. It's conceivable that a file is uploaded to something like s3 and then the loacation to the file is submitted with the form.
Since the dropzone uses the FileReader API the possibilities of what can be done with a file are endless.
Image File Example
import React from 'react';import { Dropzone } from '@react-magma/dropzone';export function Example() {const [file, setFile] = React.useState<string>();const onSendFile = (props: OnSendFileProps) => {const { file, onFinish } = props;const reader = new FileReader();reader.onload = function (evt) {setFile((evt &&evt.target &&evt.target.result &&evt.target.result.toString()) ||'');onFinish && onFinish({ file });};reader.readAsDataURL(file);};return (<div><DropzoneonSendFile={onSendFile}accept={['image/*']}labelText="Upload files (Image Preview)"helperMessage="Only PNG files"sendFiles/>{file && <img alt="" src={file} />}</div>);}
Text File Example
import React from 'react';import { Dropzone } from '@react-magma/dropzone';import { Textarea } from 'react-magma-dom';export function Example() {const [file, setFile] = React.useState<string>();const onSendFile = (props: OnSendFileProps) => {const { file, onFinish } = props;const reader = new FileReader();reader.onload = function (evt) {setFile((evt &&evt.target &&evt.target.result &&evt.target.result.toString()) ||'');onFinish && onFinish({ file });};reader.readAsText(file);};return (<div><DropzoneonSendFile={onSendFile}accept={['.txt', '.csv']}helperMessage="Only TXT or CSV files"labelText="Upload files (Text)"sendFiles/>{file && <Textarea textareaStyle={{ height: '250px' }} value={file} />}</div>);}
CSV Example
import React from 'react';import { Dropzone } from '@react-magma/dropzone';import { Datagrid } from 'react-magma-dom';export function Example() {const [file, setFile] = React.useState<any>();const [columns, setColumns] = React.useState<any>();const csvToJson = csv => {const lines = csv.split('\n');const result = [];const headers = lines[0].split(',');for (let i = 1; i < lines.length; i++) {const obj = {};const currentline = lines[i].split(',');for (let j = 0; j < headers.length; j++) {obj[headers[j]] = currentline[j];}result.push({ id: i, ...obj });}return [headers.map((header: string) => {return { field: header, header };}),result,]; //JavaScript object};const onSendFile = (props: OnSendFileProps) => {const { file, onFinish } = props;const reader = new FileReader();reader.onload = function (evt) {const [columns, rows] =(evt &&evt.target &&evt.target.result &&csvToJson(evt.target.result.toString())) ||[];setColumns(columns);setFile(rows);onFinish && onFinish({ file });};reader.readAsText(file);};return (<div><Dropzoneaccept={['.csv']}helperMessage="Only CSV files"labelText="Upload files (CSV to Datagrid)"multiple={false}onSendFile={onSendFile}sendFiles/>{file && <Datagrid columns={columns} rows={file} />}</div>);}
Dropzone Props
Any other props supplied will be provided to the wrapping div
element.
accept
Description
Set accepted file types. See https://github.com/okonet/attr-accept for more information. Keep in mind that mime type determination is not reliable across 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. See: https://github.com/react-dropzone/react-dropzone/issues/276
Type
string | string[]
Default
-
disabled
Description
Enable/Disable the input
Type
boolean
Default
false
dropzoneOptions
Description
Additional props to pass to the dropzone, see https://react-dropzone.js.org/#src
Type
DropzoneOptions
Default
-
helperMessage
Description
Content of the helper message.
Type
string
Default
-
maxFiles
Description
Maximum accepted number of files The default value is 0 which means there is no limitation to how many files are accepted.
Type
number
Default
0
minFiles
Description
Minimum accepted number of files.
Type
number
Default
-
maxSize
Description
Maximum file size (in bytes)
Type
number
Default
Infinity
minSize
Description
Minimum file size (in bytes)
Type
number
Default
0
multiple
Description
Allow drag and drop (or selection from the file dialog) of multiple files.
Type
boolean
Default
true
noDrag
Description
If true, disables drag n drop
Type
boolean
Default
false
onDeleteFile
Description
Callback for when a file is deleted
Type
function
Default
-
onRemoveFile
Description
Callback for when a file is deleted
Type
function
Default
-
onSendFile
Description
Callback for when a file is added to the preview list via dropping or selecting. Will be ran on new files when `sendFiles` is true.
Type
function
Default
-
sendFiles
Description
Run `onSendFile` on any new files. Delay processing by setting to `false` until processing is desired.
Type
boolean
Default
false
thumbnails
Description
Show thumbnails for images in lieu of the file icon.
Type
boolean
Default
true
On this page