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): adds onFileClick event #4365

Merged
merged 5 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
Expand Up @@ -350,3 +350,42 @@ export const UploadOnFileDeleteAsync = () => (
}}
</ComponentBox>
)

export const UploadOnFileClick = () => (
<ComponentBox
scope={{ createMockFile }}
data-visual-test="upload-on-file-click"
>
{() => {
const Component = () => {
const { setFiles } = Upload.useUpload('upload-on-file-click')

React.useEffect(() => {
setFiles([
{
file: createMockFile('1501870.jpg', 123, 'image/png'),
},
])
}, [])

return (
<>
<Upload
acceptedFileTypes={['jpg', 'png']}
id="upload-on-file-click"
onFileClick={({ fileItem }) => {
window.open(
'https://eufemia.dnb.no/images/avatars/' +
fileItem.file.name,
'_blank',
)
}}
/>
</>
)
}

return <Component />
}}
</ComponentBox>
)
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
UploadFileMaxSizeBasedOnFileTypeDisabled,
UploadNoTitleNoText,
UploadOnFileDeleteAsync,
UploadOnFileClick,
} from 'Docs/uilib/components/upload/Examples'

## Demos
Expand Down Expand Up @@ -83,3 +84,7 @@ This can also be used to manually implement more complex file max size verificat
### Upload with async `onFileDelete`

<UploadOnFileDeleteAsync />

### Upload with `onFileClick`

<UploadOnFileClick />
1 change: 1 addition & 0 deletions packages/dnb-eufemia/src/components/upload/Upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const Upload = (localProps: UploadAllProps) => {
fileMaxSize,
onChange,
onFileDelete, // eslint-disable-line
onFileClick, // eslint-disable-line
download, // eslint-disable-line
title, // eslint-disable-line
text, // eslint-disable-line
Expand Down
5 changes: 5 additions & 0 deletions packages/dnb-eufemia/src/components/upload/UploadDocs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,9 @@ export const UploadEvents: PropertiesTableProps = {
type: 'function',
status: 'optional',
},
onFileClick: {
doc: 'Will be called once a file gets clicked on by the user. Access the clicked file with `{ fileItem }`.',
type: 'function',
status: 'optional',
},
}
8 changes: 8 additions & 0 deletions packages/dnb-eufemia/src/components/upload/UploadFileList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function UploadFileList() {
download,
loadingText,
onFileDelete,
onFileClick,
onChange,
} = context

Expand Down Expand Up @@ -96,12 +97,19 @@ function UploadFileList() {
}
}

const onFileClickHandler = () => {
if (typeof onFileClick === 'function') {
onFileClick({ fileItem: uploadFile })
}
}

return (
<UploadFileListCell
key={index}
id={id}
uploadFile={uploadFile}
onDelete={onDeleteHandler}
onClick={onFileClick && onFileClickHandler}
deleteButtonText={deleteButton}
loadingText={loadingText}
download={download}
Expand Down
43 changes: 31 additions & 12 deletions packages/dnb-eufemia/src/components/upload/UploadFileListCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ export type UploadFileListCellProps = {
*/
onDelete: () => void

/**
* Calls onClick when clicking the file name
*/
onClick?: () => void

/**
* Causes the browser to treat all listed files as downloadable instead of opening them in a new browser tab or window.
* Default: false
Expand All @@ -77,6 +82,7 @@ const UploadFileListCell = ({
id,
uploadFile,
onDelete,
onClick,
loadingText,
deleteButtonText,
download,
Expand Down Expand Up @@ -182,18 +188,31 @@ const UploadFileListCell = ({
</div>
) : (
<div className="dnb-upload__file-cell__text-container">
<Anchor
target="_blank"
href={imageUrl}
download={download ? file.name : null}
className={classnames(
'dnb-anchor--no-launch-icon',
'dnb-upload__file-cell__title'
)}
rel="noopener noreferrer"
>
{file.name}
</Anchor>
{onClick ? (
<Button
variant="tertiary"
className={classnames(
'dnb-anchor--no-launch-icon',
'dnb-upload__file-cell__title'
)}
langz marked this conversation as resolved.
Show resolved Hide resolved
onClick={onClick}
>
{file.name}
</Button>
) : (
<Anchor
target="_blank"
href={imageUrl}
download={download ? file.name : null}
className={classnames(
'dnb-anchor--no-launch-icon',
'dnb-upload__file-cell__title'
)}
rel="noopener noreferrer"
>
{file.name}
</Anchor>
)}
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ describe.each(['ui', 'sbanken'])('Upload for %s', (themeName) => {
})
expect(screenshot).toMatchImageSnapshot()
})

it('have to match anchor looks when displaying a button', async () => {
const screenshot = await makeScreenshot({
selector: '[data-visual-test="upload-on-file-click"]',
})
expect(screenshot).toMatchImageSnapshot()
})
})

describe('Upload', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import UploadFileListCell, {
UploadFileListCellProps,
} from '../UploadFileListCell'
import { createMockFile } from './testHelpers'
import { render, screen } from '@testing-library/react'
import { fireEvent, render, screen } from '@testing-library/react'
import React from 'react'

global.URL.createObjectURL = jest.fn(() => 'url')
Expand Down Expand Up @@ -272,6 +272,27 @@ describe('UploadFileListCell', () => {
'dnb-upload__file-cell--error'
)
})

it('executes onClick event when button is clicked', () => {
const onClick = jest.fn()

render(
<UploadFileListCell
{...defaultProps}
uploadFile={{
file: createMockFile('file.png', 100, 'image/png'),
}}
onClick={onClick}
/>
)
const element = document.querySelector(
'.dnb-upload__file-cell button'
)

fireEvent.click(element)

expect(onClick).toHaveBeenCalledTimes(1)
})
})

describe('Delete Button', () => {
Expand Down Expand Up @@ -322,6 +343,25 @@ describe('UploadFileListCell', () => {
).toBeInTheDocument()
})

it('executes onDelete event when delete button is clicked', () => {
const onDelete = jest.fn()

render(
<UploadFileListCell
{...defaultProps}
uploadFile={{
file: createMockFile('file.png', 100, 'image/png'),
}}
onDelete={onDelete}
/>
)
const element = screen.getByRole('button')

fireEvent.click(element)

expect(onDelete).toHaveBeenCalledTimes(1)
})

it('renders the delete button as disabled when loading state', () => {
render(
<UploadFileListCell
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/dnb-eufemia/src/components/upload/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export type UploadProps = {
fileItem: UploadFile
}) => void | Promise<void>

/**
* Will be called once a file gets clicked on by the user. Access the clicked file with `{ fileItem }`.
*/
onFileClick?: ({ fileItem }: { fileItem: UploadFile }) => void

/**
* Causes the browser to treat all listed files as downloadable instead of opening them in a new browser tab or window.
* Default: false
Expand Down
Loading