Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Upload): add new Upload component #1581

Merged
merged 21 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from 19 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: 'Upload'
description: 'The Upload widget should be used in scenarios where the user has to upload files. Files can be uploaded by clicking button. You also have the opportunity to add descriptive texts below the title where you could put max file size, allowed fileformats etc.'
status: 'new'
showTabs: true
hideTabs:
- title: Events
---

import UploadInfo from 'Docs/uilib/components/upload/info'
import UploadDemos from 'Docs/uilib/components/upload/demos'

<UploadInfo />
<UploadDemos />
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
/**
* UI lib Component Example
*
*/

import React from 'react'
import ComponentBox from 'dnb-design-system-portal/src/shared/tags/ComponentBox'

const createMockFile = (name: string, size: number, type: string) => {
const file = new File([], name, { type })
Object.defineProperty(file, 'size', {
get() {
return size
},
})
return file
}

const useMockFiles = (setFiles, extend) => {
React.useEffect(() => {
setFiles([
{
file: createMockFile('fileName.png', 123, 'image/png'),
...extend,
},
])
}, [])
}

export const UploadPrefilledFileList = () => (
<ComponentBox
useRender
data-visual-test="upload-file-list"
scope={{ useMockFiles }}
>
{
/* jsx */ `
const Component = () => {
const {files, setFiles} = Upload.useUpload('file-list')
useMockFiles(setFiles, { errorMessage: 'This is no real file!' })

return (
<Upload
acceptedFileTypes={['jpg', 'png']}
id='file-list'
/>
)
}
render(<Component />)
`
}
</ComponentBox>
)

export const UploadBasic = () => (
<ComponentBox useRender data-visual-test="upload-basic">
{
/* jsx */ `
const Component = () => {
const {files} = Upload.useUpload('upload-basic')

return (
<Upload
acceptedFileTypes={['jpg', 'png']}
id='upload-basic'
/>
)
}
render(<Component />)
`
}
</ComponentBox>
)

export const UploadMultipleFiles = () => (
<ComponentBox useRender data-visual-test="upload-multiple-files">
{
/* jsx */ `
const Component = () => {
const {files, setFiles} = Upload.useUpload('upload-multiple-files')
return (
<Upload
acceptedFileTypes={['jpg', 'png']}
id='upload-multiple-files'
multipleFiles={true}
/>
)
}
render(<Component />)
`
}
</ComponentBox>
)
export const UploadRemoveFile = () => (
<ComponentBox useRender data-visual-test="upload-remove-files">
{
/* jsx */ `
const Component = () => {
const {files, setFiles} = Upload.useUpload('upload-remove-files')
return (
<>
<Upload
acceptedFileTypes={['jpg', 'png']}
id='upload-remove-files'
/>
<Button
top='small'
disabled={files.length < 1}
onClick={() => setFiles([])}
>
Remove selected files
</Button>
</>
)
}
render(<Component />)
`
}
</ComponentBox>
)

export const UploadIsLoading = () => (
<ComponentBox
scope={{ useMockFiles }}
useRender
data-visual-test="upload-is-loading"
>
{
/* jsx */ `
const Component = () => {
const {files, setFiles} = Upload.useUpload('upload-is-loading')
useMockFiles(setFiles, { isLoading: true })

return (
<>
<Upload
acceptedFileTypes={['jpg', 'png']}
id='upload-is-loading'
/>
<ToggleButton top='small' disabled={files.length < 1} checked onChange={({ checked }) => {
setFiles(files.map((file) => {
return {...file, isLoading: checked}
}))
}}
>Files is loading toggle</ToggleButton>
</>
)
}
render(<Component />)
`
}
</ComponentBox>
)

export const UploadErrorMessage = () => (
<ComponentBox useRender data-visual-test="upload-error-message">
{
/* jsx */ `
const Component = () => {
const {files, setFiles} = Upload.useUpload('upload-error-message')
return (
<>
<Upload
acceptedFileTypes={['jpg', 'png']}
id='upload-error-message'
/>
<ToggleButton
top='small'
disabled={files.length < 1}
onChange={
({ checked }) => {
setFiles(
files.map((file) => {
return {...file, errorMessage: checked? 'custom error message': null}
})
)
}
}
>
Toggle error message
</ToggleButton>
</>
)
}
render(<Component />)
`
}
</ComponentBox>
)

export const UploadAcceptedFormats = () => (
<ComponentBox useRender>
{
/* jsx */ `
const Component = () => {
const {files, setFiles} = Upload.useUpload('upload-accepted-formats')

return (
<Upload
acceptedFileTypes={['png', 'jpg', 'pdf']}
id='upload-accepted-formats'
/>
)
}
render(<Component />)
`
}
</ComponentBox>
)

