yet-another-react-lightbox
Version:
Modern React lightbox component
116 lines (110 loc) • 4.12 kB
JavaScript
import * as React from 'react';
import { createIcon, useLightboxProps, useLightboxState, isImageSlide, IconButton, addToolbarButton } from '../../index.js';
import { PLUGIN_DOWNLOAD } from '../../types.js';
const defaultDownloadProps = {
download: undefined,
};
const resolveDownloadProps = (download) => ({
...defaultDownloadProps,
...download,
});
function download(url, name) {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "blob";
xhr.onload = () => {
saveAs(xhr.response, name);
};
xhr.onerror = () => {
console.error("Failed to download file");
};
xhr.send();
}
function corsEnabled(url) {
const xhr = new XMLHttpRequest();
xhr.open("HEAD", url, false);
try {
xhr.send();
}
catch (_) {
}
return xhr.status >= 200 && xhr.status <= 299;
}
function click(link) {
try {
link.dispatchEvent(new MouseEvent("click"));
}
catch (_) {
const event = document.createEvent("MouseEvents");
event.initMouseEvent("click", true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
link.dispatchEvent(event);
}
}
function saveAs(source, name) {
const link = document.createElement("a");
link.rel = "noopener";
link.download = name || "";
if (!link.download) {
link.target = "_blank";
}
if (typeof source === "string") {
link.href = source;
if (link.origin !== window.location.origin) {
if (corsEnabled(link.href)) {
download(source, name);
}
else {
link.target = "_blank";
click(link);
}
}
else {
click(link);
}
}
else {
link.href = URL.createObjectURL(source);
setTimeout(() => URL.revokeObjectURL(link.href), 30000);
setTimeout(() => click(link), 0);
}
}
const DownloadIcon = createIcon("DownloadIcon", React.createElement("path", { d: "M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zm-1-4-1.41-1.41L13 12.17V4h-2v8.17L8.41 9.59 7 11l5 5 5-5z" }));
function DownloadButton() {
const { render, on, download: downloadProps } = useLightboxProps();
const { download: customDownload } = resolveDownloadProps(downloadProps);
const { currentSlide, currentIndex } = useLightboxState();
if (render.buttonDownload) {
return React.createElement(React.Fragment, null, render.buttonDownload());
}
const downloadUrl = (currentSlide &&
(currentSlide.downloadUrl ||
(typeof currentSlide.download === "string" && currentSlide.download) ||
(typeof currentSlide.download === "object" && currentSlide.download.url) ||
(isImageSlide(currentSlide) && currentSlide.src))) ||
undefined;
const canDownload = customDownload ? (currentSlide === null || currentSlide === void 0 ? void 0 : currentSlide.download) !== false : Boolean(downloadUrl);
const defaultDownload = () => {
if (currentSlide && downloadUrl) {
const downloadFilename = currentSlide.downloadFilename ||
(typeof currentSlide.download === "object" && currentSlide.download.filename) ||
undefined;
saveAs(downloadUrl, downloadFilename);
}
};
const handleDownload = () => {
var _a;
if (currentSlide) {
(customDownload || defaultDownload)({ slide: currentSlide, saveAs });
(_a = on.download) === null || _a === void 0 ? void 0 : _a.call(on, { index: currentIndex });
}
};
return (React.createElement(IconButton, { label: "Download", icon: DownloadIcon, renderIcon: render.iconDownload, disabled: !canDownload, onClick: handleDownload }));
}
function Download({ augment }) {
augment(({ toolbar, download, ...restProps }) => ({
toolbar: addToolbarButton(toolbar, PLUGIN_DOWNLOAD, React.createElement(DownloadButton, null)),
download: resolveDownloadProps(download),
...restProps,
}));
}
export { Download as default };