Improve CMS media uploads and admin styling
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
|
||||
const MAX_FILES_PER_UPLOAD = 100;
|
||||
|
||||
/** Keeps Payload's native multi-file picker from accepting an unbounded batch. */
|
||||
export function UploadLimitGuard() {
|
||||
useEffect(() => {
|
||||
const attached = new WeakSet<HTMLInputElement>();
|
||||
|
||||
const limitedTransfer = (files: FileList) => {
|
||||
const transfer = new DataTransfer();
|
||||
Array.from(files)
|
||||
.slice(0, MAX_FILES_PER_UPLOAD)
|
||||
.forEach((file) => transfer.items.add(file));
|
||||
return transfer;
|
||||
};
|
||||
|
||||
const attachToFileInputs = () => {
|
||||
document.querySelectorAll<HTMLInputElement>('input[type="file"][multiple]').forEach((input) => {
|
||||
if (attached.has(input)) return;
|
||||
attached.add(input);
|
||||
input.addEventListener("change", () => {
|
||||
if (!input.files || input.files.length <= MAX_FILES_PER_UPLOAD) return;
|
||||
|
||||
try {
|
||||
input.files = limitedTransfer(input.files).files;
|
||||
} catch {
|
||||
// Older browsers can expose a read-only FileList. Payload still
|
||||
// receives the original selection there and can process it.
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const limitDroppedFiles = (event: DragEvent) => {
|
||||
const files = event.dataTransfer?.files;
|
||||
if (!files || files.length <= MAX_FILES_PER_UPLOAD || !(event.target instanceof Element)) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
try {
|
||||
event.target.dispatchEvent(
|
||||
new DragEvent("drop", {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
dataTransfer: limitedTransfer(files),
|
||||
}),
|
||||
);
|
||||
} catch {
|
||||
// If a browser cannot construct a replacement drag event, the native
|
||||
// picker still enforces the same limit for normal file selection.
|
||||
}
|
||||
};
|
||||
|
||||
attachToFileInputs();
|
||||
document.addEventListener("drop", limitDroppedFiles, true);
|
||||
const observer = new MutationObserver(attachToFileInputs);
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
return () => {
|
||||
document.removeEventListener("drop", limitDroppedFiles, true);
|
||||
observer.disconnect();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user