fanyucomponents
Version:
一款以 純邏輯為核心、無樣式綁定 的 React 元件套件
40 lines (39 loc) • 1.72 kB
JavaScript
import { jsxs as _jsxs } from "react/jsx-runtime";
import { useState } from "react";
export const DownloadButton = (props) => {
const { children, style, rel, icon, iconPosition = "left", // 預設為左側
fileName, fileUrl, ...rest } = props;
const [loading, setLoading] = useState(false);
const handleClick = async (e) => {
if (fileName && !fileUrl.startsWith("blob:")) {
e.preventDefault();
try {
setLoading(true);
const res = await fetch(fileUrl);
const blob = await res.blob();
const url = URL.createObjectURL(blob);
const tempLink = document.createElement("a");
tempLink.href = url;
tempLink.download = fileName;
tempLink.click();
URL.revokeObjectURL(url);
}
catch (err) {
console.error("下載失敗", err);
}
finally {
setLoading(false);
}
}
};
return (_jsxs("a", { download: fileName, href: fileUrl, onClick: handleClick, style: {
display: "inline-flex", // 為了水平排列 icon 和文字
alignItems: "center",
gap: "0.5em",
cursor: loading ? "not-allowed" : "pointer",
opacity: loading ? 0.6 : 1,
pointerEvents: loading ? "none" : "auto",
...style,
}, rel: rel !== null && rel !== void 0 ? rel : "noopener noreferrer", ...rest, children: [icon && iconPosition === "left" && icon, loading ? "下載中..." : children, icon && iconPosition === "right" && icon] }));
};
DownloadButton.displayName = "DownloadButton";