From be1c21c69860e1504e325bc3f8d22a50800a9cd5 Mon Sep 17 00:00:00 2001 From: Anders Date: Fri, 13 Dec 2024 15:40:20 +0100 Subject: [PATCH] feat(Value.Upload): add async `onFileClick` event (#4397) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tobias Høegh --- .../forms/Value/Upload/Examples.tsx | 109 +++++++++++- .../extensions/forms/Value/Upload/demos.mdx | 5 + .../components/upload/UploadFileListCell.tsx | 68 ++++---- .../components/upload/UploadFileListLink.tsx | 1 + .../extensions/forms/Value/Upload/Upload.tsx | 112 +++++++------ .../__tests__/Upload.screenshot.test.ts | 26 ++- .../Value/Upload/__tests__/Upload.test.tsx | 50 +++++- ...abel-and-value-with-on-file-click.snap.png | Bin 0 -> 8988 bytes ...oad-have-to-match-label-and-value.snap.png | Bin 0 -> 8599 bytes ...have-to-match-list-upload-inline.snap.png} | Bin ...-to-match-list-with-on-file-click.snap.png | Bin 0 -> 24315 bytes ...> valueupload-have-to-match-list.snap.png} | Bin .../Value/Upload/stories/Upload.stories.tsx | 156 +++++++++++------- .../Value/Upload/style/dnb-value-upload.scss | 8 + .../forms/Value/Upload/style/index.ts | 6 + .../forms/ValueBlock/style/index.ts | 2 +- .../dnb-eufemia/src/style/dnb-ui-forms.scss | 1 + 17 files changed, 398 insertions(+), 146 deletions(-) create mode 100644 packages/dnb-eufemia/src/extensions/forms/Value/Upload/__tests__/__image_snapshots__/valueupload-have-to-match-label-and-value-with-on-file-click.snap.png create mode 100644 packages/dnb-eufemia/src/extensions/forms/Value/Upload/__tests__/__image_snapshots__/valueupload-have-to-match-label-and-value.snap.png rename packages/dnb-eufemia/src/extensions/forms/Value/Upload/__tests__/__image_snapshots__/{valueupload-have-to-list-upload-inline.snap.png => valueupload-have-to-match-list-upload-inline.snap.png} (100%) create mode 100644 packages/dnb-eufemia/src/extensions/forms/Value/Upload/__tests__/__image_snapshots__/valueupload-have-to-match-list-with-on-file-click.snap.png rename packages/dnb-eufemia/src/extensions/forms/Value/Upload/__tests__/__image_snapshots__/{valueupload-have-to-list-upload-value.snap.png => valueupload-have-to-match-list.snap.png} (100%) create mode 100644 packages/dnb-eufemia/src/extensions/forms/Value/Upload/style/dnb-value-upload.scss create mode 100644 packages/dnb-eufemia/src/extensions/forms/Value/Upload/style/index.ts diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/Upload/Examples.tsx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/Upload/Examples.tsx index e77ff37b67d..529e0f109dc 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/Upload/Examples.tsx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/Upload/Examples.tsx @@ -1,6 +1,7 @@ import ComponentBox from '../../../../../../shared/tags/ComponentBox' import { Form, Value, Field } from '@dnb/eufemia/src/extensions/forms' import { Flex, Span } from '@dnb/eufemia/src' +import { createRequest } from '../../Form/SubmitIndicator/Examples' import { createMockFile } from '../../../../../../docs/uilib/components/upload/Examples' export const Placeholder = () => { @@ -152,7 +153,11 @@ export const Label = () => { export const LabelAndValue = () => { return ( - + { ) } +export const LabelAndValueOnFileClick = () => { + return ( + + { + console.log('Clicked on file') + }} + label="Label text" + value={[ + { + file: createMockFile('fileName-1.png', 1000000, 'image/png'), + exists: false, + id: '1', + }, + { + file: createMockFile('fileName-2.png', 2000000, 'image/png'), + exists: false, + isLoading: true, + id: '2', + }, + ]} + /> + + ) +} + export const Inline = () => { return ( { ) } +export const ListVariantsOnFileClick = () => { + return ( + + { + console.log('Clicked on file') + }} + value={[ + { + file: createMockFile('fileName-1.png', 1000000, 'image/png'), + exists: false, + isLoading: true, + id: '1', + }, + { + file: createMockFile('fileName-2.png', 2000000, 'image/png'), + exists: false, + id: '2', + }, + { + file: createMockFile('fileName-3.png', 3000000, 'image/png'), + exists: false, + id: '3', + }, + ]} + label="Ordered List" + variant="ol" + /> + { + console.log('Clicked on file') + }} + value={[ + { + file: createMockFile('fileName-1.png', 1000000, 'image/png'), + exists: false, + id: '1', + }, + { + file: createMockFile('fileName-2.png', 2000000, 'image/png'), + exists: false, + id: '2', + isLoading: true, + }, + { + file: createMockFile('fileName-3.png', 3000000, 'image/png'), + exists: false, + id: '3', + isLoading: true, + }, + ]} + label="Unordered List" + variant="ul" + /> + + ) +} + export const ListTypes = () => { return ( @@ -396,7 +493,7 @@ export const ListTypes = () => { export const OnFileClick = () => { return ( - + { id: '2', }, ]} - onFileClick={({ fileItem }) => { + onFileClick={async ({ fileItem }) => { + const request = createRequest() + console.log( + 'making API request to fetch the url of the file: ' + + fileItem.file.name, + ) + await request(2000) // Simulate a request window.open( 'https://eufemia.dnb.no/images/avatars/' + fileItem.file.name, '_blank', diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/Upload/demos.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/Upload/demos.mdx index 0ea47024a75..023e79d3970 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/Upload/demos.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/Upload/demos.mdx @@ -53,3 +53,8 @@ import * as Examples from './Examples' ### Using `onFileClick` + + + + + diff --git a/packages/dnb-eufemia/src/components/upload/UploadFileListCell.tsx b/packages/dnb-eufemia/src/components/upload/UploadFileListCell.tsx index 78cd45065d1..6f0b787eea9 100644 --- a/packages/dnb-eufemia/src/components/upload/UploadFileListCell.tsx +++ b/packages/dnb-eufemia/src/components/upload/UploadFileListCell.tsx @@ -29,6 +29,7 @@ import { getPreviousSibling } from '../../shared/component-helper' import useUpload from './useUpload' import { getFileTypeFromExtension } from './UploadVerify' import UploadFileLink from './UploadFileListLink' +import { ProgressIndicatorAllProps } from '../progress-indicator/types' // Will be deprecated - and then default to only showing the file icon, // and not file icon per file extension type @@ -90,8 +91,6 @@ const UploadFileListCell = ({ const { file, errorMessage, isLoading } = uploadFile const hasWarning = errorMessage != null - const fileType = getFileTypeFromExtension(file) - const imageUrl = URL.createObjectURL(file) const cellRef = useRef() const exists = useExistsHighlight(id, file) @@ -122,7 +121,7 @@ const UploadFileListCell = ({ >
- {getIcon()} + {getFileIcon(file, { isLoading }, hasWarning)} {getTitle()}
@@ -142,34 +141,6 @@ const UploadFileListCell = ({ ) - function getIcon() { - if (isLoading) { - return - } - - if (hasWarning) return - - let iconFileType = fileType - - if (!iconFileType) { - const mimeParts = file.type.split('/') - iconFileType = - fileExtensionImages[mimeParts[0]] || - fileExtensionImages[mimeParts[1]] - } - - if ( - !Object.prototype.hasOwnProperty.call( - fileExtensionImages, - iconFileType - ) - ) { - iconFileType = 'file' - } - - return - } - function getTitle() { return isLoading ? (
+ } + + if (hasWarning) return + + let iconFileType = getFileTypeFromExtension(file) + + if (!iconFileType) { + const mimeParts = file.type.split('/') + iconFileType = + fileExtensionImages[mimeParts[0]] || + fileExtensionImages[mimeParts[1]] + } + + if ( + !Object.prototype.hasOwnProperty.call( + fileExtensionImages, + iconFileType + ) + ) { + iconFileType = 'file' + } + + return +} diff --git a/packages/dnb-eufemia/src/components/upload/UploadFileListLink.tsx b/packages/dnb-eufemia/src/components/upload/UploadFileListLink.tsx index 9a96178d4ca..015ed24284a 100644 --- a/packages/dnb-eufemia/src/components/upload/UploadFileListLink.tsx +++ b/packages/dnb-eufemia/src/components/upload/UploadFileListLink.tsx @@ -36,6 +36,7 @@ const UploadFileButton = (props: UploadFileButtonProps) => { const spacingClasses = createSpacingClasses(props) return (