Skip to content

Commit 18082bb

Browse files
authored
fix: Portal frontend 40 (#78)
* fix: download file button * fix: download csv file * Merge branch 'main' into portal-frontend-40
1 parent f0596b1 commit 18082bb

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/components/DownloadFileButton.tsx

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Button, type ButtonProps } from "@mui/material"
2+
import { type FC, useEffect } from "react"
3+
import { Download as DownloadIcon } from "@mui/icons-material"
4+
5+
export type DownloadFileButtonProps = ButtonProps & {
6+
file:
7+
| Blob
8+
| MediaSource
9+
| {
10+
text: string
11+
mimeType: "plain" | "csv"
12+
name: string
13+
charset?: string
14+
extension?: string
15+
}
16+
}
17+
18+
const DownloadFileButton: FC<DownloadFileButtonProps> = ({
19+
children = "Download",
20+
endIcon = <DownloadIcon />,
21+
file,
22+
...otherButtonProps
23+
}) => {
24+
let url: undefined | string = undefined
25+
let anchorProps: undefined | { download?: string; href: string } = undefined
26+
if ("mimeType" in file) {
27+
let { text, mimeType, name, charset = "utf-8", extension } = file
28+
29+
if (!extension) extension = "." + { plain: "txt", csv: "csv" }[mimeType]
30+
31+
anchorProps = {
32+
download: name + extension,
33+
href: `data:text/${mimeType};charset=${charset},${encodeURIComponent(text)}`,
34+
}
35+
} else {
36+
url = URL.createObjectURL(file)
37+
38+
anchorProps = { href: url }
39+
}
40+
41+
useEffect(() => {
42+
return () => {
43+
if (url) URL.revokeObjectURL(url)
44+
}
45+
}, [url])
46+
47+
return (
48+
<Button endIcon={endIcon} {...otherButtonProps} {...anchorProps}>
49+
{children}
50+
</Button>
51+
)
52+
}
53+
54+
export default DownloadFileButton

src/components/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export * from "./CopyIconButton"
66
export { default as CopyIconButton } from "./CopyIconButton"
77
export * from "./Countdown"
88
export { default as Countdown } from "./Countdown"
9+
export * from "./DownloadFileButton"
10+
export { default as DownloadFileButton } from "./DownloadFileButton"
911
export * from "./ElevatedAppBar"
1012
export { default as ElevatedAppBar } from "./ElevatedAppBar"
1113
export * from "./Image"

0 commit comments

Comments
 (0)