@zag-js/file-upload
Version:
Core logic for the file-upload widget implemented as a state machine
99 lines (97 loc) • 3.87 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/file-upload.utils.ts
var file_upload_utils_exports = {};
__export(file_upload_utils_exports, {
getEventFiles: () => getEventFiles,
isEventWithFiles: () => isEventWithFiles,
isFilesWithinRange: () => isFilesWithinRange,
setInputFiles: () => setInputFiles
});
module.exports = __toCommonJS(file_upload_utils_exports);
var import_dom_query = require("@zag-js/dom-query");
var import_file_utils = require("@zag-js/file-utils");
function isEventWithFiles(event) {
const target = (0, import_dom_query.getEventTarget)(event);
if (!event.dataTransfer) return !!target && "files" in target;
return event.dataTransfer.types.some((type) => {
return type === "Files" || type === "application/x-moz-file";
});
}
function isFilesWithinRange(ctx, incomingCount, currentAcceptedFiles) {
const { prop, computed } = ctx;
if (!computed("multiple") && incomingCount > 1) return false;
if (!computed("multiple") && incomingCount + currentAcceptedFiles.length === 2) return true;
if (incomingCount + currentAcceptedFiles.length > prop("maxFiles")) return false;
return true;
}
function getEventFiles(ctx, files, currentAcceptedFiles = [], currentRejectedFiles = []) {
const { prop, computed } = ctx;
const acceptedFiles = [];
const rejectedFiles = [];
const validateParams = {
acceptedFiles: currentAcceptedFiles,
rejectedFiles: currentRejectedFiles
};
files.forEach((file) => {
const [accepted, acceptError] = (0, import_file_utils.isValidFileType)(file, computed("acceptAttr"));
const [sizeMatch, sizeError] = (0, import_file_utils.isValidFileSize)(file, prop("minFileSize"), prop("maxFileSize"));
const isDuplicate = currentAcceptedFiles.some((f) => (0, import_file_utils.isFileEqual)(f, file)) || acceptedFiles.some((f) => (0, import_file_utils.isFileEqual)(f, file));
const validateErrors = prop("validate")?.(file, validateParams);
const valid = validateErrors ? validateErrors.length === 0 : true;
if (accepted && sizeMatch && valid && !isDuplicate) {
acceptedFiles.push(file);
} else {
const errors = [acceptError, sizeError];
if (isDuplicate) errors.push("FILE_EXISTS");
if (!valid) errors.push(...validateErrors ?? []);
rejectedFiles.push({ file, errors: errors.filter(Boolean) });
}
});
if (!isFilesWithinRange(ctx, acceptedFiles.length, currentAcceptedFiles)) {
acceptedFiles.forEach((file) => {
rejectedFiles.push({ file, errors: ["TOO_MANY_FILES"] });
});
acceptedFiles.splice(0);
}
return {
acceptedFiles,
rejectedFiles
};
}
function setInputFiles(inputEl, files) {
const win = (0, import_dom_query.getWindow)(inputEl);
try {
if ("DataTransfer" in win) {
const dataTransfer = new win.DataTransfer();
files.forEach((file) => {
dataTransfer.items.add(file);
});
inputEl.files = dataTransfer.files;
}
} catch {
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
getEventFiles,
isEventWithFiles,
isFilesWithinRange,
setInputFiles
});