Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/react-core/src/components/FileUpload/FileUpload.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { DropzoneInputProps, DropzoneOptions, FileRejection, useDropzone } from 'react-dropzone';
import { DropzoneInputProps, DropzoneOptions, FileRejection, useDropzone, ErrorCode } from 'react-dropzone';
import { FileUploadField, FileUploadFieldProps } from './FileUploadField';
import { readFile, fileReaderType } from '../../helpers/fileUtils';
import { DropEvent } from '../../helpers/typeUtils';
Expand Down Expand Up @@ -84,6 +84,8 @@ export interface FileUploadProps
onTextChange?: (event: React.ChangeEvent<HTMLTextAreaElement>, text: string) => void;
}

export { ErrorCode as DropzoneErrorCode }; // FileInvalidType, FileTooLarge, FileTooSmall, TooManyFiles

export const FileUpload: React.FunctionComponent<FileUploadProps> = ({
id,
type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Typing/pasting text in the box will call `onTextChange` with a string, and a str

### Restricting file size and type

Any [props accepted by `react-dropzone`'s `Dropzone` component](https://react-dropzone.js.org/#!/Dropzone) can be passed as a `dropzoneProps` object in order to customize the behavior of the Dropzone, such as restricting the size and type of files allowed. The following example will only accept CSV files smaller than 1 KB. Note that file type determination is not reliable across platforms (see the note on react-dropzone's docs about the `accept` prop), so be sure to test the behavior of your file upload restriction on all browsers and operating systems targeted by your application.
Any [props accepted by `react-dropzone`'s `Dropzone` component](https://react-dropzone.js.org/#!/Dropzone) can be passed as a `dropzoneProps` object in order to customize the behavior of the Dropzone, such as restricting the size and type of files allowed. You can also capture and act upon native `react-dropzone` errors using the exposed `DropzoneErrorCode` enum. The following example will only accept CSV files smaller than 1 KB. Note that file type determination is not reliable across platforms (see the note on react-dropzone's docs about the `accept` prop), so be sure to test the behavior of your file upload restriction on all browsers and operating systems targeted by your application.

#### IMPORTANT: A note about security

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import {
FileUpload,
DropzoneErrorCode,
FileUploadHelperText,
Form,
FormGroup,
Expand All @@ -9,13 +10,13 @@ import {
DropEvent,
Icon
} from '@patternfly/react-core';
import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon';

export const TextFileUploadWithRestrictions: React.FunctionComponent = () => {
const [value, setValue] = React.useState('');
const [filename, setFilename] = React.useState('');
const [isLoading, setIsLoading] = React.useState(false);
const [isRejected, setIsRejected] = React.useState(false);
const [message, setMessage] = React.useState('Must be a CSV file no larger than 1 KB');

const handleFileInputChange = (_, file: File) => {
setFilename(file.name);
Expand All @@ -29,16 +30,25 @@ export const TextFileUploadWithRestrictions: React.FunctionComponent = () => {
setValue(value);
};

const handleClear = (_event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
const reset = () => {
setFilename('');
setValue('');
};

const handleClear = (_event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
reset();
setIsRejected(false);
};

const handleFileRejected = () => {
reset();
setIsRejected(true);
};

const handleFileAccepted = () => {
setIsRejected(false);
};

const handleFileReadStarted = (_event: DropEvent, _fileHandle: File) => {
setIsLoading(true);
};
Expand Down Expand Up @@ -66,7 +76,16 @@ export const TextFileUploadWithRestrictions: React.FunctionComponent = () => {
dropzoneProps={{
accept: { 'text/csv': ['.csv'] },
maxSize: 1024,
onDropRejected: handleFileRejected
onDropRejected: (rejections) => {
const error = rejections[0].errors[0];
if (error.code === DropzoneErrorCode.FileTooLarge) {
setMessage('File is too big');
} else if (error.code === DropzoneErrorCode.FileInvalidType) {
setMessage('File is not a CSV file');
}
handleFileRejected();
},
onDropAccepted: handleFileAccepted
}}
validated={isRejected ? 'error' : 'default'}
browseButtonText="Upload"
Expand All @@ -77,10 +96,8 @@ export const TextFileUploadWithRestrictions: React.FunctionComponent = () => {
<HelperTextItem id="restricted-file-example-helpText" variant={isRejected ? 'error' : 'default'}>
{isRejected ? (
<>
<Icon status="danger">
<ExclamationCircleIcon />
</Icon>
Must be a CSV file no larger than 1 KB
<Icon status="danger" />
{message}
</>
) : (
'Upload a CSV file'
Expand Down
Loading