@patternfly/react-core 4.221.15 → 4.221.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/umd/react-core.min.css +69 -69
- package/package.json +5 -5
- package/src/components/FileUpload/examples/FileUpload.md +6 -270
- package/src/components/FileUpload/examples/FileUploadCustomPreview.tsx +40 -0
- package/src/components/FileUpload/examples/FileUploadCustomUpload.tsx +116 -0
- package/src/components/FileUpload/examples/FileUploadSimpleFile.tsx +31 -0
- package/src/components/FileUpload/examples/FileUploadSimpleText.tsx +51 -0
- package/src/components/FileUpload/examples/FileUploadTextWithEdits.tsx +51 -0
- package/src/components/FileUpload/examples/FileUploadTextWithRestrictions.tsx +71 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## 4.221.16 (2022-06-13)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @patternfly/react-core
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
## 4.221.15 (2022-06-13)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @patternfly/react-core
|
|
@@ -23396,6 +23396,75 @@ svg.pf-c-spinner.pf-m-xl {
|
|
|
23396
23396
|
direction: ltr;
|
|
23397
23397
|
}
|
|
23398
23398
|
}
|
|
23399
|
+
.pf-l-gallery {
|
|
23400
|
+
--pf-l-gallery--m-gutter--GridGap: var(--pf-global--gutter);
|
|
23401
|
+
--pf-l-gallery--GridTemplateColumns--min: 250px;
|
|
23402
|
+
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min);
|
|
23403
|
+
--pf-l-gallery--GridTemplateColumns--max: 1fr;
|
|
23404
|
+
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max);
|
|
23405
|
+
--pf-l-gallery--GridTemplateColumns: repeat(auto-fill, minmax(var(--pf-l-gallery--GridTemplateColumns--minmax--min), var(--pf-l-gallery--GridTemplateColumns--minmax--max)));
|
|
23406
|
+
--pf-l-gallery--GridTemplateRows: auto;
|
|
23407
|
+
display: grid;
|
|
23408
|
+
grid-template-columns: var(--pf-l-gallery--GridTemplateColumns);
|
|
23409
|
+
grid-template-rows: var(--pf-l-gallery--GridTemplateRows);
|
|
23410
|
+
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min);
|
|
23411
|
+
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max);
|
|
23412
|
+
}
|
|
23413
|
+
|
|
23414
|
+
.pf-l-gallery.pf-m-gutter {
|
|
23415
|
+
grid-gap: var(--pf-l-gallery--m-gutter--GridGap);
|
|
23416
|
+
}
|
|
23417
|
+
|
|
23418
|
+
@media (min-width: 576px) {
|
|
23419
|
+
.pf-l-gallery {
|
|
23420
|
+
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min-on-sm, var(--pf-l-gallery--GridTemplateColumns--min));
|
|
23421
|
+
}
|
|
23422
|
+
}
|
|
23423
|
+
@media (min-width: 768px) {
|
|
23424
|
+
.pf-l-gallery {
|
|
23425
|
+
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min-on-md, var(--pf-l-gallery--GridTemplateColumns--min-on-sm, var(--pf-l-gallery--GridTemplateColumns--min)));
|
|
23426
|
+
}
|
|
23427
|
+
}
|
|
23428
|
+
@media (min-width: 992px) {
|
|
23429
|
+
.pf-l-gallery {
|
|
23430
|
+
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min-on-lg, var(--pf-l-gallery--GridTemplateColumns--min-on-md, var(--pf-l-gallery--GridTemplateColumns--min-on-sm, var(--pf-l-gallery--GridTemplateColumns--min))));
|
|
23431
|
+
}
|
|
23432
|
+
}
|
|
23433
|
+
@media (min-width: 1200px) {
|
|
23434
|
+
.pf-l-gallery {
|
|
23435
|
+
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min-on-xl, var(--pf-l-gallery--GridTemplateColumns--min-on-lg, var(--pf-l-gallery--GridTemplateColumns--min-on-md, var(--pf-l-gallery--GridTemplateColumns--min-on-sm, var(--pf-l-gallery--GridTemplateColumns--min)))));
|
|
23436
|
+
}
|
|
23437
|
+
}
|
|
23438
|
+
@media (min-width: 1450px) {
|
|
23439
|
+
.pf-l-gallery {
|
|
23440
|
+
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min-on-2xl, var(--pf-l-gallery--GridTemplateColumns--min-on-xl, var(--pf-l-gallery--GridTemplateColumns--min-on-lg, var(--pf-l-gallery--GridTemplateColumns--min-on-md, var(--pf-l-gallery--GridTemplateColumns--min-on-sm, var(--pf-l-gallery--GridTemplateColumns--min))))));
|
|
23441
|
+
}
|
|
23442
|
+
}
|
|
23443
|
+
@media (min-width: 576px) {
|
|
23444
|
+
.pf-l-gallery {
|
|
23445
|
+
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max-on-sm, var(--pf-l-gallery--GridTemplateColumns--max));
|
|
23446
|
+
}
|
|
23447
|
+
}
|
|
23448
|
+
@media (min-width: 768px) {
|
|
23449
|
+
.pf-l-gallery {
|
|
23450
|
+
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max-on-md, var(--pf-l-gallery--GridTemplateColumns--max-on-sm, var(--pf-l-gallery--GridTemplateColumns--max)));
|
|
23451
|
+
}
|
|
23452
|
+
}
|
|
23453
|
+
@media (min-width: 992px) {
|
|
23454
|
+
.pf-l-gallery {
|
|
23455
|
+
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max-on-lg, var(--pf-l-gallery--GridTemplateColumns--max-on-md, var(--pf-l-gallery--GridTemplateColumns--max-on-sm, var(--pf-l-gallery--GridTemplateColumns--max))));
|
|
23456
|
+
}
|
|
23457
|
+
}
|
|
23458
|
+
@media (min-width: 1200px) {
|
|
23459
|
+
.pf-l-gallery {
|
|
23460
|
+
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max-on-xl, var(--pf-l-gallery--GridTemplateColumns--max-on-lg, var(--pf-l-gallery--GridTemplateColumns--max-on-md, var(--pf-l-gallery--GridTemplateColumns--max-on-sm, var(--pf-l-gallery--GridTemplateColumns--max)))));
|
|
23461
|
+
}
|
|
23462
|
+
}
|
|
23463
|
+
@media (min-width: 1450px) {
|
|
23464
|
+
.pf-l-gallery {
|
|
23465
|
+
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max-on-2xl, var(--pf-l-gallery--GridTemplateColumns--max-on-xl, var(--pf-l-gallery--GridTemplateColumns--max-on-lg, var(--pf-l-gallery--GridTemplateColumns--max-on-md, var(--pf-l-gallery--GridTemplateColumns--max-on-sm, var(--pf-l-gallery--GridTemplateColumns--max))))));
|
|
23466
|
+
}
|
|
23467
|
+
}
|
|
23399
23468
|
.pf-l-flex {
|
|
23400
23469
|
--pf-l-flex--Display: flex;
|
|
23401
23470
|
--pf-l-flex--FlexWrap: wrap;
|
|
@@ -25472,75 +25541,6 @@ svg.pf-c-spinner.pf-m-xl {
|
|
|
25472
25541
|
--pf-l-flex--spacer: var(--pf-l-flex--spacer--4xl);
|
|
25473
25542
|
}
|
|
25474
25543
|
}
|
|
25475
|
-
.pf-l-gallery {
|
|
25476
|
-
--pf-l-gallery--m-gutter--GridGap: var(--pf-global--gutter);
|
|
25477
|
-
--pf-l-gallery--GridTemplateColumns--min: 250px;
|
|
25478
|
-
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min);
|
|
25479
|
-
--pf-l-gallery--GridTemplateColumns--max: 1fr;
|
|
25480
|
-
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max);
|
|
25481
|
-
--pf-l-gallery--GridTemplateColumns: repeat(auto-fill, minmax(var(--pf-l-gallery--GridTemplateColumns--minmax--min), var(--pf-l-gallery--GridTemplateColumns--minmax--max)));
|
|
25482
|
-
--pf-l-gallery--GridTemplateRows: auto;
|
|
25483
|
-
display: grid;
|
|
25484
|
-
grid-template-columns: var(--pf-l-gallery--GridTemplateColumns);
|
|
25485
|
-
grid-template-rows: var(--pf-l-gallery--GridTemplateRows);
|
|
25486
|
-
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min);
|
|
25487
|
-
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max);
|
|
25488
|
-
}
|
|
25489
|
-
|
|
25490
|
-
.pf-l-gallery.pf-m-gutter {
|
|
25491
|
-
grid-gap: var(--pf-l-gallery--m-gutter--GridGap);
|
|
25492
|
-
}
|
|
25493
|
-
|
|
25494
|
-
@media (min-width: 576px) {
|
|
25495
|
-
.pf-l-gallery {
|
|
25496
|
-
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min-on-sm, var(--pf-l-gallery--GridTemplateColumns--min));
|
|
25497
|
-
}
|
|
25498
|
-
}
|
|
25499
|
-
@media (min-width: 768px) {
|
|
25500
|
-
.pf-l-gallery {
|
|
25501
|
-
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min-on-md, var(--pf-l-gallery--GridTemplateColumns--min-on-sm, var(--pf-l-gallery--GridTemplateColumns--min)));
|
|
25502
|
-
}
|
|
25503
|
-
}
|
|
25504
|
-
@media (min-width: 992px) {
|
|
25505
|
-
.pf-l-gallery {
|
|
25506
|
-
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min-on-lg, var(--pf-l-gallery--GridTemplateColumns--min-on-md, var(--pf-l-gallery--GridTemplateColumns--min-on-sm, var(--pf-l-gallery--GridTemplateColumns--min))));
|
|
25507
|
-
}
|
|
25508
|
-
}
|
|
25509
|
-
@media (min-width: 1200px) {
|
|
25510
|
-
.pf-l-gallery {
|
|
25511
|
-
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min-on-xl, var(--pf-l-gallery--GridTemplateColumns--min-on-lg, var(--pf-l-gallery--GridTemplateColumns--min-on-md, var(--pf-l-gallery--GridTemplateColumns--min-on-sm, var(--pf-l-gallery--GridTemplateColumns--min)))));
|
|
25512
|
-
}
|
|
25513
|
-
}
|
|
25514
|
-
@media (min-width: 1450px) {
|
|
25515
|
-
.pf-l-gallery {
|
|
25516
|
-
--pf-l-gallery--GridTemplateColumns--minmax--min: var(--pf-l-gallery--GridTemplateColumns--min-on-2xl, var(--pf-l-gallery--GridTemplateColumns--min-on-xl, var(--pf-l-gallery--GridTemplateColumns--min-on-lg, var(--pf-l-gallery--GridTemplateColumns--min-on-md, var(--pf-l-gallery--GridTemplateColumns--min-on-sm, var(--pf-l-gallery--GridTemplateColumns--min))))));
|
|
25517
|
-
}
|
|
25518
|
-
}
|
|
25519
|
-
@media (min-width: 576px) {
|
|
25520
|
-
.pf-l-gallery {
|
|
25521
|
-
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max-on-sm, var(--pf-l-gallery--GridTemplateColumns--max));
|
|
25522
|
-
}
|
|
25523
|
-
}
|
|
25524
|
-
@media (min-width: 768px) {
|
|
25525
|
-
.pf-l-gallery {
|
|
25526
|
-
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max-on-md, var(--pf-l-gallery--GridTemplateColumns--max-on-sm, var(--pf-l-gallery--GridTemplateColumns--max)));
|
|
25527
|
-
}
|
|
25528
|
-
}
|
|
25529
|
-
@media (min-width: 992px) {
|
|
25530
|
-
.pf-l-gallery {
|
|
25531
|
-
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max-on-lg, var(--pf-l-gallery--GridTemplateColumns--max-on-md, var(--pf-l-gallery--GridTemplateColumns--max-on-sm, var(--pf-l-gallery--GridTemplateColumns--max))));
|
|
25532
|
-
}
|
|
25533
|
-
}
|
|
25534
|
-
@media (min-width: 1200px) {
|
|
25535
|
-
.pf-l-gallery {
|
|
25536
|
-
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max-on-xl, var(--pf-l-gallery--GridTemplateColumns--max-on-lg, var(--pf-l-gallery--GridTemplateColumns--max-on-md, var(--pf-l-gallery--GridTemplateColumns--max-on-sm, var(--pf-l-gallery--GridTemplateColumns--max)))));
|
|
25537
|
-
}
|
|
25538
|
-
}
|
|
25539
|
-
@media (min-width: 1450px) {
|
|
25540
|
-
.pf-l-gallery {
|
|
25541
|
-
--pf-l-gallery--GridTemplateColumns--minmax--max: var(--pf-l-gallery--GridTemplateColumns--max-on-2xl, var(--pf-l-gallery--GridTemplateColumns--max-on-xl, var(--pf-l-gallery--GridTemplateColumns--max-on-lg, var(--pf-l-gallery--GridTemplateColumns--max-on-md, var(--pf-l-gallery--GridTemplateColumns--max-on-sm, var(--pf-l-gallery--GridTemplateColumns--max))))));
|
|
25542
|
-
}
|
|
25543
|
-
}
|
|
25544
25544
|
.pf-l-grid {
|
|
25545
25545
|
--pf-l-grid--m-gutter--GridGap: var(--pf-global--gutter);
|
|
25546
25546
|
--pf-l-grid__item--GridColumnStart: auto;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "4.221.
|
|
3
|
+
"version": "4.221.16",
|
|
4
4
|
"description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
|
|
5
5
|
"main": "dist/js/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"generate": "node scripts/copyStyles.js"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@patternfly/react-icons": "^4.72.
|
|
38
|
-
"@patternfly/react-styles": "^4.71.
|
|
39
|
-
"@patternfly/react-tokens": "^4.73.
|
|
37
|
+
"@patternfly/react-icons": "^4.72.16",
|
|
38
|
+
"@patternfly/react-styles": "^4.71.16",
|
|
39
|
+
"@patternfly/react-tokens": "^4.73.16",
|
|
40
40
|
"focus-trap": "6.9.2",
|
|
41
41
|
"react-dropzone": "9.0.0",
|
|
42
42
|
"tippy.js": "5.1.2",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"react": "^16.8.0 || ^17.0.0",
|
|
61
61
|
"react-dom": "^16.8.0 || ^17.0.0"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "5d2d632484b0028c60bd5f13e970a27216727bd1"
|
|
64
64
|
}
|
|
@@ -18,42 +18,7 @@ Pressing _Clear_ button triggers `onClearClick` event.
|
|
|
18
18
|
|
|
19
19
|
### Simple text file
|
|
20
20
|
|
|
21
|
-
```
|
|
22
|
-
import React from 'react';
|
|
23
|
-
import { FileUpload } from '@patternfly/react-core';
|
|
24
|
-
|
|
25
|
-
class SimpleTextFileUpload extends React.Component {
|
|
26
|
-
constructor(props) {
|
|
27
|
-
super(props);
|
|
28
|
-
this.state = { value: '', filename: '', isLoading: false };
|
|
29
|
-
this.handleFileInputChange = (event, file) => this.setState({ filename: file.name });
|
|
30
|
-
this.handleTextOrDataChange = value => this.setState({ value });
|
|
31
|
-
this.handleClear = event => this.setState({ filename: '', value: '' });
|
|
32
|
-
this.handleFileReadStarted = fileHandle => this.setState({ isLoading: true });
|
|
33
|
-
this.handleFileReadFinished = fileHandle => this.setState({ isLoading: false });
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
render() {
|
|
37
|
-
const { value, filename, isLoading } = this.state;
|
|
38
|
-
return (
|
|
39
|
-
<FileUpload
|
|
40
|
-
id="simple-text-file"
|
|
41
|
-
type="text"
|
|
42
|
-
value={value}
|
|
43
|
-
filename={filename}
|
|
44
|
-
filenamePlaceholder="Drag and drop a file or upload one"
|
|
45
|
-
onFileInputChange={this.handleFileInputChange}
|
|
46
|
-
onDataChange={this.handleTextOrDataChange}
|
|
47
|
-
onTextChange={this.handleTextOrDataChange}
|
|
48
|
-
onReadStarted={this.handleFileReadStarted}
|
|
49
|
-
onReadFinished={this.handleFileReadFinished}
|
|
50
|
-
onClearClick={this.handleClear}
|
|
51
|
-
isLoading={isLoading}
|
|
52
|
-
browseButtonText="Upload"
|
|
53
|
-
/>
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
21
|
+
```ts file="./FileUploadSimpleText.tsx"
|
|
57
22
|
```
|
|
58
23
|
|
|
59
24
|
A user can always type instead of selecting a file, but by default, once a user selects a text file from their disk they are not allowed to edit it (to prevent unintended changes to a format-sensitive file). This behavior can be changed with the `allowEditingUploadedText` prop.
|
|
@@ -61,43 +26,7 @@ Typing/pasting text in the box will call `onTextChange` with a string, and a str
|
|
|
61
26
|
|
|
62
27
|
### Text file with edits allowed
|
|
63
28
|
|
|
64
|
-
```
|
|
65
|
-
import React from 'react';
|
|
66
|
-
import { FileUpload } from '@patternfly/react-core';
|
|
67
|
-
|
|
68
|
-
class TextFileWithEditsAllowed extends React.Component {
|
|
69
|
-
constructor(props) {
|
|
70
|
-
super(props);
|
|
71
|
-
this.state = { value: '', filename: '', isLoading: false };
|
|
72
|
-
this.handleFileInputChange = (event, file) => this.setState({ filename: file.name });
|
|
73
|
-
this.handleTextOrDataChange = value => this.setState({ value });
|
|
74
|
-
this.handleClear = event => this.setState({ filename: '', value: '' });
|
|
75
|
-
this.handleFileReadStarted = fileHandle => this.setState({ isLoading: true });
|
|
76
|
-
this.handleFileReadFinished = fileHandle => this.setState({ isLoading: false });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
render() {
|
|
80
|
-
const { value, filename, isLoading } = this.state;
|
|
81
|
-
return (
|
|
82
|
-
<FileUpload
|
|
83
|
-
id="text-file-with-edits-allowed"
|
|
84
|
-
type="text"
|
|
85
|
-
value={value}
|
|
86
|
-
filename={filename}
|
|
87
|
-
filenamePlaceholder="Drag and drop a file or upload one"
|
|
88
|
-
onFileInputChange={this.handleFileInputChange}
|
|
89
|
-
onDataChange={this.handleTextOrDataChange}
|
|
90
|
-
onClearClick={this.handleClear}
|
|
91
|
-
onTextChange={this.handleTextOrDataChange}
|
|
92
|
-
onReadStarted={this.handleFileReadStarted}
|
|
93
|
-
onReadFinished={this.handleFileReadFinished}
|
|
94
|
-
isLoading={isLoading}
|
|
95
|
-
allowEditingUploadedText
|
|
96
|
-
browseButtonText="Upload"
|
|
97
|
-
/>
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
29
|
+
```ts file="./FileUploadTextWithEdits.tsx"
|
|
101
30
|
```
|
|
102
31
|
|
|
103
32
|
### Restricting file size and type
|
|
@@ -110,58 +39,7 @@ Restricting file sizes and types in this way is for user convenience only, and i
|
|
|
110
39
|
|
|
111
40
|
### Text file with restrictions
|
|
112
41
|
|
|
113
|
-
```
|
|
114
|
-
import React from 'react';
|
|
115
|
-
import { FileUpload, Form, FormGroup } from '@patternfly/react-core';
|
|
116
|
-
|
|
117
|
-
class TextFileUploadWithRestrictions extends React.Component {
|
|
118
|
-
constructor(props) {
|
|
119
|
-
super(props);
|
|
120
|
-
this.state = { value: '', filename: '', isLoading: false, isRejected: false };
|
|
121
|
-
this.handleFileInputChange = (event, file) => this.setState({ filename: file.name });
|
|
122
|
-
this.handleTextOrDataChange = value => this.setState({ value });
|
|
123
|
-
this.handleClear = event => this.setState({ filename: '', value: '', isRejected: false });
|
|
124
|
-
this.handleFileRejected = (rejectedFiles, event) => this.setState({ isRejected: true });
|
|
125
|
-
this.handleFileReadStarted = fileHandle => this.setState({ isLoading: true });
|
|
126
|
-
this.handleFileReadFinished = fileHandle => this.setState({ isLoading: false });
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
render() {
|
|
130
|
-
const { value, filename, isLoading, isRejected } = this.state;
|
|
131
|
-
return (
|
|
132
|
-
<Form>
|
|
133
|
-
<FormGroup
|
|
134
|
-
fieldId="text-file-with-restrictions"
|
|
135
|
-
helperText="Upload a CSV file"
|
|
136
|
-
helperTextInvalid="Must be a CSV file no larger than 1 KB"
|
|
137
|
-
validated={isRejected ? 'error' : 'default'}
|
|
138
|
-
>
|
|
139
|
-
<FileUpload
|
|
140
|
-
id="text-file-with-restrictions"
|
|
141
|
-
type="text"
|
|
142
|
-
value={value}
|
|
143
|
-
filename={filename}
|
|
144
|
-
filenamePlaceholder="Drag and drop a file or upload one"
|
|
145
|
-
onFileInputChange={this.handleFileInputChange}
|
|
146
|
-
onDataChange={this.handleTextOrDataChange}
|
|
147
|
-
onTextChange={this.handleTextOrDataChange}
|
|
148
|
-
onClearClick={this.handleClear}
|
|
149
|
-
onReadStarted={this.handleFileReadStarted}
|
|
150
|
-
onReadFinished={this.handleFileReadFinished}
|
|
151
|
-
isLoading={isLoading}
|
|
152
|
-
dropzoneProps={{
|
|
153
|
-
accept: '.csv',
|
|
154
|
-
maxSize: 1024,
|
|
155
|
-
onDropRejected: this.handleFileRejected
|
|
156
|
-
}}
|
|
157
|
-
validated={isRejected ? 'error' : 'default'}
|
|
158
|
-
browseButtonText="Upload"
|
|
159
|
-
/>
|
|
160
|
-
</FormGroup>
|
|
161
|
-
</Form>
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
42
|
+
```ts file="./FileUploadTextWithRestrictions.tsx"
|
|
165
43
|
```
|
|
166
44
|
|
|
167
45
|
### Other file types
|
|
@@ -170,35 +48,7 @@ If no `type` prop is specified, the component will not read files directly. When
|
|
|
170
48
|
|
|
171
49
|
### Simple file of any format
|
|
172
50
|
|
|
173
|
-
```
|
|
174
|
-
import React from 'react';
|
|
175
|
-
import { FileUpload } from '@patternfly/react-core';
|
|
176
|
-
|
|
177
|
-
class SimpleFileUpload extends React.Component {
|
|
178
|
-
constructor(props) {
|
|
179
|
-
super(props);
|
|
180
|
-
this.state = { value: null, filename: '' };
|
|
181
|
-
this.handleFileInputChange = (event, file) => {
|
|
182
|
-
this.setState({ filename: file.name });
|
|
183
|
-
};
|
|
184
|
-
this.handleClear = event => this.setState({ filename: '', value: '' });
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
render() {
|
|
188
|
-
const { value, filename } = this.state;
|
|
189
|
-
return (
|
|
190
|
-
<FileUpload
|
|
191
|
-
id="simple-file"
|
|
192
|
-
value={value}
|
|
193
|
-
filename={filename}
|
|
194
|
-
filenamePlaceholder="Drag and drop a file or upload one"
|
|
195
|
-
browseButtonText="Upload"
|
|
196
|
-
onFileInputChange={this.handleFileInputChange}
|
|
197
|
-
onClearClick={this.handleClear}
|
|
198
|
-
/>
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
51
|
+
```ts file="./FileUploadSimpleFile.tsx"
|
|
202
52
|
```
|
|
203
53
|
|
|
204
54
|
### Customizing the file preview
|
|
@@ -207,43 +57,7 @@ Regardless of `type`, the preview area (the TextArea, or any future implementati
|
|
|
207
57
|
|
|
208
58
|
### Custom file preview
|
|
209
59
|
|
|
210
|
-
```
|
|
211
|
-
import React from 'react';
|
|
212
|
-
import { FileUpload } from '@patternfly/react-core';
|
|
213
|
-
import FileUploadIcon from '@patternfly/react-icons/dist/esm/icons/file-upload-icon';
|
|
214
|
-
|
|
215
|
-
class CustomPreviewFileUpload extends React.Component {
|
|
216
|
-
constructor(props) {
|
|
217
|
-
super(props);
|
|
218
|
-
this.state = { value: null, filename: '' };
|
|
219
|
-
this.handleFileInputChange = (event, file) => {
|
|
220
|
-
this.setState({ value: file, filename: file.name });
|
|
221
|
-
};
|
|
222
|
-
this.handleClear = event => this.setState({ filename: '', value: '' });
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
render() {
|
|
226
|
-
const { value, filename, isLoading } = this.state;
|
|
227
|
-
return (
|
|
228
|
-
<FileUpload
|
|
229
|
-
id="customized-preview-file"
|
|
230
|
-
value={value}
|
|
231
|
-
filename={filename}
|
|
232
|
-
filenamePlaceholder="Drag and drop a file or upload one"
|
|
233
|
-
onFileInputChange={this.handleFileInputChange}
|
|
234
|
-
onClearClick={this.handleClear}
|
|
235
|
-
hideDefaultPreview
|
|
236
|
-
browseButtonText="Upload"
|
|
237
|
-
>
|
|
238
|
-
{value && (
|
|
239
|
-
<div className="pf-u-m-md">
|
|
240
|
-
<FileUploadIcon size="lg" /> Custom preview here for your {value.size}-byte file named {value.name}
|
|
241
|
-
</div>
|
|
242
|
-
)}
|
|
243
|
-
</FileUpload>
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
60
|
+
```ts file="./FileUploadCustomPreview.tsx"
|
|
247
61
|
```
|
|
248
62
|
|
|
249
63
|
### Bringing your own file browse logic
|
|
@@ -254,83 +68,5 @@ Note that the `isLoading` prop is styled to position the spinner dead center abo
|
|
|
254
68
|
|
|
255
69
|
### Custom file upload
|
|
256
70
|
|
|
257
|
-
```
|
|
258
|
-
import React from 'react';
|
|
259
|
-
import { FileUploadField, Checkbox } from '@patternfly/react-core';
|
|
260
|
-
|
|
261
|
-
class CustomFileUpload extends React.Component {
|
|
262
|
-
constructor(props) {
|
|
263
|
-
super(props);
|
|
264
|
-
this.state = {
|
|
265
|
-
value: '',
|
|
266
|
-
filename: false,
|
|
267
|
-
isClearButtonDisabled: true,
|
|
268
|
-
isLoading: false,
|
|
269
|
-
isDragActive: false,
|
|
270
|
-
hideDefaultPreview: false,
|
|
271
|
-
children: false,
|
|
272
|
-
hasPlaceholderText: false
|
|
273
|
-
};
|
|
274
|
-
this.handleTextAreaChange = value => {
|
|
275
|
-
this.setState({ value });
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
render() {
|
|
280
|
-
const {
|
|
281
|
-
value,
|
|
282
|
-
filename,
|
|
283
|
-
isClearButtonDisabled,
|
|
284
|
-
isLoading,
|
|
285
|
-
isDragActive,
|
|
286
|
-
hideDefaultPreview,
|
|
287
|
-
children,
|
|
288
|
-
hasPlaceholderText
|
|
289
|
-
} = this.state;
|
|
290
|
-
return (
|
|
291
|
-
<div>
|
|
292
|
-
{['filename', 'isClearButtonDisabled', 'isDragActive', 'isLoading', 'hideDefaultPreview', 'children', 'hasPlaceholderText'].map(
|
|
293
|
-
stateKey => (
|
|
294
|
-
<Checkbox
|
|
295
|
-
key={stateKey}
|
|
296
|
-
id={stateKey}
|
|
297
|
-
label={stateKey}
|
|
298
|
-
aria-label={stateKey}
|
|
299
|
-
isChecked={this.state[stateKey]}
|
|
300
|
-
onChange={checked =>
|
|
301
|
-
this.setState({
|
|
302
|
-
[stateKey]: checked,
|
|
303
|
-
// See notes above this example
|
|
304
|
-
...(stateKey === 'isLoading' && checked && { hideDefaultPreview: false }),
|
|
305
|
-
...(stateKey === 'hideDefaultPreview' && checked && { isLoading: false })
|
|
306
|
-
})
|
|
307
|
-
}
|
|
308
|
-
/>
|
|
309
|
-
)
|
|
310
|
-
)}
|
|
311
|
-
<br />
|
|
312
|
-
<FileUploadField
|
|
313
|
-
id="custom-file-upload"
|
|
314
|
-
type="text"
|
|
315
|
-
value={value}
|
|
316
|
-
filename={filename ? 'example-filename.txt' : ''}
|
|
317
|
-
onTextChange={this.handleTextAreaChange}
|
|
318
|
-
filenamePlaceholder="Do something custom with this!"
|
|
319
|
-
onBrowseButtonClick={() => alert('Browse button clicked!')}
|
|
320
|
-
onClearButtonClick={() => alert('Clear button clicked!')}
|
|
321
|
-
isClearButtonDisabled={isClearButtonDisabled}
|
|
322
|
-
isLoading={isLoading}
|
|
323
|
-
isDragActive={isDragActive}
|
|
324
|
-
hideDefaultPreview={hideDefaultPreview}
|
|
325
|
-
browseButtonText="Upload"
|
|
326
|
-
textAreaPlaceholder={hasPlaceholderText ? "File preview" : ''}
|
|
327
|
-
>
|
|
328
|
-
{children && (
|
|
329
|
-
<div className="pf-u-m-md">(A custom preview of the uploaded file can be passed as children)</div>
|
|
330
|
-
)}
|
|
331
|
-
</FileUploadField>
|
|
332
|
-
</div>
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
71
|
+
```ts file="./FileUploadCustomUpload.tsx"
|
|
336
72
|
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FileUpload } from '@patternfly/react-core';
|
|
3
|
+
import FileUploadIcon from '@patternfly/react-icons/dist/esm/icons/file-upload-icon';
|
|
4
|
+
|
|
5
|
+
export const CustomPreviewFileUpload: React.FunctionComponent = () => {
|
|
6
|
+
const [value, setValue] = React.useState(null);
|
|
7
|
+
const [filename, setFilename] = React.useState('');
|
|
8
|
+
|
|
9
|
+
const handleFileInputChange = (
|
|
10
|
+
_event: React.ChangeEvent<HTMLInputElement> | React.DragEvent<HTMLElement>,
|
|
11
|
+
file: File
|
|
12
|
+
) => {
|
|
13
|
+
setValue(file);
|
|
14
|
+
setFilename(file.name);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const handleClear = (_event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
|
18
|
+
setFilename('');
|
|
19
|
+
setValue('');
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<FileUpload
|
|
24
|
+
id="customized-preview-file"
|
|
25
|
+
value={value}
|
|
26
|
+
filename={filename}
|
|
27
|
+
filenamePlaceholder="Drag and drop a file or upload one"
|
|
28
|
+
onFileInputChange={handleFileInputChange}
|
|
29
|
+
onClearClick={handleClear}
|
|
30
|
+
hideDefaultPreview
|
|
31
|
+
browseButtonText="Upload"
|
|
32
|
+
>
|
|
33
|
+
{value && (
|
|
34
|
+
<div className="pf-u-m-md">
|
|
35
|
+
<FileUploadIcon size="lg" /> Custom preview here for your {value.size}-byte file named {value.name}
|
|
36
|
+
</div>
|
|
37
|
+
)}
|
|
38
|
+
</FileUpload>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FileUploadField, Checkbox } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const CustomPreviewFileUpload: React.FunctionComponent = () => {
|
|
5
|
+
const properties = [
|
|
6
|
+
'filename',
|
|
7
|
+
'isClearButtonDisabled',
|
|
8
|
+
'isDragActive',
|
|
9
|
+
'isLoading',
|
|
10
|
+
'hideDefaultPreview',
|
|
11
|
+
'children',
|
|
12
|
+
'hasPlaceholderText'
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const [value, setValue] = React.useState('');
|
|
16
|
+
const [filename, setFilename] = React.useState(false);
|
|
17
|
+
const [isClearButtonDisabled, setIsClearButtonDisabled] = React.useState(true);
|
|
18
|
+
const [isLoading, setIsLoading] = React.useState(false);
|
|
19
|
+
const [isDragActive, setIsDragActive] = React.useState(false);
|
|
20
|
+
const [hideDefaultPreview, setHideDefaultPreview] = React.useState(false);
|
|
21
|
+
const [children, setChildren] = React.useState(false);
|
|
22
|
+
const [hasPlaceholderText, setHasPlaceholderText] = React.useState(false);
|
|
23
|
+
const [checkedState, setCheckedState] = React.useState([
|
|
24
|
+
filename,
|
|
25
|
+
isClearButtonDisabled,
|
|
26
|
+
isLoading,
|
|
27
|
+
isDragActive,
|
|
28
|
+
hideDefaultPreview,
|
|
29
|
+
children,
|
|
30
|
+
hasPlaceholderText
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
const handleTextAreaChange = (value: string) => {
|
|
34
|
+
setValue(value);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const handleOnChange = (checked: boolean, stateKey: string, index: number) => {
|
|
38
|
+
const updatedCheckedState = [...checkedState];
|
|
39
|
+
switch (stateKey) {
|
|
40
|
+
case 'filename':
|
|
41
|
+
checked ? setFilename(true) : setFilename(false);
|
|
42
|
+
break;
|
|
43
|
+
|
|
44
|
+
case 'isClearButtonDisabled':
|
|
45
|
+
checked ? setIsClearButtonDisabled(true) : setIsClearButtonDisabled(false);
|
|
46
|
+
break;
|
|
47
|
+
|
|
48
|
+
case 'isDragActive':
|
|
49
|
+
checked ? setIsDragActive(true) : setIsDragActive(false);
|
|
50
|
+
break;
|
|
51
|
+
|
|
52
|
+
case 'isLoading':
|
|
53
|
+
checked ? setIsLoading(true) : setIsLoading(false);
|
|
54
|
+
// See notes above this example
|
|
55
|
+
if (checked) {
|
|
56
|
+
updatedCheckedState[properties.indexOf('hideDefaultPreview')] = false;
|
|
57
|
+
setHideDefaultPreview(false);
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case 'hideDefaultPreview':
|
|
62
|
+
checked ? setHideDefaultPreview(true) : setHideDefaultPreview(false);
|
|
63
|
+
// See notes above this example
|
|
64
|
+
if (checked) {
|
|
65
|
+
updatedCheckedState[properties.indexOf('isLoading')] = false;
|
|
66
|
+
setIsLoading(false);
|
|
67
|
+
}
|
|
68
|
+
break;
|
|
69
|
+
|
|
70
|
+
case 'children':
|
|
71
|
+
checked ? setChildren(true) : setChildren(false);
|
|
72
|
+
break;
|
|
73
|
+
|
|
74
|
+
case 'hasPlaceholderText':
|
|
75
|
+
checked ? setHasPlaceholderText(true) : setHasPlaceholderText(false);
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
updatedCheckedState[index] = checked;
|
|
79
|
+
setCheckedState(updatedCheckedState);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<div>
|
|
84
|
+
{properties.map((stateKey, index) => (
|
|
85
|
+
<Checkbox
|
|
86
|
+
name={stateKey}
|
|
87
|
+
key={stateKey}
|
|
88
|
+
id={stateKey}
|
|
89
|
+
label={stateKey}
|
|
90
|
+
aria-label={stateKey}
|
|
91
|
+
isChecked={checkedState[index]}
|
|
92
|
+
onChange={checked => handleOnChange(checked, stateKey, index)}
|
|
93
|
+
/>
|
|
94
|
+
))}
|
|
95
|
+
<br />
|
|
96
|
+
<FileUploadField
|
|
97
|
+
id="custom-file-upload"
|
|
98
|
+
type="text"
|
|
99
|
+
value={value}
|
|
100
|
+
filename={filename ? 'example-filename.txt' : ''}
|
|
101
|
+
onTextChange={handleTextAreaChange}
|
|
102
|
+
filenamePlaceholder="Do something custom with this!"
|
|
103
|
+
onBrowseButtonClick={() => alert('Browse button clicked!')}
|
|
104
|
+
onClearButtonClick={() => alert('Clear button clicked!')}
|
|
105
|
+
isClearButtonDisabled={isClearButtonDisabled}
|
|
106
|
+
isLoading={isLoading}
|
|
107
|
+
isDragActive={isDragActive}
|
|
108
|
+
hideDefaultPreview={hideDefaultPreview}
|
|
109
|
+
browseButtonText="Upload"
|
|
110
|
+
textAreaPlaceholder={hasPlaceholderText ? 'File preview' : ''}
|
|
111
|
+
>
|
|
112
|
+
{children && <div className="pf-u-m-md">(A custom preview of the uploaded file can be passed as children)</div>}
|
|
113
|
+
</FileUploadField>
|
|
114
|
+
</div>
|
|
115
|
+
);
|
|
116
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FileUpload } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const SimpleFileUpload: React.FunctionComponent = () => {
|
|
5
|
+
const [value, setValue] = React.useState(null);
|
|
6
|
+
const [filename, setFilename] = React.useState('');
|
|
7
|
+
|
|
8
|
+
const handleFileInputChange = (
|
|
9
|
+
_event: React.ChangeEvent<HTMLInputElement> | React.DragEvent<HTMLElement>,
|
|
10
|
+
file: File
|
|
11
|
+
) => {
|
|
12
|
+
setFilename(file.name);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const handleClear = (_event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
|
16
|
+
setFilename('');
|
|
17
|
+
setValue('');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<FileUpload
|
|
22
|
+
id="simple-file"
|
|
23
|
+
value={value}
|
|
24
|
+
filename={filename}
|
|
25
|
+
filenamePlaceholder="Drag and drop a file or upload one"
|
|
26
|
+
onFileInputChange={handleFileInputChange}
|
|
27
|
+
onClearClick={handleClear}
|
|
28
|
+
browseButtonText="Upload"
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FileUpload } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const SimpleTextFileUpload: React.FunctionComponent = () => {
|
|
5
|
+
const [value, setValue] = React.useState('');
|
|
6
|
+
const [filename, setFilename] = React.useState('');
|
|
7
|
+
const [isLoading, setIsLoading] = React.useState(false);
|
|
8
|
+
|
|
9
|
+
const handleFileInputChange = (
|
|
10
|
+
_event: React.ChangeEvent<HTMLInputElement> | React.DragEvent<HTMLElement>,
|
|
11
|
+
file: File
|
|
12
|
+
) => {
|
|
13
|
+
setFilename(file.name);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const handleTextOrDataChange = (value: string) => {
|
|
17
|
+
setValue(value);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const handleClear = (_event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
|
21
|
+
setFilename('');
|
|
22
|
+
setValue('');
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const handleFileReadStarted = (_fileHandle: File) => {
|
|
26
|
+
setIsLoading(true);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const handleFileReadFinished = (_fileHandle: File) => {
|
|
30
|
+
setIsLoading(false);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<FileUpload
|
|
35
|
+
id="text-file-with-edits-allowed"
|
|
36
|
+
type="text"
|
|
37
|
+
value={value}
|
|
38
|
+
filename={filename}
|
|
39
|
+
filenamePlaceholder="Drag and drop a file or upload one"
|
|
40
|
+
onFileInputChange={handleFileInputChange}
|
|
41
|
+
onDataChange={handleTextOrDataChange}
|
|
42
|
+
onTextChange={handleTextOrDataChange}
|
|
43
|
+
onReadStarted={handleFileReadStarted}
|
|
44
|
+
onReadFinished={handleFileReadFinished}
|
|
45
|
+
onClearClick={handleClear}
|
|
46
|
+
isLoading={isLoading}
|
|
47
|
+
allowEditingUploadedText={false}
|
|
48
|
+
browseButtonText="Upload"
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FileUpload } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const TextFileWithEditsAllowed: React.FunctionComponent = () => {
|
|
5
|
+
const [value, setValue] = React.useState('');
|
|
6
|
+
const [filename, setFilename] = React.useState('');
|
|
7
|
+
const [isLoading, setIsLoading] = React.useState(false);
|
|
8
|
+
|
|
9
|
+
const handleFileInputChange = (
|
|
10
|
+
_event: React.ChangeEvent<HTMLInputElement> | React.DragEvent<HTMLElement>,
|
|
11
|
+
file: File
|
|
12
|
+
) => {
|
|
13
|
+
setFilename(file.name);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const handleTextOrDataChange = (value: string) => {
|
|
17
|
+
setValue(value);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const handleClear = (_event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
|
21
|
+
setFilename('');
|
|
22
|
+
setValue('');
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const handleFileReadStarted = (_fileHandle: File) => {
|
|
26
|
+
setIsLoading(true);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const handleFileReadFinished = (_fileHandle: File) => {
|
|
30
|
+
setIsLoading(false);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<FileUpload
|
|
35
|
+
id="text-file-with-edits-allowed"
|
|
36
|
+
type="text"
|
|
37
|
+
value={value}
|
|
38
|
+
filename={filename}
|
|
39
|
+
filenamePlaceholder="Drag and drop a file or upload one"
|
|
40
|
+
onFileInputChange={handleFileInputChange}
|
|
41
|
+
onDataChange={handleTextOrDataChange}
|
|
42
|
+
onTextChange={handleTextOrDataChange}
|
|
43
|
+
onReadStarted={handleFileReadStarted}
|
|
44
|
+
onReadFinished={handleFileReadFinished}
|
|
45
|
+
onClearClick={handleClear}
|
|
46
|
+
isLoading={isLoading}
|
|
47
|
+
allowEditingUploadedText={true}
|
|
48
|
+
browseButtonText="Upload"
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FileUpload, Form, FormGroup } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const TextFileUploadWithRestrictions: React.FunctionComponent = () => {
|
|
5
|
+
const [value, setValue] = React.useState('');
|
|
6
|
+
const [filename, setFilename] = React.useState('');
|
|
7
|
+
const [isLoading, setIsLoading] = React.useState(false);
|
|
8
|
+
const [isRejected, setIsRejected] = React.useState(false);
|
|
9
|
+
|
|
10
|
+
const handleFileInputChange = (
|
|
11
|
+
_event: React.ChangeEvent<HTMLInputElement> | React.DragEvent<HTMLElement>,
|
|
12
|
+
file: File
|
|
13
|
+
) => {
|
|
14
|
+
setFilename(file.name);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const handleTextOrDataChange = (value: string) => {
|
|
18
|
+
setValue(value);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const handleClear = (_event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
|
22
|
+
setFilename('');
|
|
23
|
+
setValue('');
|
|
24
|
+
setIsRejected(false);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const handleFileRejected = (_rejectedFiles: File[], _event: React.DragEvent<HTMLElement>) => {
|
|
28
|
+
setIsRejected(true);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const handleFileReadStarted = (_fileHandle: File) => {
|
|
32
|
+
setIsLoading(true);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const handleFileReadFinished = (_fileHandle: File) => {
|
|
36
|
+
setIsLoading(false);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Form>
|
|
41
|
+
<FormGroup
|
|
42
|
+
fieldId="text-file-with-restrictions"
|
|
43
|
+
helperText="Upload a CSV file"
|
|
44
|
+
helperTextInvalid="Must be a CSV file no larger than 1 KB"
|
|
45
|
+
validated={isRejected ? 'error' : 'default'}
|
|
46
|
+
>
|
|
47
|
+
<FileUpload
|
|
48
|
+
id="text-file-with-restrictions"
|
|
49
|
+
type="text"
|
|
50
|
+
value={value}
|
|
51
|
+
filename={filename}
|
|
52
|
+
filenamePlaceholder="Drag and drop a file or upload one"
|
|
53
|
+
onFileInputChange={handleFileInputChange}
|
|
54
|
+
onDataChange={handleTextOrDataChange}
|
|
55
|
+
onTextChange={handleTextOrDataChange}
|
|
56
|
+
onReadStarted={handleFileReadStarted}
|
|
57
|
+
onReadFinished={handleFileReadFinished}
|
|
58
|
+
onClearClick={handleClear}
|
|
59
|
+
isLoading={isLoading}
|
|
60
|
+
dropzoneProps={{
|
|
61
|
+
accept: '.csv',
|
|
62
|
+
maxSize: 1024,
|
|
63
|
+
onDropRejected: handleFileRejected
|
|
64
|
+
}}
|
|
65
|
+
validated={isRejected ? 'error' : 'default'}
|
|
66
|
+
browseButtonText="Upload"
|
|
67
|
+
/>
|
|
68
|
+
</FormGroup>
|
|
69
|
+
</Form>
|
|
70
|
+
);
|
|
71
|
+
};
|