Skip to content

Commit 6484e76

Browse files
committed
Fix file rejection behavior and add example of custom dropzoneProps
1 parent eb05e8e commit 6484e76

File tree

4 files changed

+69
-6
lines changed

4 files changed

+69
-6
lines changed

packages/react-core/src/components/FileUpload/FileUpload.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ export const FileUpload: React.FunctionComponent<FileUploadProps> = ({
6767
};
6868

6969
const onDropRejected = (rejectedFiles: File[], event: React.DragEvent<HTMLElement>) => {
70-
onChange('', '', event);
70+
if (rejectedFiles.length > 0) {
71+
onChange('', rejectedFiles[0].name, event);
72+
}
7173
dropzoneProps.onDropRejected && dropzoneProps.onDropRejected(rejectedFiles, event);
7274
};
7375

packages/react-core/src/components/FileUpload/FileUploadField.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export interface FileUploadFieldProps extends Omit<React.HTMLProps<HTMLFormEleme
4545
browseButtonText?: string;
4646
/** Text for the Clear button */
4747
clearButtonText?: string;
48+
/** Flag to disable the Clear button */
49+
clearButtonDisabled?: boolean;
4850
/** Flag to hide the TextArea. Use with children to add custom support for non-text files. */
4951
hideTextArea?: boolean;
5052
/** Additional children to render after (or instead of) the TextArea. */
@@ -74,6 +76,7 @@ export const FileUploadField: React.FunctionComponent<FileUploadFieldProps> = ({
7476
filenameAriaLabel = filename ? 'Read only filename' : filenamePlaceholder,
7577
browseButtonText = 'Browse...',
7678
clearButtonText = 'Clear',
79+
clearButtonDisabled = !filename && !value,
7780
containerRef = null as React.Ref<any>,
7881
children = null,
7982
hideTextArea = false,
@@ -105,10 +108,19 @@ export const FileUploadField: React.FunctionComponent<FileUploadFieldProps> = ({
105108
aria-describedby={`${id}-browse-button`}
106109
value={filename}
107110
/>
108-
<Button id={`${id}-browse-button`} variant={ButtonVariant.control} onClick={onBrowseButtonClick}>
111+
<Button
112+
id={`${id}-browse-button`}
113+
variant={ButtonVariant.control}
114+
onClick={onBrowseButtonClick}
115+
isDisabled={isDisabled}
116+
>
109117
{browseButtonText}
110118
</Button>
111-
<Button variant={ButtonVariant.control} isDisabled={!value} onClick={onClearButtonClick}>
119+
<Button
120+
variant={ButtonVariant.control}
121+
isDisabled={isDisabled || clearButtonDisabled}
122+
onClick={onClearButtonClick}
123+
>
112124
{clearButtonText}
113125
</Button>
114126
</InputGroup>

packages/react-core/src/components/FileUpload/examples/FileUpload.md

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ section: 'components'
77
beta: true
88
---
99

10-
import { FileUpload } from '@patternfly/react-core';
10+
import { FileUpload, Form, FormGroup } from '@patternfly/react-core';
1111

1212
## Examples
1313

14-
The basic `FileUpload` component can handle simple text files, loading them into memory and passing their contents as a string to an `onChange` prop. It uses the `react-dropzone` library to provide the file browse dialog and drag/drop behavior. Any props accepted by `react-dropzone` can be passed as a `dropzoneProps` object in order to customize the behavior of the Dropzone.
14+
The basic `FileUpload` component can handle simple text files via browse or drag-and-drop, loading them into memory and passing their contents as a string to an `onChange` prop.
1515

1616
```js title=Simple-text-file isBeta
1717
import React from 'react';
@@ -33,7 +33,55 @@ class SimpleTextFileUpload extends React.Component {
3333
}
3434
```
3535

36-
`FileUpload` is a thin wrapper around the `FileUploadField` presentational component. If you need to implement your own logic for reading or displaying a file, you can instead render a `FileUploadField` directly, which requires additional props (you must implement your own `onBrowseButtonClick` handler, etc).
36+
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. This example will only accept CSV files smaller than 1 KB.
37+
38+
```js title=Simple-text-file-with-restrictions isBeta
39+
import React from 'react';
40+
import { FileUpload, Form, FormGroup } from '@patternfly/react-core';
41+
42+
class SimpleTextFileUploadWithRestrictions extends React.Component {
43+
constructor(props) {
44+
super(props);
45+
this.state = { value: '', filename: '', rejected: false };
46+
this.handleFileChange = (value, filename, event) => {
47+
this.setState({ value, filename, rejected: false });
48+
};
49+
this.handleFileRejected = (rejectedFiles, event) => {
50+
this.setState({ rejected: true });
51+
};
52+
}
53+
54+
render() {
55+
const { value, filename, rejected } = this.state;
56+
return (
57+
<Form>
58+
<FormGroup
59+
fieldId="simple-text-file-with-restrictions"
60+
helperText="Upload a CSV file"
61+
helperTextInvalid="Must be a CSV file no larger than 1 KB"
62+
validated={rejected ? 'error' : 'default'}
63+
>
64+
<FileUpload
65+
id="simple-text-file-with-restrictions"
66+
value={value}
67+
filename={filename}
68+
onChange={this.handleFileChange}
69+
dropzoneProps={{
70+
accept: '.csv',
71+
maxSize: 1024,
72+
onDropAccepted: this.handleFileAccepted,
73+
onDropRejected: this.handleFileRejected
74+
}}
75+
validated={rejected ? 'error' : 'default'}
76+
/>
77+
</FormGroup>
78+
</Form>
79+
);
80+
}
81+
}
82+
```
83+
84+
`FileUpload` is a thin wrapper around the `FileUploadField` presentational component. If you need to implement your own logic for accepting, reading or displaying files, you can instead render a `FileUploadField` directly, which requires additional props (e.g. `onBrowseButtonClick`, `isDragActive`).
3785

3886
```js title=Custom-file-upload isBeta
3987
import React from 'react';

packages/react-core/src/helpers/fileUtils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*
55
* @param {File} fileHandle - File object to read
66
*/
7+
// TODO handle the loading spinner case?
78
export function readTextFile(fileHandle: File) {
89
return new Promise((resolve, reject) => {
910
if (fileHandle) {

0 commit comments

Comments
 (0)