@builtwithjavascript/vue-file-upload
Advanced tools
@@ -10,3 +10,5 @@ import type { IFileInfo } from '@builtwithjavascript/file-input-validator'; | ||
| } | ||
| declare const _default: import("vue").DefineComponent<IFileInputProps, { | ||
| declare const _default: typeof __VLS_export; | ||
| export default _default; | ||
| declare const __VLS_export: import("vue").DefineComponent<IFileInputProps, { | ||
| resetInputFile: () => any; | ||
@@ -22,2 +24,1 @@ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & { | ||
| }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>; | ||
| export default _default; |
@@ -15,7 +15,7 @@ import type { IFileInfo, IFileValidatorOptions } from '@builtwithjavascript/file-input-validator'; | ||
| } | ||
| declare var __VLS_14: {}; | ||
| declare var __VLS_15: {}; | ||
| type __VLS_Slots = {} & { | ||
| default?: (props: typeof __VLS_14) => any; | ||
| default?: (props: typeof __VLS_15) => any; | ||
| }; | ||
| declare const __VLS_component: import("vue").DefineComponent<IFileUploadProps, { | ||
| declare const __VLS_base: import("vue").DefineComponent<IFileUploadProps, { | ||
| reset: () => any; | ||
@@ -38,3 +38,4 @@ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & { | ||
| }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>; | ||
| declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>; | ||
| declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>; | ||
| declare const _default: typeof __VLS_export; | ||
| export default _default; | ||
@@ -41,0 +42,0 @@ type __VLS_WithSlots<T, S> = T & { |
@@ -12,3 +12,3 @@ import type { IFileInfo, IFileValidatorItem } from '@builtwithjavascript/file-input-validator'; | ||
| } | ||
| declare const _default: import("vue").DefineComponent<IProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<IProps> & Readonly<{}>, { | ||
| declare const __VLS_export: import("vue").DefineComponent<IProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<IProps> & Readonly<{}>, { | ||
| roundedCorners: boolean; | ||
@@ -20,2 +20,3 @@ validatorRowCssClass: string; | ||
| }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>; | ||
| declare const _default: typeof __VLS_export; | ||
| export default _default; |
@@ -12,3 +12,3 @@ import { IFileValidatorItem } from '@builtwithjavascript/file-input-validator'; | ||
| } | ||
| declare const _default: import("vue").DefineComponent<IProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<IProps> & Readonly<{}>, { | ||
| declare const __VLS_export: import("vue").DefineComponent<IProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<IProps> & Readonly<{}>, { | ||
| id: string; | ||
@@ -20,2 +20,3 @@ roundedCorners: boolean; | ||
| }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>; | ||
| declare const _default: typeof __VLS_export; | ||
| export default _default; |
+373
-359
@@ -1,360 +0,374 @@ | ||
| import { defineComponent as g, ref as b, computed as v, createElementBlock as C, openBlock as p, normalizeClass as f, createElementVNode as c, toDisplayString as y, normalizeStyle as F, withDirectives as w, createCommentVNode as B, vShow as I, Fragment as k, renderList as S, createBlock as L, reactive as N, createVNode as V, renderSlot as O } from "vue"; | ||
| const M = [ | ||
| { | ||
| key: "name", | ||
| name: "Name", | ||
| value: "", | ||
| displayValue: "", | ||
| hasError: !1, | ||
| iconSuccess: "", | ||
| //IconConstants.IconSuccess, | ||
| iconError: "" | ||
| //IconConstants.IconError | ||
| }, | ||
| { | ||
| key: "type", | ||
| name: "Type", | ||
| value: "", | ||
| displayValue: "", | ||
| hasError: !1, | ||
| iconSuccess: "", | ||
| //IconConstants.IconSuccess, | ||
| iconError: "" | ||
| //IconConstants.IconError | ||
| }, | ||
| { | ||
| key: "size", | ||
| name: "Size", | ||
| value: "", | ||
| displayValue: "", | ||
| hasError: !1, | ||
| iconSuccess: "", | ||
| //IconConstants.IconSuccess, | ||
| iconError: "" | ||
| //IconConstants.IconError | ||
| } | ||
| ], z = { | ||
| allowedTypes: ["csv"], | ||
| propertiesToValidate: ["name", "type", "size"], | ||
| maxSize: 50, | ||
| maxNameLength: 75, | ||
| nameTruncateMaxLength: 35 | ||
| }, R = (l) => { | ||
| const e = (l || "").split("."); | ||
| return e && e.length > 1 ? (e[e.length - 1] || "").trim().toLowerCase() : ""; | ||
| }, _ = (l, e, t) => { | ||
| const a = e.file; | ||
| if (!a) | ||
| return; | ||
| const s = t.find((o) => o.name.toLowerCase() === "lastmodified"); | ||
| s && (e.lastModified = a.lastModifiedDate, s.hasError = !1, s.value = e.lastModified, s.displayValue = e.lastModified); | ||
| }, x = (l, e = 2) => { | ||
| if (l === 0) | ||
| return "0 Bytes"; | ||
| const t = 1024, a = e < 0 ? 0 : e, s = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], o = Math.floor(Math.log(l) / Math.log(t)); | ||
| return parseFloat((l / Math.pow(t, o)).toFixed(a)) + " " + s[o]; | ||
| }, m = (l, e) => { | ||
| l.isValid = !1; | ||
| const t = (e || "").trim(); | ||
| return t.length > 0 ? l.message = t : l.message = "", l; | ||
| }, $ = { | ||
| name: (l, e, t) => { | ||
| const a = e.file, s = t.find((n) => n.name.toLowerCase() === "name"); | ||
| if (!s) { | ||
| console.warn('name strrategy: could not find "name" validator item'); | ||
| return; | ||
| } | ||
| const o = l.nameTruncateMaxLength, i = " ...", r = (a?.name || "").trim(); | ||
| if (s.value = r, r.length < o) | ||
| s.displayValue = r; | ||
| else { | ||
| const n = r.substring(0, 13), d = r.split("").reverse().join("").substring(0, 13).split("").reverse().join(""); | ||
| s.displayValue = `${n} ${i} ${d}`; | ||
| } | ||
| if (e.name = s.value, e.displayName = s.displayValue, r.length > l.maxNameLength) { | ||
| const n = `max length allowed is ${l.maxNameLength.toString()} chars`; | ||
| s.hasError = !0, s.displayValue = `File name is too long - ${n}`, m(e); | ||
| } else | ||
| e.message = e.name, s.hasError = !1; | ||
| }, | ||
| type: (l, e, t) => { | ||
| const a = e.file; | ||
| if (!a) | ||
| return; | ||
| const s = l.allowedTypes || []; | ||
| if (s.length === 0) { | ||
| m(e, "No allowed file types have been specified by the developer"); | ||
| return; | ||
| } | ||
| if (s.indexOf("*") > -1) | ||
| return; | ||
| const o = t.find((n) => n.name.toLowerCase() === "type"); | ||
| if (!o) | ||
| return; | ||
| let i = ""; | ||
| s.length > 1 ? i = `file must be one of these types: ${s.join(",")}` : i = `file type must be ${s[0]}`; | ||
| const r = R(a.name); | ||
| r ? s.indexOf(r) > -1 ? (o.hasError = !1, o.value = a.type, o.displayValue = r) : (o.hasError = !0, o.value = a.type || "unknown", o.displayValue = `${r} - ${i}`, m(e)) : (o.hasError = !0, o.value = a.type || "unknown", o.displayValue = `${o.value} - ${i}`, m(e)); | ||
| }, | ||
| size: (l, e, t) => { | ||
| const a = e.file; | ||
| if (!a) | ||
| return; | ||
| const s = t.find((n) => n.name.toLowerCase() === "size"); | ||
| if (!s) | ||
| return; | ||
| const o = 1024e3, i = a.size, r = o * l.maxSize; | ||
| if (s.value = `${i} bytes`, s.displayValue = x(i), i > r) { | ||
| const n = `max upload size is ${l.maxSize.toString()} MB`; | ||
| s.hasError = !0, s.displayValue = `${s.displayValue} - ${n}`, m(e); | ||
| } else | ||
| s.hasError = !1; | ||
| }, | ||
| datemodified: (l, e, t) => { | ||
| _(l, e, t); | ||
| }, | ||
| lastmodified: (l, e, t) => { | ||
| _(l, e, t); | ||
| } | ||
| }; | ||
| class T { | ||
| options; | ||
| enabledValidatorItems = []; | ||
| constructor(e) { | ||
| this.options = { ...z, ...e || {} }, this.enabledValidatorItems = M.filter((t) => this.options.allowedTypes.indexOf(t.key)); | ||
| } | ||
| get validatorItems() { | ||
| const e = (this.options.propertiesToValidate || []).map((t) => t.toLowerCase()); | ||
| return e.length > 0 ? this.enabledValidatorItems.filter( | ||
| (t) => e.indexOf(t.name.toLowerCase()) > -1 | ||
| ) : []; | ||
| } | ||
| validateFile(e) { | ||
| if (e.file) { | ||
| e.isValid = !0; | ||
| const t = this.options.propertiesToValidate || []; | ||
| t.length > 0 && t.forEach((a) => { | ||
| const s = a.toLowerCase(); | ||
| if (Object.prototype.hasOwnProperty.call($, s)) { | ||
| const o = $[s]; | ||
| o(this.options, e, this.enabledValidatorItems); | ||
| } else | ||
| console.warn("FileValidator: Warning: could not find validator for property", s); | ||
| }); | ||
| } else | ||
| m(e, "No file has been selected"); | ||
| return this.validatorItems; | ||
| } | ||
| } | ||
| const j = (l) => new T(l), W = ["id", "data-testid", "aria-disabled", "for"], D = ["id", "disabled"], U = g({ | ||
| name: "FileInputComponent" | ||
| }), P = /* @__PURE__ */ g({ | ||
| ...U, | ||
| props: { | ||
| id: {}, | ||
| disabled: { type: Boolean, default: !1 }, | ||
| model: {}, | ||
| validator: {}, | ||
| inputWrapperCssClass: { default: "" }, | ||
| inputCssClass: { default: "" } | ||
| }, | ||
| emits: ["changed"], | ||
| setup(l, { expose: e, emit: t }) { | ||
| const a = l, s = t, o = b(), i = v(() => { | ||
| const d = [ | ||
| //'cursor-pointer w-full flex flex-col space-y-2 p-2 overflow-hidden overflow-ellipsis whitespace-nowrap' | ||
| ]; | ||
| return a.disabled && d.push("disabled"), d.push(`${a.inputWrapperCssClass}`), d.join(" ").trim(); | ||
| }); | ||
| e({ | ||
| resetInputFile: () => { | ||
| const d = o.value; | ||
| d && (d.value = ""); | ||
| } | ||
| }); | ||
| const n = (d) => { | ||
| const u = d.target; | ||
| u.files && u.files.length > 0 ? a.model.file = u.files.item(0) : a.model.file = null, a.model.fileSelected = !!a.model.file, s("changed", a.model); | ||
| }; | ||
| return (d, u) => (p(), C("label", { | ||
| class: f(i.value), | ||
| id: `${a.id}-input-wrapper`, | ||
| "data-testid": a.id, | ||
| "aria-disabled": a.disabled, | ||
| for: `${a.id}-input` | ||
| }, [ | ||
| c("input", { | ||
| ref_key: "refInputFile", | ||
| ref: o, | ||
| type: "file", | ||
| id: `${a.id}-input`, | ||
| disabled: a.disabled, | ||
| class: f(a.inputCssClass || ""), | ||
| onChange: n | ||
| }, null, 42, D) | ||
| ], 10, W)); | ||
| } | ||
| }), G = ["title", "id", "data-testid"], K = { | ||
| class: /* @__PURE__ */ f("property-name"), | ||
| style: { flex: "none", width: "5rem" } | ||
| }, Y = /* @__PURE__ */ g({ | ||
| __name: "FileValidatorRow.component", | ||
| props: { | ||
| id: { default: "not-set" }, | ||
| index: {}, | ||
| totItemsCount: {}, | ||
| roundedCorners: { type: Boolean, default: !1 }, | ||
| model: {}, | ||
| validatorRowCssClass: { default: "" }, | ||
| successClass: { default: "success" }, | ||
| errorClass: { default: "error" } | ||
| }, | ||
| setup(l) { | ||
| const e = l, t = v(() => { | ||
| const { model: a } = e, s = a?.hasError || !1, o = ["file-validator-item"]; | ||
| return o.push(`${e.validatorRowCssClass || ""}`), o.push(s ? e.errorClass : e.successClass), o.join(" ").trim(); | ||
| }); | ||
| return (a, s) => (p(), C("div", { | ||
| class: f(t.value), | ||
| title: a.model.value, | ||
| id: e.id, | ||
| "data-testid": e.id | ||
| }, [ | ||
| c("span", K, y(a.model.name), 1), | ||
| c("span", { | ||
| class: f(`property-value ${a.model.hasError ? "error" : ""}`), | ||
| style: F(`flex: 0 1 auto;${a.model.hasError ? "" : "overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"}`) | ||
| }, y(a.model.displayValue), 7) | ||
| ], 10, G)); | ||
| } | ||
| }), Z = ["data-testid"], q = { style: {} }, A = ["title"], H = { | ||
| key: 0, | ||
| class: "file-validator-inner" | ||
| }, J = /* @__PURE__ */ g({ | ||
| __name: "FileValidator.component", | ||
| props: { | ||
| id: {}, | ||
| model: {}, | ||
| showOnlyErrors: { type: Boolean, default: !0 }, | ||
| roundedCorners: { type: Boolean, default: !1 }, | ||
| validatorItems: {}, | ||
| successClass: { default: "success bg-success content-success" }, | ||
| errorClass: { default: "error bg-danger content-danger" }, | ||
| validatorRowCssClass: { default: "" } | ||
| }, | ||
| setup(l) { | ||
| const e = l, t = v(() => e.validatorItems.filter((s) => !e.showOnlyErrors || s.hasError)), a = v(() => { | ||
| const s = [ | ||
| //`file-validator-item px-4 py-2 flex items-center text-white` | ||
| "file-validator-item" | ||
| ]; | ||
| return s.push(`${e.model?.isValid ? e.successClass : e.errorClass}`), s.join(" ").trim(); | ||
| }); | ||
| return (s, o) => w((p(), C("div", { | ||
| "data-testid": e.id, | ||
| class: "file-validator" | ||
| }, [ | ||
| w(c("div", { | ||
| class: f(a.value) | ||
| }, [ | ||
| c("span", q, y(s.model.isValid ? "File:" : "Error:"), 1), | ||
| c("span", { | ||
| class: "", | ||
| title: s.model.isValid ? s.model.displayName : s.model.message | ||
| }, y(s.model.isValid ? s.model.displayName : s.model.message), 9, A) | ||
| ], 2), [ | ||
| [I, s.model.message] | ||
| ]), | ||
| s.model.message ? B("", !0) : (p(), C("div", H, [ | ||
| (p(!0), C(k, null, S(t.value, (i, r) => (p(), L(Y, { | ||
| id: `${e.id}-file-validator-row_${i.key}`, | ||
| key: `file-validator-row-${i.key}`, | ||
| index: r, | ||
| totItemsCount: t.value.length, | ||
| roundedCorners: s.roundedCorners, | ||
| model: i, | ||
| successClass: e.successClass, | ||
| errorClass: e.errorClass, | ||
| validatorRowCssClass: e.validatorRowCssClass | ||
| }, null, 8, ["id", "index", "totItemsCount", "roundedCorners", "model", "successClass", "errorClass", "validatorRowCssClass"]))), 128)) | ||
| ])) | ||
| ], 8, Z)), [ | ||
| [I, s.model.displayName.length > 0] | ||
| ]); | ||
| } | ||
| }), Q = { className: "w-full space-y-2" }, X = ["disabled"], le = /* @__PURE__ */ g({ | ||
| __name: "FileUpload.component", | ||
| props: { | ||
| id: {}, | ||
| disabled: { type: Boolean, default: !1 }, | ||
| uploadLabel: {}, | ||
| validatorOptions: {}, | ||
| showOnlyErrors: { type: Boolean, default: !1 }, | ||
| roundedCorners: { type: Boolean, default: !1 }, | ||
| successClass: { default: "success" }, | ||
| errorClass: { default: "error" }, | ||
| inputCssClass: {}, | ||
| inputWrapperCssClass: { default: "" }, | ||
| validatorRowCssClass: {} | ||
| }, | ||
| emits: ["fileSelectionChanged", "uploadClicked", "update:valid"], | ||
| setup(l, { expose: e, emit: t }) { | ||
| const a = l, s = t, o = b(), i = () => ({ | ||
| file: null, | ||
| lastModified: "", | ||
| fileSelected: !1, | ||
| isValid: !1, | ||
| name: "", | ||
| displayName: "", | ||
| message: "" | ||
| }), r = N({ | ||
| fileInfo: i(), | ||
| validatorItems: [] | ||
| }), n = v(() => r.fileInfo.file ? r.validatorItems.some((h) => h.hasError) : !0), d = j(a.validatorOptions), u = (h) => { | ||
| r.fileInfo = h, r.validatorItems = d.validateFile(r.fileInfo), console.log("___ fileSelectionChanged", r.fileInfo, r.validatorItems), s("fileSelectionChanged", r.fileInfo), s("update:valid", n.value); | ||
| }, E = async () => { | ||
| console.log("___ onUploadClick", r.fileInfo?.file), s("uploadClicked", r.fileInfo); | ||
| }; | ||
| return e({ | ||
| reset: () => { | ||
| o.value?.resetInputFile(), u(i()); | ||
| } | ||
| }), (h, se) => (p(), C("div", Q, [ | ||
| V(P, { | ||
| ref_key: "refFileInputComp", | ||
| ref: o, | ||
| id: a.id, | ||
| disabled: a.disabled, | ||
| model: r.fileInfo, | ||
| inputWrapperCssClass: a.inputWrapperCssClass, | ||
| inputCssClass: a.inputCssClass, | ||
| onChanged: u | ||
| }, null, 8, ["id", "disabled", "model", "inputWrapperCssClass", "inputCssClass"]), | ||
| V(J, { | ||
| model: r.fileInfo, | ||
| id: `${a.id}-validator`, | ||
| validatorItems: r.validatorItems, | ||
| showOnlyErrors: a.showOnlyErrors, | ||
| roundedCorners: a.roundedCorners, | ||
| successClass: a.successClass, | ||
| errorClass: a.errorClass, | ||
| validatorRowCssClass: a.validatorRowCssClass | ||
| }, null, 8, ["model", "id", "validatorItems", "showOnlyErrors", "roundedCorners", "successClass", "errorClass", "validatorRowCssClass"]), | ||
| O(h.$slots, "default", {}, () => [ | ||
| c("button", { | ||
| onClick: E, | ||
| disabled: n.value, | ||
| class: f(`p-2 rounded-md ${n.value ? "bg-gray-400" : "bg-blue-500"} color-white`) | ||
| }, y(a.uploadLabel), 11, X) | ||
| ]) | ||
| ])); | ||
| } | ||
| import { Fragment as e, computed as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createVNode as o, defineComponent as s, normalizeClass as c, normalizeStyle as l, openBlock as u, reactive as d, ref as f, renderList as p, renderSlot as m, toDisplayString as h, vShow as g, withDirectives as _ } from "vue"; | ||
| //#region node_modules/@builtwithjavascript/file-input-validator/dist/file-input-validator.es.js | ||
| var v = [ | ||
| { | ||
| key: "name", | ||
| name: "Name", | ||
| value: "", | ||
| displayValue: "", | ||
| hasError: !1, | ||
| iconSuccess: "", | ||
| iconError: "" | ||
| }, | ||
| { | ||
| key: "type", | ||
| name: "Type", | ||
| value: "", | ||
| displayValue: "", | ||
| hasError: !1, | ||
| iconSuccess: "", | ||
| iconError: "" | ||
| }, | ||
| { | ||
| key: "size", | ||
| name: "Size", | ||
| value: "", | ||
| displayValue: "", | ||
| hasError: !1, | ||
| iconSuccess: "", | ||
| iconError: "" | ||
| } | ||
| ], y = { | ||
| allowedTypes: ["csv"], | ||
| propertiesToValidate: [ | ||
| "name", | ||
| "type", | ||
| "size" | ||
| ], | ||
| maxSize: 50, | ||
| maxNameLength: 75, | ||
| nameTruncateMaxLength: 35 | ||
| }, b = (e) => { | ||
| let t = (e || "").split("."); | ||
| return t && t.length > 1 ? (t[t.length - 1] || "").trim().toLowerCase() : ""; | ||
| }, x = (e, t, n) => { | ||
| let r = t.file; | ||
| if (!r) return; | ||
| let i = n.find((e) => e.name.toLowerCase() === "lastmodified"); | ||
| i && (t.lastModified = r.lastModifiedDate, i.hasError = !1, i.value = t.lastModified, i.displayValue = t.lastModified); | ||
| }, S = (e, t = 2) => { | ||
| if (e === 0) return "0 Bytes"; | ||
| let n = 1024, r = t < 0 ? 0 : t, i = [ | ||
| "Bytes", | ||
| "KB", | ||
| "MB", | ||
| "GB", | ||
| "TB", | ||
| "PB", | ||
| "EB", | ||
| "ZB", | ||
| "YB" | ||
| ], a = Math.floor(Math.log(e) / Math.log(n)); | ||
| return parseFloat((e / n ** +a).toFixed(r)) + " " + i[a]; | ||
| }, C = (e, t) => { | ||
| e.isValid = !1; | ||
| let n = (t || "").trim(); | ||
| return n.length > 0 ? e.message = n : e.message = "", e; | ||
| }, w = { | ||
| name: (e, t, n) => { | ||
| let r = t.file, i = n.find((e) => e.name.toLowerCase() === "name"); | ||
| if (!i) { | ||
| console.warn("name strrategy: could not find \"name\" validator item"); | ||
| return; | ||
| } | ||
| let a = e.nameTruncateMaxLength, o = (r?.name || "").trim(); | ||
| if (i.value = o, o.length < a ? i.displayValue = o : i.displayValue = `${o.substring(0, 13)} ... ${o.split("").reverse().join("").substring(0, 13).split("").reverse().join("")}`, t.name = i.value, t.displayName = i.displayValue, o.length > e.maxNameLength) { | ||
| let n = `max length allowed is ${e.maxNameLength.toString()} chars`; | ||
| i.hasError = !0, i.displayValue = `File name is too long - ${n}`, C(t); | ||
| } else t.message = t.name, i.hasError = !1; | ||
| }, | ||
| type: (e, t, n) => { | ||
| let r = t.file; | ||
| if (!r) return; | ||
| let i = e.allowedTypes || []; | ||
| if (i.length === 0) { | ||
| C(t, "No allowed file types have been specified by the developer"); | ||
| return; | ||
| } | ||
| if (i.indexOf("*") > -1) return; | ||
| let a = n.find((e) => e.name.toLowerCase() === "type"); | ||
| if (!a) return; | ||
| let o = ""; | ||
| o = i.length > 1 ? `file must be one of these types: ${i.join(",")}` : `file type must be ${i[0]}`; | ||
| let s = b(r.name); | ||
| s ? i.indexOf(s) > -1 ? (a.hasError = !1, a.value = r.type, a.displayValue = s) : (a.hasError = !0, a.value = r.type || "unknown", a.displayValue = `${s} - ${o}`, C(t)) : (a.hasError = !0, a.value = r.type || "unknown", a.displayValue = `${a.value} - ${o}`, C(t)); | ||
| }, | ||
| size: (e, t, n) => { | ||
| let r = t.file; | ||
| if (!r) return; | ||
| let i = n.find((e) => e.name.toLowerCase() === "size"); | ||
| if (!i) return; | ||
| let a = r.size, o = 1024e3 * e.maxSize; | ||
| if (i.value = `${a} bytes`, i.displayValue = S(a), a > o) { | ||
| let n = `max upload size is ${e.maxSize.toString()} MB`; | ||
| i.hasError = !0, i.displayValue = `${i.displayValue} - ${n}`, C(t); | ||
| } else i.hasError = !1; | ||
| }, | ||
| datemodified: (e, t, n) => { | ||
| x(e, t, n); | ||
| }, | ||
| lastmodified: (e, t, n) => { | ||
| x(e, t, n); | ||
| } | ||
| }, T = class { | ||
| options; | ||
| enabledValidatorItems = []; | ||
| constructor(e) { | ||
| this.options = { | ||
| ...y, | ||
| ...e || {} | ||
| }, this.enabledValidatorItems = v.filter((e) => this.options.allowedTypes.indexOf(e.key)); | ||
| } | ||
| get validatorItems() { | ||
| let e = (this.options.propertiesToValidate || []).map((e) => e.toLowerCase()); | ||
| return e.length > 0 ? this.enabledValidatorItems.filter((t) => e.indexOf(t.name.toLowerCase()) > -1) : []; | ||
| } | ||
| validateFile(e) { | ||
| if (e.file) { | ||
| e.isValid = !0; | ||
| let t = this.options.propertiesToValidate || []; | ||
| t.length > 0 && t.forEach((t) => { | ||
| let n = t.toLowerCase(); | ||
| if (Object.prototype.hasOwnProperty.call(w, n)) { | ||
| let t = w[n]; | ||
| t(this.options, e, this.enabledValidatorItems); | ||
| } else console.warn("FileValidator: Warning: could not find validator for property", n); | ||
| }); | ||
| } else C(e, "No file has been selected"); | ||
| return this.validatorItems; | ||
| } | ||
| }, E = (e) => new T(e), D = [ | ||
| "id", | ||
| "data-testid", | ||
| "aria-disabled", | ||
| "for" | ||
| ], O = ["id", "disabled"], k = /* @__PURE__ */ s({ | ||
| ...s({ name: "FileInputComponent" }), | ||
| props: { | ||
| id: {}, | ||
| disabled: { | ||
| type: Boolean, | ||
| default: !1 | ||
| }, | ||
| model: {}, | ||
| validator: {}, | ||
| inputWrapperCssClass: { default: "" }, | ||
| inputCssClass: { default: "" } | ||
| }, | ||
| emits: ["changed"], | ||
| setup(e, { expose: n, emit: r }) { | ||
| let o = e, s = r, l = f(), d = t(() => { | ||
| let e = []; | ||
| return o.disabled && e.push("disabled"), e.push(`${o.inputWrapperCssClass}`), e.join(" ").trim(); | ||
| }); | ||
| n({ resetInputFile: () => { | ||
| let e = l.value; | ||
| e && (e.value = ""); | ||
| } }); | ||
| let p = (e) => { | ||
| let t = e.target; | ||
| t.files && t.files.length > 0 ? o.model.file = t.files.item(0) : o.model.file = null, o.model.fileSelected = !!o.model.file, s("changed", o.model); | ||
| }; | ||
| return (e, t) => (u(), i("label", { | ||
| class: c(d.value), | ||
| id: `${o.id}-input-wrapper`, | ||
| "data-testid": o.id, | ||
| "aria-disabled": o.disabled, | ||
| for: `${o.id}-input` | ||
| }, [a("input", { | ||
| ref_key: "refInputFile", | ||
| ref: l, | ||
| type: "file", | ||
| id: `${o.id}-input`, | ||
| disabled: o.disabled, | ||
| class: c(o.inputCssClass || ""), | ||
| onChange: p | ||
| }, null, 42, O)], 10, D)); | ||
| } | ||
| }), A = [ | ||
| "title", | ||
| "id", | ||
| "data-testid" | ||
| ], j = { | ||
| class: /* @__PURE__ */ c("property-name"), | ||
| style: { | ||
| flex: "none", | ||
| width: "5rem" | ||
| } | ||
| }, M = /* @__PURE__ */ s({ | ||
| __name: "FileValidatorRow.component", | ||
| props: { | ||
| id: { default: "not-set" }, | ||
| index: {}, | ||
| totItemsCount: {}, | ||
| roundedCorners: { | ||
| type: Boolean, | ||
| default: !1 | ||
| }, | ||
| model: {}, | ||
| validatorRowCssClass: { default: "" }, | ||
| successClass: { default: "success" }, | ||
| errorClass: { default: "error" } | ||
| }, | ||
| setup(e) { | ||
| let n = e, r = t(() => { | ||
| let { model: e } = n, t = e?.hasError || !1, r = ["file-validator-item"]; | ||
| return r.push(`${n.validatorRowCssClass || ""}`), r.push(t ? n.errorClass : n.successClass), r.join(" ").trim(); | ||
| }); | ||
| return (t, o) => (u(), i("div", { | ||
| class: c(r.value), | ||
| title: e.model.value, | ||
| id: n.id, | ||
| "data-testid": n.id | ||
| }, [a("span", j, h(e.model.name), 1), a("span", { | ||
| class: c(`property-value ${e.model.hasError ? "error" : ""}`), | ||
| style: l(`flex: 0 1 auto;${e.model.hasError ? "" : "overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"}`) | ||
| }, h(e.model.displayValue), 7)], 10, A)); | ||
| } | ||
| }), N = ["data-testid"], P = { style: {} }, F = ["title"], I = { | ||
| key: 0, | ||
| class: "file-validator-inner" | ||
| }, L = /* @__PURE__ */ s({ | ||
| __name: "FileValidator.component", | ||
| props: { | ||
| id: {}, | ||
| model: {}, | ||
| showOnlyErrors: { | ||
| type: Boolean, | ||
| default: !0 | ||
| }, | ||
| roundedCorners: { | ||
| type: Boolean, | ||
| default: !1 | ||
| }, | ||
| validatorItems: {}, | ||
| successClass: { default: "success bg-success content-success" }, | ||
| errorClass: { default: "error bg-danger content-danger" }, | ||
| validatorRowCssClass: { default: "" } | ||
| }, | ||
| setup(o) { | ||
| let s = o, l = t(() => s.validatorItems.filter((e) => !s.showOnlyErrors || e.hasError)), d = t(() => { | ||
| let e = ["file-validator-item"]; | ||
| return e.push(`${s.model?.isValid ? s.successClass : s.errorClass}`), e.join(" ").trim(); | ||
| }); | ||
| return (t, f) => _((u(), i("div", { | ||
| "data-testid": s.id, | ||
| class: "file-validator" | ||
| }, [_(a("div", { class: c(d.value) }, [a("span", P, h(o.model.isValid ? "File:" : "Error:"), 1), a("span", { | ||
| class: "", | ||
| title: o.model.isValid ? o.model.displayName : o.model.message | ||
| }, h(o.model.isValid ? o.model.displayName : o.model.message), 9, F)], 2), [[g, o.model.message]]), o.model.message ? r("", !0) : (u(), i("div", I, [(u(!0), i(e, null, p(l.value, (e, t) => (u(), n(M, { | ||
| id: `${s.id}-file-validator-row_${e.key}`, | ||
| key: `file-validator-row-${e.key}`, | ||
| index: t, | ||
| totItemsCount: l.value.length, | ||
| roundedCorners: o.roundedCorners, | ||
| model: e, | ||
| successClass: s.successClass, | ||
| errorClass: s.errorClass, | ||
| validatorRowCssClass: s.validatorRowCssClass | ||
| }, null, 8, [ | ||
| "id", | ||
| "index", | ||
| "totItemsCount", | ||
| "roundedCorners", | ||
| "model", | ||
| "successClass", | ||
| "errorClass", | ||
| "validatorRowCssClass" | ||
| ]))), 128))]))], 8, N)), [[g, o.model.displayName.length > 0]]); | ||
| } | ||
| }), R = { className: "w-full space-y-2" }, z = ["disabled"], B = /* @__PURE__ */ s({ | ||
| __name: "FileUpload.component", | ||
| props: { | ||
| id: {}, | ||
| disabled: { | ||
| type: Boolean, | ||
| default: !1 | ||
| }, | ||
| uploadLabel: {}, | ||
| validatorOptions: {}, | ||
| showOnlyErrors: { | ||
| type: Boolean, | ||
| default: !1 | ||
| }, | ||
| roundedCorners: { | ||
| type: Boolean, | ||
| default: !1 | ||
| }, | ||
| successClass: { default: "success" }, | ||
| errorClass: { default: "error" }, | ||
| inputCssClass: {}, | ||
| inputWrapperCssClass: { default: "" }, | ||
| validatorRowCssClass: {} | ||
| }, | ||
| emits: [ | ||
| "fileSelectionChanged", | ||
| "uploadClicked", | ||
| "update:valid" | ||
| ], | ||
| setup(e, { expose: n, emit: r }) { | ||
| let s = e, l = r, p = f(), g = () => ({ | ||
| file: null, | ||
| lastModified: "", | ||
| fileSelected: !1, | ||
| isValid: !1, | ||
| name: "", | ||
| displayName: "", | ||
| message: "" | ||
| }), _ = d({ | ||
| fileInfo: g(), | ||
| validatorItems: [] | ||
| }), v = t(() => _.fileInfo.file ? _.validatorItems.some((e) => e.hasError) : !0), y = E(s.validatorOptions), b = (e) => { | ||
| _.fileInfo = e, _.validatorItems = y.validateFile(_.fileInfo), console.log("___ fileSelectionChanged", _.fileInfo, _.validatorItems), l("fileSelectionChanged", _.fileInfo), l("update:valid", v.value); | ||
| }, x = async () => { | ||
| console.log("___ onUploadClick", _.fileInfo?.file), l("uploadClicked", _.fileInfo); | ||
| }; | ||
| return n({ reset: () => { | ||
| p.value?.resetInputFile(), b(g()); | ||
| } }), (e, t) => (u(), i("div", R, [ | ||
| o(k, { | ||
| ref_key: "refFileInputComp", | ||
| ref: p, | ||
| id: s.id, | ||
| disabled: s.disabled, | ||
| model: _.fileInfo, | ||
| inputWrapperCssClass: s.inputWrapperCssClass, | ||
| inputCssClass: s.inputCssClass, | ||
| onChanged: b | ||
| }, null, 8, [ | ||
| "id", | ||
| "disabled", | ||
| "model", | ||
| "inputWrapperCssClass", | ||
| "inputCssClass" | ||
| ]), | ||
| o(L, { | ||
| model: _.fileInfo, | ||
| id: `${s.id}-validator`, | ||
| validatorItems: _.validatorItems, | ||
| showOnlyErrors: s.showOnlyErrors, | ||
| roundedCorners: s.roundedCorners, | ||
| successClass: s.successClass, | ||
| errorClass: s.errorClass, | ||
| validatorRowCssClass: s.validatorRowCssClass | ||
| }, null, 8, [ | ||
| "model", | ||
| "id", | ||
| "validatorItems", | ||
| "showOnlyErrors", | ||
| "roundedCorners", | ||
| "successClass", | ||
| "errorClass", | ||
| "validatorRowCssClass" | ||
| ]), | ||
| m(e.$slots, "default", {}, () => [a("button", { | ||
| onClick: x, | ||
| disabled: v.value, | ||
| class: c(`p-2 rounded-md ${v.value ? "bg-gray-400" : "bg-blue-500"} color-white`) | ||
| }, h(s.uploadLabel), 11, z)]) | ||
| ])); | ||
| } | ||
| }); | ||
| export { | ||
| z as DefaultFileValidatorOptions, | ||
| P as FileInputComponent, | ||
| M as FileInputValidatorItems, | ||
| le as FileUploadComponent, | ||
| J as FileValidatorComponent, | ||
| Y as FileValidatorRowComponent | ||
| }; | ||
| //#endregion | ||
| export { y as DefaultFileValidatorOptions, k as FileInputComponent, v as FileInputValidatorItems, B as FileUploadComponent, L as FileValidatorComponent, M as FileValidatorRowComponent }; |
@@ -1,1 +0,1 @@ | ||
| (function(c,s){typeof exports=="object"&&typeof module<"u"?s(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],s):(c=typeof globalThis<"u"?globalThis:c||self,s(c["vue-file-upload"]={},c.Vue))})(this,(function(c,s){"use strict";const C=[{key:"name",name:"Name",value:"",displayValue:"",hasError:!1,iconSuccess:"",iconError:""},{key:"type",name:"Type",value:"",displayValue:"",hasError:!1,iconSuccess:"",iconError:""},{key:"size",name:"Size",value:"",displayValue:"",hasError:!1,iconSuccess:"",iconError:""}],h={allowedTypes:["csv"],propertiesToValidate:["name","type","size"],maxSize:50,maxNameLength:75,nameTruncateMaxLength:35},E=a=>{const e=(a||"").split(".");return e&&e.length>1?(e[e.length-1]||"").trim().toLowerCase():""},y=(a,e,o)=>{const t=e.file;if(!t)return;const l=o.find(i=>i.name.toLowerCase()==="lastmodified");l&&(e.lastModified=t.lastModifiedDate,l.hasError=!1,l.value=e.lastModified,l.displayValue=e.lastModified)},b=(a,e=2)=>{if(a===0)return"0 Bytes";const o=1024,t=e<0?0:e,l=["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],i=Math.floor(Math.log(a)/Math.log(o));return parseFloat((a/Math.pow(o,i)).toFixed(t))+" "+l[i]},f=(a,e)=>{a.isValid=!1;const o=(e||"").trim();return o.length>0?a.message=o:a.message="",a},g={name:(a,e,o)=>{const t=e.file,l=o.find(d=>d.name.toLowerCase()==="name");if(!l){console.warn('name strrategy: could not find "name" validator item');return}const i=a.nameTruncateMaxLength,n=" ...",r=(t?.name||"").trim();if(l.value=r,r.length<i)l.displayValue=r;else{const d=r.substring(0,13),p=r.split("").reverse().join("").substring(0,13).split("").reverse().join("");l.displayValue=`${d} ${n} ${p}`}if(e.name=l.value,e.displayName=l.displayValue,r.length>a.maxNameLength){const d=`max length allowed is ${a.maxNameLength.toString()} chars`;l.hasError=!0,l.displayValue=`File name is too long - ${d}`,f(e)}else e.message=e.name,l.hasError=!1},type:(a,e,o)=>{const t=e.file;if(!t)return;const l=a.allowedTypes||[];if(l.length===0){f(e,"No allowed file types have been specified by the developer");return}if(l.indexOf("*")>-1)return;const i=o.find(d=>d.name.toLowerCase()==="type");if(!i)return;let n="";l.length>1?n=`file must be one of these types: ${l.join(",")}`:n=`file type must be ${l[0]}`;const r=E(t.name);r?l.indexOf(r)>-1?(i.hasError=!1,i.value=t.type,i.displayValue=r):(i.hasError=!0,i.value=t.type||"unknown",i.displayValue=`${r} - ${n}`,f(e)):(i.hasError=!0,i.value=t.type||"unknown",i.displayValue=`${i.value} - ${n}`,f(e))},size:(a,e,o)=>{const t=e.file;if(!t)return;const l=o.find(d=>d.name.toLowerCase()==="size");if(!l)return;const i=1024e3,n=t.size,r=i*a.maxSize;if(l.value=`${n} bytes`,l.displayValue=b(n),n>r){const d=`max upload size is ${a.maxSize.toString()} MB`;l.hasError=!0,l.displayValue=`${l.displayValue} - ${d}`,f(e)}else l.hasError=!1},datemodified:(a,e,o)=>{y(a,e,o)},lastmodified:(a,e,o)=>{y(a,e,o)}};class _{options;enabledValidatorItems=[];constructor(e){this.options={...h,...e||{}},this.enabledValidatorItems=C.filter(o=>this.options.allowedTypes.indexOf(o.key))}get validatorItems(){const e=(this.options.propertiesToValidate||[]).map(o=>o.toLowerCase());return e.length>0?this.enabledValidatorItems.filter(o=>e.indexOf(o.name.toLowerCase())>-1):[]}validateFile(e){if(e.file){e.isValid=!0;const o=this.options.propertiesToValidate||[];o.length>0&&o.forEach(t=>{const l=t.toLowerCase();if(Object.prototype.hasOwnProperty.call(g,l)){const i=g[l];i(this.options,e,this.enabledValidatorItems)}else console.warn("FileValidator: Warning: could not find validator for property",l)})}else f(e,"No file has been selected");return this.validatorItems}}const $=a=>new _(a),B=["id","data-testid","aria-disabled","for"],k=["id","disabled"],v=s.defineComponent({name:"FileInputComponent"}),w=s.defineComponent({...v,props:{id:{},disabled:{type:Boolean,default:!1},model:{},validator:{},inputWrapperCssClass:{default:""},inputCssClass:{default:""}},emits:["changed"],setup(a,{expose:e,emit:o}){const t=a,l=o,i=s.ref(),n=s.computed(()=>{const p=[];return t.disabled&&p.push("disabled"),p.push(`${t.inputWrapperCssClass}`),p.join(" ").trim()});e({resetInputFile:()=>{const p=i.value;p&&(p.value="")}});const d=p=>{const m=p.target;m.files&&m.files.length>0?t.model.file=m.files.item(0):t.model.file=null,t.model.fileSelected=!!t.model.file,l("changed",t.model)};return(p,m)=>(s.openBlock(),s.createElementBlock("label",{class:s.normalizeClass(n.value),id:`${t.id}-input-wrapper`,"data-testid":t.id,"aria-disabled":t.disabled,for:`${t.id}-input`},[s.createElementVNode("input",{ref_key:"refInputFile",ref:i,type:"file",id:`${t.id}-input`,disabled:t.disabled,class:s.normalizeClass(t.inputCssClass||""),onChange:d},null,42,k)],10,B))}}),F=["title","id","data-testid"],S={class:s.normalizeClass("property-name"),style:{flex:"none",width:"5rem"}},V=s.defineComponent({__name:"FileValidatorRow.component",props:{id:{default:"not-set"},index:{},totItemsCount:{},roundedCorners:{type:Boolean,default:!1},model:{},validatorRowCssClass:{default:""},successClass:{default:"success"},errorClass:{default:"error"}},setup(a){const e=a,o=s.computed(()=>{const{model:t}=e,l=t?.hasError||!1,i=["file-validator-item"];return i.push(`${e.validatorRowCssClass||""}`),i.push(l?e.errorClass:e.successClass),i.join(" ").trim()});return(t,l)=>(s.openBlock(),s.createElementBlock("div",{class:s.normalizeClass(o.value),title:t.model.value,id:e.id,"data-testid":e.id},[s.createElementVNode("span",S,s.toDisplayString(t.model.name),1),s.createElementVNode("span",{class:s.normalizeClass(`property-value ${t.model.hasError?"error":""}`),style:s.normalizeStyle(`flex: 0 1 auto;${t.model.hasError?"":"overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"}`)},s.toDisplayString(t.model.displayValue),7)],10,F))}}),N=["data-testid"],z={style:{}},L=["title"],O={key:0,class:"file-validator-inner"},I=s.defineComponent({__name:"FileValidator.component",props:{id:{},model:{},showOnlyErrors:{type:Boolean,default:!0},roundedCorners:{type:Boolean,default:!1},validatorItems:{},successClass:{default:"success bg-success content-success"},errorClass:{default:"error bg-danger content-danger"},validatorRowCssClass:{default:""}},setup(a){const e=a,o=s.computed(()=>e.validatorItems.filter(l=>!e.showOnlyErrors||l.hasError)),t=s.computed(()=>{const l=["file-validator-item"];return l.push(`${e.model?.isValid?e.successClass:e.errorClass}`),l.join(" ").trim()});return(l,i)=>s.withDirectives((s.openBlock(),s.createElementBlock("div",{"data-testid":e.id,class:"file-validator"},[s.withDirectives(s.createElementVNode("div",{class:s.normalizeClass(t.value)},[s.createElementVNode("span",z,s.toDisplayString(l.model.isValid?"File:":"Error:"),1),s.createElementVNode("span",{class:"",title:l.model.isValid?l.model.displayName:l.model.message},s.toDisplayString(l.model.isValid?l.model.displayName:l.model.message),9,L)],2),[[s.vShow,l.model.message]]),l.model.message?s.createCommentVNode("",!0):(s.openBlock(),s.createElementBlock("div",O,[(s.openBlock(!0),s.createElementBlock(s.Fragment,null,s.renderList(o.value,(n,r)=>(s.openBlock(),s.createBlock(V,{id:`${e.id}-file-validator-row_${n.key}`,key:`file-validator-row-${n.key}`,index:r,totItemsCount:o.value.length,roundedCorners:l.roundedCorners,model:n,successClass:e.successClass,errorClass:e.errorClass,validatorRowCssClass:e.validatorRowCssClass},null,8,["id","index","totItemsCount","roundedCorners","model","successClass","errorClass","validatorRowCssClass"]))),128))]))],8,N)),[[s.vShow,l.model.displayName.length>0]])}}),M={className:"w-full space-y-2"},T=["disabled"],R=s.defineComponent({__name:"FileUpload.component",props:{id:{},disabled:{type:Boolean,default:!1},uploadLabel:{},validatorOptions:{},showOnlyErrors:{type:Boolean,default:!1},roundedCorners:{type:Boolean,default:!1},successClass:{default:"success"},errorClass:{default:"error"},inputCssClass:{},inputWrapperCssClass:{default:""},validatorRowCssClass:{}},emits:["fileSelectionChanged","uploadClicked","update:valid"],setup(a,{expose:e,emit:o}){const t=a,l=o,i=s.ref(),n=()=>({file:null,lastModified:"",fileSelected:!1,isValid:!1,name:"",displayName:"",message:""}),r=s.reactive({fileInfo:n(),validatorItems:[]}),d=s.computed(()=>r.fileInfo.file?r.validatorItems.some(u=>u.hasError):!0),p=$(t.validatorOptions),m=u=>{r.fileInfo=u,r.validatorItems=p.validateFile(r.fileInfo),console.log("___ fileSelectionChanged",r.fileInfo,r.validatorItems),l("fileSelectionChanged",r.fileInfo),l("update:valid",d.value)},D=async()=>{console.log("___ onUploadClick",r.fileInfo?.file),l("uploadClicked",r.fileInfo)};return e({reset:()=>{i.value?.resetInputFile(),m(n())}}),(u,W)=>(s.openBlock(),s.createElementBlock("div",M,[s.createVNode(w,{ref_key:"refFileInputComp",ref:i,id:t.id,disabled:t.disabled,model:r.fileInfo,inputWrapperCssClass:t.inputWrapperCssClass,inputCssClass:t.inputCssClass,onChanged:m},null,8,["id","disabled","model","inputWrapperCssClass","inputCssClass"]),s.createVNode(I,{model:r.fileInfo,id:`${t.id}-validator`,validatorItems:r.validatorItems,showOnlyErrors:t.showOnlyErrors,roundedCorners:t.roundedCorners,successClass:t.successClass,errorClass:t.errorClass,validatorRowCssClass:t.validatorRowCssClass},null,8,["model","id","validatorItems","showOnlyErrors","roundedCorners","successClass","errorClass","validatorRowCssClass"]),s.renderSlot(u.$slots,"default",{},()=>[s.createElementVNode("button",{onClick:D,disabled:d.value,class:s.normalizeClass(`p-2 rounded-md ${d.value?"bg-gray-400":"bg-blue-500"} color-white`)},s.toDisplayString(t.uploadLabel),11,T)])]))}});c.DefaultFileValidatorOptions=h,c.FileInputComponent=w,c.FileInputValidatorItems=C,c.FileUploadComponent=R,c.FileValidatorComponent=I,c.FileValidatorRowComponent=V,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})})); | ||
| (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`vue`)):typeof define==`function`&&define.amd?define([`exports`,`vue`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e[`vue-file-upload`]={},e.Vue))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=[{key:`name`,name:`Name`,value:``,displayValue:``,hasError:!1,iconSuccess:``,iconError:``},{key:`type`,name:`Type`,value:``,displayValue:``,hasError:!1,iconSuccess:``,iconError:``},{key:`size`,name:`Size`,value:``,displayValue:``,hasError:!1,iconSuccess:``,iconError:``}],r={allowedTypes:[`csv`],propertiesToValidate:[`name`,`type`,`size`],maxSize:50,maxNameLength:75,nameTruncateMaxLength:35},i=e=>{let t=(e||``).split(`.`);return t&&t.length>1?(t[t.length-1]||``).trim().toLowerCase():``},a=(e,t,n)=>{let r=t.file;if(!r)return;let i=n.find(e=>e.name.toLowerCase()===`lastmodified`);i&&(t.lastModified=r.lastModifiedDate,i.hasError=!1,i.value=t.lastModified,i.displayValue=t.lastModified)},o=(e,t=2)=>{if(e===0)return`0 Bytes`;let n=1024,r=t<0?0:t,i=[`Bytes`,`KB`,`MB`,`GB`,`TB`,`PB`,`EB`,`ZB`,`YB`],a=Math.floor(Math.log(e)/Math.log(n));return parseFloat((e/n**+a).toFixed(r))+` `+i[a]},s=(e,t)=>{e.isValid=!1;let n=(t||``).trim();return n.length>0?e.message=n:e.message=``,e},c={name:(e,t,n)=>{let r=t.file,i=n.find(e=>e.name.toLowerCase()===`name`);if(!i){console.warn(`name strrategy: could not find "name" validator item`);return}let a=e.nameTruncateMaxLength,o=(r?.name||``).trim();if(i.value=o,o.length<a?i.displayValue=o:i.displayValue=`${o.substring(0,13)} ... ${o.split(``).reverse().join(``).substring(0,13).split(``).reverse().join(``)}`,t.name=i.value,t.displayName=i.displayValue,o.length>e.maxNameLength){let n=`max length allowed is ${e.maxNameLength.toString()} chars`;i.hasError=!0,i.displayValue=`File name is too long - ${n}`,s(t)}else t.message=t.name,i.hasError=!1},type:(e,t,n)=>{let r=t.file;if(!r)return;let a=e.allowedTypes||[];if(a.length===0){s(t,`No allowed file types have been specified by the developer`);return}if(a.indexOf(`*`)>-1)return;let o=n.find(e=>e.name.toLowerCase()===`type`);if(!o)return;let c=``;c=a.length>1?`file must be one of these types: ${a.join(`,`)}`:`file type must be ${a[0]}`;let l=i(r.name);l?a.indexOf(l)>-1?(o.hasError=!1,o.value=r.type,o.displayValue=l):(o.hasError=!0,o.value=r.type||`unknown`,o.displayValue=`${l} - ${c}`,s(t)):(o.hasError=!0,o.value=r.type||`unknown`,o.displayValue=`${o.value} - ${c}`,s(t))},size:(e,t,n)=>{let r=t.file;if(!r)return;let i=n.find(e=>e.name.toLowerCase()===`size`);if(!i)return;let a=r.size,c=1024e3*e.maxSize;if(i.value=`${a} bytes`,i.displayValue=o(a),a>c){let n=`max upload size is ${e.maxSize.toString()} MB`;i.hasError=!0,i.displayValue=`${i.displayValue} - ${n}`,s(t)}else i.hasError=!1},datemodified:(e,t,n)=>{a(e,t,n)},lastmodified:(e,t,n)=>{a(e,t,n)}},l=class{options;enabledValidatorItems=[];constructor(e){this.options={...r,...e||{}},this.enabledValidatorItems=n.filter(e=>this.options.allowedTypes.indexOf(e.key))}get validatorItems(){let e=(this.options.propertiesToValidate||[]).map(e=>e.toLowerCase());return e.length>0?this.enabledValidatorItems.filter(t=>e.indexOf(t.name.toLowerCase())>-1):[]}validateFile(e){if(e.file){e.isValid=!0;let t=this.options.propertiesToValidate||[];t.length>0&&t.forEach(t=>{let n=t.toLowerCase();if(Object.prototype.hasOwnProperty.call(c,n)){let t=c[n];t(this.options,e,this.enabledValidatorItems)}else console.warn(`FileValidator: Warning: could not find validator for property`,n)})}else s(e,`No file has been selected`);return this.validatorItems}},u=e=>new l(e),d=[`id`,`data-testid`,`aria-disabled`,`for`],f=[`id`,`disabled`],p=(0,t.defineComponent)({name:`FileInputComponent`}),m=(0,t.defineComponent)({...p,props:{id:{},disabled:{type:Boolean,default:!1},model:{},validator:{},inputWrapperCssClass:{default:``},inputCssClass:{default:``}},emits:[`changed`],setup(e,{expose:n,emit:r}){let i=e,a=r,o=(0,t.ref)(),s=(0,t.computed)(()=>{let e=[];return i.disabled&&e.push(`disabled`),e.push(`${i.inputWrapperCssClass}`),e.join(` `).trim()});n({resetInputFile:()=>{let e=o.value;e&&(e.value=``)}});let c=e=>{let t=e.target;t.files&&t.files.length>0?i.model.file=t.files.item(0):i.model.file=null,i.model.fileSelected=!!i.model.file,a(`changed`,i.model)};return(e,n)=>((0,t.openBlock)(),(0,t.createElementBlock)(`label`,{class:(0,t.normalizeClass)(s.value),id:`${i.id}-input-wrapper`,"data-testid":i.id,"aria-disabled":i.disabled,for:`${i.id}-input`},[(0,t.createElementVNode)(`input`,{ref_key:`refInputFile`,ref:o,type:`file`,id:`${i.id}-input`,disabled:i.disabled,class:(0,t.normalizeClass)(i.inputCssClass||``),onChange:c},null,42,f)],10,d))}}),h=[`title`,`id`,`data-testid`],g={class:(0,t.normalizeClass)(`property-name`),style:{flex:`none`,width:`5rem`}},_=(0,t.defineComponent)({__name:`FileValidatorRow.component`,props:{id:{default:`not-set`},index:{},totItemsCount:{},roundedCorners:{type:Boolean,default:!1},model:{},validatorRowCssClass:{default:``},successClass:{default:`success`},errorClass:{default:`error`}},setup(e){let n=e,r=(0,t.computed)(()=>{let{model:e}=n,t=e?.hasError||!1,r=[`file-validator-item`];return r.push(`${n.validatorRowCssClass||``}`),r.push(t?n.errorClass:n.successClass),r.join(` `).trim()});return(i,a)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{class:(0,t.normalizeClass)(r.value),title:e.model.value,id:n.id,"data-testid":n.id},[(0,t.createElementVNode)(`span`,g,(0,t.toDisplayString)(e.model.name),1),(0,t.createElementVNode)(`span`,{class:(0,t.normalizeClass)(`property-value ${e.model.hasError?`error`:``}`),style:(0,t.normalizeStyle)(`flex: 0 1 auto;${e.model.hasError?``:`overflow: hidden; text-overflow: ellipsis; white-space: nowrap;`}`)},(0,t.toDisplayString)(e.model.displayValue),7)],10,h))}}),v=[`data-testid`],y={style:{}},b=[`title`],x={key:0,class:`file-validator-inner`},S=(0,t.defineComponent)({__name:`FileValidator.component`,props:{id:{},model:{},showOnlyErrors:{type:Boolean,default:!0},roundedCorners:{type:Boolean,default:!1},validatorItems:{},successClass:{default:`success bg-success content-success`},errorClass:{default:`error bg-danger content-danger`},validatorRowCssClass:{default:``}},setup(e){let n=e,r=(0,t.computed)(()=>n.validatorItems.filter(e=>!n.showOnlyErrors||e.hasError)),i=(0,t.computed)(()=>{let e=[`file-validator-item`];return e.push(`${n.model?.isValid?n.successClass:n.errorClass}`),e.join(` `).trim()});return(a,o)=>(0,t.withDirectives)(((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{"data-testid":n.id,class:`file-validator`},[(0,t.withDirectives)((0,t.createElementVNode)(`div`,{class:(0,t.normalizeClass)(i.value)},[(0,t.createElementVNode)(`span`,y,(0,t.toDisplayString)(e.model.isValid?`File:`:`Error:`),1),(0,t.createElementVNode)(`span`,{class:``,title:e.model.isValid?e.model.displayName:e.model.message},(0,t.toDisplayString)(e.model.isValid?e.model.displayName:e.model.message),9,b)],2),[[t.vShow,e.model.message]]),e.model.message?(0,t.createCommentVNode)(``,!0):((0,t.openBlock)(),(0,t.createElementBlock)(`div`,x,[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(r.value,(i,a)=>((0,t.openBlock)(),(0,t.createBlock)(_,{id:`${n.id}-file-validator-row_${i.key}`,key:`file-validator-row-${i.key}`,index:a,totItemsCount:r.value.length,roundedCorners:e.roundedCorners,model:i,successClass:n.successClass,errorClass:n.errorClass,validatorRowCssClass:n.validatorRowCssClass},null,8,[`id`,`index`,`totItemsCount`,`roundedCorners`,`model`,`successClass`,`errorClass`,`validatorRowCssClass`]))),128))]))],8,v)),[[t.vShow,e.model.displayName.length>0]])}}),C={className:`w-full space-y-2`},w=[`disabled`],T=(0,t.defineComponent)({__name:`FileUpload.component`,props:{id:{},disabled:{type:Boolean,default:!1},uploadLabel:{},validatorOptions:{},showOnlyErrors:{type:Boolean,default:!1},roundedCorners:{type:Boolean,default:!1},successClass:{default:`success`},errorClass:{default:`error`},inputCssClass:{},inputWrapperCssClass:{default:``},validatorRowCssClass:{}},emits:[`fileSelectionChanged`,`uploadClicked`,`update:valid`],setup(e,{expose:n,emit:r}){let i=e,a=r,o=(0,t.ref)(),s=()=>({file:null,lastModified:``,fileSelected:!1,isValid:!1,name:``,displayName:``,message:``}),c=(0,t.reactive)({fileInfo:s(),validatorItems:[]}),l=(0,t.computed)(()=>c.fileInfo.file?c.validatorItems.some(e=>e.hasError):!0),d=u(i.validatorOptions),f=e=>{c.fileInfo=e,c.validatorItems=d.validateFile(c.fileInfo),console.log(`___ fileSelectionChanged`,c.fileInfo,c.validatorItems),a(`fileSelectionChanged`,c.fileInfo),a(`update:valid`,l.value)},p=async()=>{console.log(`___ onUploadClick`,c.fileInfo?.file),a(`uploadClicked`,c.fileInfo)};return n({reset:()=>{o.value?.resetInputFile(),f(s())}}),(e,n)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,C,[(0,t.createVNode)(m,{ref_key:`refFileInputComp`,ref:o,id:i.id,disabled:i.disabled,model:c.fileInfo,inputWrapperCssClass:i.inputWrapperCssClass,inputCssClass:i.inputCssClass,onChanged:f},null,8,[`id`,`disabled`,`model`,`inputWrapperCssClass`,`inputCssClass`]),(0,t.createVNode)(S,{model:c.fileInfo,id:`${i.id}-validator`,validatorItems:c.validatorItems,showOnlyErrors:i.showOnlyErrors,roundedCorners:i.roundedCorners,successClass:i.successClass,errorClass:i.errorClass,validatorRowCssClass:i.validatorRowCssClass},null,8,[`model`,`id`,`validatorItems`,`showOnlyErrors`,`roundedCorners`,`successClass`,`errorClass`,`validatorRowCssClass`]),(0,t.renderSlot)(e.$slots,`default`,{},()=>[(0,t.createElementVNode)(`button`,{onClick:p,disabled:l.value,class:(0,t.normalizeClass)(`p-2 rounded-md ${l.value?`bg-gray-400`:`bg-blue-500`} color-white`)},(0,t.toDisplayString)(i.uploadLabel),11,w)])]))}});e.DefaultFileValidatorOptions=r,e.FileInputComponent=m,e.FileInputValidatorItems=n,e.FileUploadComponent=T,e.FileValidatorComponent=S,e.FileValidatorRowComponent=_}); |
+13
-13
| { | ||
| "name": "@builtwithjavascript/vue-file-upload", | ||
| "version": "1.0.9", | ||
| "version": "1.1.0", | ||
| "description": "A Vue file upload component with validation, unstyled", | ||
@@ -24,3 +24,3 @@ "author": "Damiano Fusco", | ||
| "build": "npm run pretty; vite build && npm run build-types", | ||
| "pub": "npm publish --access public", | ||
| "pub": "npm run build; npm publish --access public --otp=", | ||
| "test": "TESTING=true vitest run", | ||
@@ -35,15 +35,15 @@ "test-watch": "TESTING=true vitest watch", | ||
| "devDependencies": { | ||
| "@builtwithjavascript/file-input-validator": "^1.0.7", | ||
| "@builtwithjavascript/file-input-validator": "^1.0.9", | ||
| "@testing-library/user-event": "^14.6.1", | ||
| "@testing-library/vue": "^8.1.0", | ||
| "@types/node": "^24.4.0", | ||
| "@vitejs/plugin-vue": "^6.0.1", | ||
| "jsdom": "^27.0.0", | ||
| "prettier": "^3.6.2", | ||
| "typescript": "^5.9.2", | ||
| "vite": "^7.1.5", | ||
| "vitest": "^3.2.4", | ||
| "vitest-preview": "^0.0.1", | ||
| "vue": "^3.5.21", | ||
| "vue-tsc": "^3.0.7" | ||
| "@types/node": "^25.5.0", | ||
| "@vitejs/plugin-vue": "^6.0.5", | ||
| "jsdom": "^29.0.1", | ||
| "prettier": "^3.8.1", | ||
| "typescript": "^6.0.2", | ||
| "vite": "^8.0.2", | ||
| "vitest": "^4.1.1", | ||
| "vitest-preview": "^0.0.3", | ||
| "vue": "^3.5.31", | ||
| "vue-tsc": "^3.2.6" | ||
| }, | ||
@@ -50,0 +50,0 @@ "files": [ |
+3
-3
@@ -18,5 +18,2 @@ # @builtwithjavascript/vue-file-upload | ||
| ## Other Dependencies | ||
| - @builtwithjavascript/file-input-validator | ||
| ## Install | ||
@@ -84,1 +81,4 @@ ``` | ||
| NOTE: if you pass `showOnlyErrors` true, then only the validator items that fail will be displayed. | ||
| ### Dev Dependencies | ||
| @builtwithjavascript/file-input-validator @testing-library/user-event @testing-library/vue @types/node @vitejs/plugin-vue jsdom prettier typescript vite vitest vitest-preview vue vue-tsc |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
31909
-2.33%494
-3.89%1
Infinity%