diff --git a/packages/react-core/src/components/FileUpload/examples/FileUpload.md b/packages/react-core/src/components/FileUpload/examples/FileUpload.md index 037913251d4..88e897072b3 100644 --- a/packages/react-core/src/components/FileUpload/examples/FileUpload.md +++ b/packages/react-core/src/components/FileUpload/examples/FileUpload.md @@ -18,42 +18,7 @@ Pressing _Clear_ button triggers `onClearClick` event. ### Simple text file -```js -import React from 'react'; -import { FileUpload } from '@patternfly/react-core'; - -class SimpleTextFileUpload extends React.Component { - constructor(props) { - super(props); - this.state = { value: '', filename: '', isLoading: false }; - this.handleFileInputChange = (event, file) => this.setState({ filename: file.name }); - this.handleTextOrDataChange = value => this.setState({ value }); - this.handleClear = event => this.setState({ filename: '', value: '' }); - this.handleFileReadStarted = fileHandle => this.setState({ isLoading: true }); - this.handleFileReadFinished = fileHandle => this.setState({ isLoading: false }); - } - - render() { - const { value, filename, isLoading } = this.state; - return ( - - ); - } -} +```ts file="./FileUploadSimpleText.tsx" ``` 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 ### Text file with edits allowed -```js -import React from 'react'; -import { FileUpload } from '@patternfly/react-core'; - -class TextFileWithEditsAllowed extends React.Component { - constructor(props) { - super(props); - this.state = { value: '', filename: '', isLoading: false }; - this.handleFileInputChange = (event, file) => this.setState({ filename: file.name }); - this.handleTextOrDataChange = value => this.setState({ value }); - this.handleClear = event => this.setState({ filename: '', value: '' }); - this.handleFileReadStarted = fileHandle => this.setState({ isLoading: true }); - this.handleFileReadFinished = fileHandle => this.setState({ isLoading: false }); - } - - render() { - const { value, filename, isLoading } = this.state; - return ( - - ); - } -} +```ts file="./FileUploadTextWithEdits.tsx" ``` ### Restricting file size and type @@ -110,58 +39,7 @@ Restricting file sizes and types in this way is for user convenience only, and i ### Text file with restrictions -```js -import React from 'react'; -import { FileUpload, Form, FormGroup } from '@patternfly/react-core'; - -class TextFileUploadWithRestrictions extends React.Component { - constructor(props) { - super(props); - this.state = { value: '', filename: '', isLoading: false, isRejected: false }; - this.handleFileInputChange = (event, file) => this.setState({ filename: file.name }); - this.handleTextOrDataChange = value => this.setState({ value }); - this.handleClear = event => this.setState({ filename: '', value: '', isRejected: false }); - this.handleFileRejected = (rejectedFiles, event) => this.setState({ isRejected: true }); - this.handleFileReadStarted = fileHandle => this.setState({ isLoading: true }); - this.handleFileReadFinished = fileHandle => this.setState({ isLoading: false }); - } - - render() { - const { value, filename, isLoading, isRejected } = this.state; - return ( -
- - - -
- ); - } -} +```ts file="./FileUploadTextWithRestrictions.tsx" ``` ### Other file types @@ -170,35 +48,7 @@ If no `type` prop is specified, the component will not read files directly. When ### Simple file of any format -```js -import React from 'react'; -import { FileUpload } from '@patternfly/react-core'; - -class SimpleFileUpload extends React.Component { - constructor(props) { - super(props); - this.state = { value: null, filename: '' }; - this.handleFileInputChange = (event, file) => { - this.setState({ filename: file.name }); - }; - this.handleClear = event => this.setState({ filename: '', value: '' }); - } - - render() { - const { value, filename } = this.state; - return ( - - ); - } -} +```ts file="./FileUploadSimpleFile.tsx" ``` ### Customizing the file preview @@ -207,43 +57,7 @@ Regardless of `type`, the preview area (the TextArea, or any future implementati ### Custom file preview -```js -import React from 'react'; -import { FileUpload } from '@patternfly/react-core'; -import FileUploadIcon from '@patternfly/react-icons/dist/esm/icons/file-upload-icon'; - -class CustomPreviewFileUpload extends React.Component { - constructor(props) { - super(props); - this.state = { value: null, filename: '' }; - this.handleFileInputChange = (event, file) => { - this.setState({ value: file, filename: file.name }); - }; - this.handleClear = event => this.setState({ filename: '', value: '' }); - } - - render() { - const { value, filename, isLoading } = this.state; - return ( - - {value && ( -
- Custom preview here for your {value.size}-byte file named {value.name} -
- )} -
- ); - } -} +```ts file="./FileUploadCustomPreview.tsx" ``` ### Bringing your own file browse logic @@ -254,83 +68,5 @@ Note that the `isLoading` prop is styled to position the spinner dead center abo ### Custom file upload -```js -import React from 'react'; -import { FileUploadField, Checkbox } from '@patternfly/react-core'; - -class CustomFileUpload extends React.Component { - constructor(props) { - super(props); - this.state = { - value: '', - filename: false, - isClearButtonDisabled: true, - isLoading: false, - isDragActive: false, - hideDefaultPreview: false, - children: false, - hasPlaceholderText: false - }; - this.handleTextAreaChange = value => { - this.setState({ value }); - }; - } - - render() { - const { - value, - filename, - isClearButtonDisabled, - isLoading, - isDragActive, - hideDefaultPreview, - children, - hasPlaceholderText - } = this.state; - return ( -
- {['filename', 'isClearButtonDisabled', 'isDragActive', 'isLoading', 'hideDefaultPreview', 'children', 'hasPlaceholderText'].map( - stateKey => ( - - this.setState({ - [stateKey]: checked, - // See notes above this example - ...(stateKey === 'isLoading' && checked && { hideDefaultPreview: false }), - ...(stateKey === 'hideDefaultPreview' && checked && { isLoading: false }) - }) - } - /> - ) - )} -
- alert('Browse button clicked!')} - onClearButtonClick={() => alert('Clear button clicked!')} - isClearButtonDisabled={isClearButtonDisabled} - isLoading={isLoading} - isDragActive={isDragActive} - hideDefaultPreview={hideDefaultPreview} - browseButtonText="Upload" - textAreaPlaceholder={hasPlaceholderText ? "File preview" : ''} - > - {children && ( -
(A custom preview of the uploaded file can be passed as children)
- )} -
-
- ); - } -} +```ts file="./FileUploadCustomUpload.tsx" ``` diff --git a/packages/react-core/src/components/FileUpload/examples/FileUploadCustomPreview.tsx b/packages/react-core/src/components/FileUpload/examples/FileUploadCustomPreview.tsx new file mode 100644 index 00000000000..773ab29d88b --- /dev/null +++ b/packages/react-core/src/components/FileUpload/examples/FileUploadCustomPreview.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { FileUpload } from '@patternfly/react-core'; +import FileUploadIcon from '@patternfly/react-icons/dist/esm/icons/file-upload-icon'; + +export const CustomPreviewFileUpload: React.FunctionComponent = () => { + const [value, setValue] = React.useState(null); + const [filename, setFilename] = React.useState(''); + + const handleFileInputChange = ( + _event: React.ChangeEvent | React.DragEvent, + file: File + ) => { + setValue(file); + setFilename(file.name); + }; + + const handleClear = (_event: React.MouseEvent) => { + setFilename(''); + setValue(''); + }; + + return ( + + {value && ( +
+ Custom preview here for your {value.size}-byte file named {value.name} +
+ )} +
+ ); +}; diff --git a/packages/react-core/src/components/FileUpload/examples/FileUploadCustomUpload.tsx b/packages/react-core/src/components/FileUpload/examples/FileUploadCustomUpload.tsx new file mode 100644 index 00000000000..7102067192f --- /dev/null +++ b/packages/react-core/src/components/FileUpload/examples/FileUploadCustomUpload.tsx @@ -0,0 +1,116 @@ +import React from 'react'; +import { FileUploadField, Checkbox } from '@patternfly/react-core'; + +export const CustomPreviewFileUpload: React.FunctionComponent = () => { + const properties = [ + 'filename', + 'isClearButtonDisabled', + 'isDragActive', + 'isLoading', + 'hideDefaultPreview', + 'children', + 'hasPlaceholderText' + ]; + + const [value, setValue] = React.useState(''); + const [filename, setFilename] = React.useState(false); + const [isClearButtonDisabled, setIsClearButtonDisabled] = React.useState(true); + const [isLoading, setIsLoading] = React.useState(false); + const [isDragActive, setIsDragActive] = React.useState(false); + const [hideDefaultPreview, setHideDefaultPreview] = React.useState(false); + const [children, setChildren] = React.useState(false); + const [hasPlaceholderText, setHasPlaceholderText] = React.useState(false); + const [checkedState, setCheckedState] = React.useState([ + filename, + isClearButtonDisabled, + isLoading, + isDragActive, + hideDefaultPreview, + children, + hasPlaceholderText + ]); + + const handleTextAreaChange = (value: string) => { + setValue(value); + }; + + const handleOnChange = (checked: boolean, stateKey: string, index: number) => { + const updatedCheckedState = [...checkedState]; + switch (stateKey) { + case 'filename': + checked ? setFilename(true) : setFilename(false); + break; + + case 'isClearButtonDisabled': + checked ? setIsClearButtonDisabled(true) : setIsClearButtonDisabled(false); + break; + + case 'isDragActive': + checked ? setIsDragActive(true) : setIsDragActive(false); + break; + + case 'isLoading': + checked ? setIsLoading(true) : setIsLoading(false); + // See notes above this example + if (checked) { + updatedCheckedState[properties.indexOf('hideDefaultPreview')] = false; + setHideDefaultPreview(false); + } + break; + + case 'hideDefaultPreview': + checked ? setHideDefaultPreview(true) : setHideDefaultPreview(false); + // See notes above this example + if (checked) { + updatedCheckedState[properties.indexOf('isLoading')] = false; + setIsLoading(false); + } + break; + + case 'children': + checked ? setChildren(true) : setChildren(false); + break; + + case 'hasPlaceholderText': + checked ? setHasPlaceholderText(true) : setHasPlaceholderText(false); + break; + } + updatedCheckedState[index] = checked; + setCheckedState(updatedCheckedState); + }; + + return ( +
+ {properties.map((stateKey, index) => ( + handleOnChange(checked, stateKey, index)} + /> + ))} +
+ alert('Browse button clicked!')} + onClearButtonClick={() => alert('Clear button clicked!')} + isClearButtonDisabled={isClearButtonDisabled} + isLoading={isLoading} + isDragActive={isDragActive} + hideDefaultPreview={hideDefaultPreview} + browseButtonText="Upload" + textAreaPlaceholder={hasPlaceholderText ? 'File preview' : ''} + > + {children &&
(A custom preview of the uploaded file can be passed as children)
} +
+
+ ); +}; diff --git a/packages/react-core/src/components/FileUpload/examples/FileUploadSimpleFile.tsx b/packages/react-core/src/components/FileUpload/examples/FileUploadSimpleFile.tsx new file mode 100644 index 00000000000..ff67bc0259a --- /dev/null +++ b/packages/react-core/src/components/FileUpload/examples/FileUploadSimpleFile.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { FileUpload } from '@patternfly/react-core'; + +export const SimpleFileUpload: React.FunctionComponent = () => { + const [value, setValue] = React.useState(null); + const [filename, setFilename] = React.useState(''); + + const handleFileInputChange = ( + _event: React.ChangeEvent | React.DragEvent, + file: File + ) => { + setFilename(file.name); + }; + + const handleClear = (_event: React.MouseEvent) => { + setFilename(''); + setValue(''); + }; + + return ( + + ); +}; diff --git a/packages/react-core/src/components/FileUpload/examples/FileUploadSimpleText.tsx b/packages/react-core/src/components/FileUpload/examples/FileUploadSimpleText.tsx new file mode 100644 index 00000000000..a5bda90ce08 --- /dev/null +++ b/packages/react-core/src/components/FileUpload/examples/FileUploadSimpleText.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { FileUpload } from '@patternfly/react-core'; + +export const SimpleTextFileUpload: React.FunctionComponent = () => { + const [value, setValue] = React.useState(''); + const [filename, setFilename] = React.useState(''); + const [isLoading, setIsLoading] = React.useState(false); + + const handleFileInputChange = ( + _event: React.ChangeEvent | React.DragEvent, + file: File + ) => { + setFilename(file.name); + }; + + const handleTextOrDataChange = (value: string) => { + setValue(value); + }; + + const handleClear = (_event: React.MouseEvent) => { + setFilename(''); + setValue(''); + }; + + const handleFileReadStarted = (_fileHandle: File) => { + setIsLoading(true); + }; + + const handleFileReadFinished = (_fileHandle: File) => { + setIsLoading(false); + }; + + return ( + + ); +}; diff --git a/packages/react-core/src/components/FileUpload/examples/FileUploadTextWithEdits.tsx b/packages/react-core/src/components/FileUpload/examples/FileUploadTextWithEdits.tsx new file mode 100644 index 00000000000..e13382dffca --- /dev/null +++ b/packages/react-core/src/components/FileUpload/examples/FileUploadTextWithEdits.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { FileUpload } from '@patternfly/react-core'; + +export const TextFileWithEditsAllowed: React.FunctionComponent = () => { + const [value, setValue] = React.useState(''); + const [filename, setFilename] = React.useState(''); + const [isLoading, setIsLoading] = React.useState(false); + + const handleFileInputChange = ( + _event: React.ChangeEvent | React.DragEvent, + file: File + ) => { + setFilename(file.name); + }; + + const handleTextOrDataChange = (value: string) => { + setValue(value); + }; + + const handleClear = (_event: React.MouseEvent) => { + setFilename(''); + setValue(''); + }; + + const handleFileReadStarted = (_fileHandle: File) => { + setIsLoading(true); + }; + + const handleFileReadFinished = (_fileHandle: File) => { + setIsLoading(false); + }; + + return ( + + ); +}; diff --git a/packages/react-core/src/components/FileUpload/examples/FileUploadTextWithRestrictions.tsx b/packages/react-core/src/components/FileUpload/examples/FileUploadTextWithRestrictions.tsx new file mode 100644 index 00000000000..db982a67cfd --- /dev/null +++ b/packages/react-core/src/components/FileUpload/examples/FileUploadTextWithRestrictions.tsx @@ -0,0 +1,71 @@ +import React from 'react'; +import { FileUpload, Form, FormGroup } from '@patternfly/react-core'; + +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 handleFileInputChange = ( + _event: React.ChangeEvent | React.DragEvent, + file: File + ) => { + setFilename(file.name); + }; + + const handleTextOrDataChange = (value: string) => { + setValue(value); + }; + + const handleClear = (_event: React.MouseEvent) => { + setFilename(''); + setValue(''); + setIsRejected(false); + }; + + const handleFileRejected = (_rejectedFiles: File[], _event: React.DragEvent) => { + setIsRejected(true); + }; + + const handleFileReadStarted = (_fileHandle: File) => { + setIsLoading(true); + }; + + const handleFileReadFinished = (_fileHandle: File) => { + setIsLoading(false); + }; + + return ( +
+ + + +
+ ); +};