@clxrity/zip
Version:
A React zip utility library
145 lines (143 loc) • 3.82 kB
JavaScript
// src/client/unzip.ts
import JSZip from "jszip";
async function unzipFileClient(blob, options) {
const zip = await JSZip.loadAsync(blob);
const files = [];
await Promise.all(
Object.entries(zip.files).map(async ([name, entry]) => {
if (!entry.dir) {
const content = await entry.async("blob");
const file = new File([content], name);
if (options?.onEachFile) {
await options.onEachFile(file);
}
files.push(file);
}
})
);
if (options?.onComplete) {
await options.onComplete(files);
}
return files;
}
// src/client/zip.ts
import JSZip2 from "jszip";
async function zipFilesClient(files, options) {
const zip = new JSZip2();
const processedFiles = options?.onBeforeZip ? await options.onBeforeZip(files) : files ?? [];
for (const file of processedFiles) {
zip.file(file.name, file);
}
const zipBlob = await zip.generateAsync({ type: "blob" });
if (options?.onAfterZip) {
await options.onAfterZip(zipBlob);
}
return zipBlob;
}
// src/client/components/FileUpload.tsx
import { useCallback, useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
function FileUpload({
mode = "zip",
onBeforeZip = void 0,
onAfterZip = void 0,
onEachUnzippedFile = void 0,
onUnzipComplete = void 0,
onError = void 0,
...props
}) {
const [status, setStatus] = useState(null);
const inputRef = useRef(null);
const handleClick = () => {
inputRef.current?.click();
};
const handleFiles = useCallback(
async (files) => {
if (!files || files.length === 0) return;
try {
setStatus("Processing...");
const fileArray = Array.from(files);
if (mode === "zip") {
await zipFilesClient(fileArray, {
onBeforeZip,
onAfterZip
});
setStatus("Files zipped successfully");
} else {
const zipFile = fileArray[0];
if (zipFile?.type !== "application/zip") {
setStatus("Error: Invalid zip file");
throw new Error(
"Please upload a valid zip file"
);
}
await unzipFileClient(zipFile, {
onEachFile: onEachUnzippedFile,
onComplete: onUnzipComplete
});
setStatus("Files unzipped successfully");
}
} catch (e) {
setStatus("Error processing files");
if (onError) onError(e);
else console.error(e);
}
},
[
mode,
onBeforeZip,
onAfterZip,
onEachUnzippedFile,
onUnzipComplete,
onError
]
);
return /* @__PURE__ */ jsxs(
"div",
{
onClick: handleClick,
style: {
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "10px",
padding: "20px",
border: "1px dashed #aaa",
borderRadius: "5px",
cursor: "pointer"
},
children: [
/* @__PURE__ */ jsx(
"input",
{
"data-testid": "file-input",
type: "file",
multiple: mode === "zip",
accept: mode === "unzip" ? ".zip" : void 0,
onChange: (e) => {
handleFiles(e.target.files);
props.onChange?.(e);
},
onClick: (e) => {
e.currentTarget.value = "";
},
style: {
display: "none",
...props.style
},
id: "file-upload-input",
ref: inputRef,
...props
}
),
status && /* @__PURE__ */ jsx("p", { "data-testid": "file-upload-status", children: status })
]
}
);
}
export {
FileUpload,
unzipFileClient,
zipFilesClient
};
//# sourceMappingURL=index.js.map