export const UploadCustomText = () => (
<ComponentBox>
{
/* jsx */ `
<Upload
acceptedFileTypes={['jpg', 'png']}
id='upload-custom-text'
title='custom title'
text='custom text'
formatsDescription='custom formatsDescription'
fileSizeDescription='custom fileSizeDescription'
fileSizeContent='custom fileSizeContent'
uploadButtonText='custom uploadButtonText'
uploadLoadingText='custom uploadLoadingText'
deleteButton='custom deleteButton'
/>
`
}
</ComponentBox>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
showTabs: true
---

import {
UploadBasic,
UploadPrefilledFileList,
UploadRemoveFile,
UploadMultipleFiles,
UploadIsLoading,
UploadErrorMessage,
UploadAcceptedFormats,
UploadCustomText,
} from 'Docs/uilib/components/upload/Examples'

## Demos

### Upload (default)

<UploadBasic />

### 'useUpload' React Hook

By using the `Upload.useUpload` you can remove or add files or the status displayed in the component.

<UploadRemoveFile />

### Upload multiple files

<UploadMultipleFiles />

### Upload loading state

When uploading the file you can set the loading state of the request using the `Upload.useUpload` hook and passing isLoading to the file that is being uploaded.

<UploadIsLoading />

### Upload error message

The only checks we do currently is for the file size and the file type. These errors are handled by the HTML element ´input´ so they aren't selectable. If you want any other error messages you can use the `Upload.useUpload` the same way as with the loading state.

<UploadErrorMessage />

### Upload specific accepted file formats

You can pass the file formats as a string array. This will restrict which files that can be selected.

<UploadAcceptedFormats />

### Upload custom text

All the text can be custom.

<UploadCustomText />

### Upload with prefilled error

<UploadPrefilledFileList />
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
showTabs: true
---

## Description

The Upload should be used in scenarios where the user has to upload any kind of files.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
showTabs: true
---

## Properties


| Properties | Description |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| [Space](/uilib/components/space/properties) | _(optional)_ Spacing properties like `top` or `bottom` are supported. |
| `className` | _(optional)_ Custom className for the component root. |
| `skeleton` | _(optional)_ Skeleton should be applied when loading content Default: null. |
| `acceptedFileTypes` | _(required)_ List of accepted file types. |
| `fileMaxSize` | _(optional)_ fileMaxSize is max size of each file in MB |
| `multipleFiles` | _(optional)_ if set true, accepting multiple files is allowed |
| `title` | _(optional)_ Custom text property. Replaces the default title |
| `text` | _(optional)_ Custom text property. Replaces the default text |
| `formatsDescription` | _(optional)_ Custom text property. Replaces the default accepted format description |
| `fileSizeDescription` | _(optional)_ Custom text property. Replaces the default max file size description |
| `fileSizeContent` | _(optional)_ Custom text property. Replaces the default file size content |
| `uploadButtonText` | _(optional)_ Custom text property. Replaces the default upload button text |
| `uploadLoadingText` | _(optional)_ Custom text property. Replaces the default loading text |
| `deleteButton` | _(optional)_ Custom text property. Replaces the default delete button text |
| `fileListAriaLabel` | _(optional)_ Custom text property. Replaces the default list aria label |
14 changes: 14 additions & 0 deletions packages/dnb-eufemia/src/components/Upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* ATTENTION: This file is auto generated by using "prepareTemplates".
* Do not change the content!
*
*/

/**
* Library Index upload to autogenerate all the components and extensions
* Used by "prepareUploads"
*/

import Upload from './upload/Upload'
export * from './upload/Upload'
export default Upload
2 changes: 2 additions & 0 deletions packages/dnb-eufemia/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import Textarea from './textarea/Textarea'
import Timeline from './timeline/Timeline'
import ToggleButton from './toggle-button/ToggleButton'
import Tooltip from './tooltip/Tooltip'
import Upload from './upload/Upload'
import VisuallyHidden from './visually-hidden/VisuallyHidden'

// define / export all the available components
Expand Down Expand Up @@ -102,5 +103,6 @@ export {
Timeline,
ToggleButton,
Tooltip,
Upload,
VisuallyHidden,
}
3 changes: 3 additions & 0 deletions packages/dnb-eufemia/src/components/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import Textarea from './textarea/Textarea'
import Timeline from './timeline/Timeline'
import ToggleButton from './toggle-button/ToggleButton'
import Tooltip from './tooltip/Tooltip'
import Upload from './upload/Upload'
import VisuallyHidden from './visually-hidden/VisuallyHidden'

// define / export all the available components
Expand Down Expand Up @@ -104,6 +105,7 @@ export {
Timeline,
ToggleButton,
Tooltip,
Upload,
VisuallyHidden,
}

Expand Down Expand Up @@ -153,6 +155,7 @@ export const getComponents = () => {
Timeline,
ToggleButton,
Tooltip,
Upload,
VisuallyHidden,
}
}
Expand Down
Loading