UNPKG

vexip-ui

Version:

A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good

571 lines (570 loc) 17.2 kB
import { isVNode as ze, defineComponent as Ne, toRef as Be, ref as I, computed as S, watch as Ue, onBeforeUnmount as Oe, createVNode as r, Fragment as Re, renderSlot as w, mergeProps as A } from "vue"; import "../button/index.mjs"; import "../icon/index.mjs"; import "../renderer/index.mjs"; import "../upload-list/index.mjs"; import "../form/index.mjs"; import { useProps as $e, createIconProp as Ge, createStateProp as je, useNameHelper as Me, useLocale as Ve, useIcons as _e, emitEvent as y } from "@vexip-ui/config"; import { noop as L, randomString as X, isDefined as He, isPromise as Q, isFalse as W, isClient as Ke } from "@vexip-ui/utils"; import { uploadProps as qe } from "./props.mjs"; import { upload as Je } from "./request.mjs"; import { StatusType as d, uploadListTypes as Qe } from "./symbol.mjs"; import { useFieldStore as We } from "../form/helper.mjs"; import Xe from "../button/button.mjs"; import C from "../icon/icon.mjs"; import F from "../renderer/renderer.mjs"; import Ye from "./upload-list.vue2.mjs"; function Ze(T) { return typeof T == "function" || Object.prototype.toString.call(T) === "[object Object]" && !ze(T); } function et() { return { id: X(), name: "", size: 0, type: "", base64: null, status: d.PENDING, percentage: 0, source: null, url: null, path: "", xhr: null, response: null, error: null, abort: L }; } const vt = /* @__PURE__ */ Ne({ name: "Upload", props: qe, emits: ["update:file-list"], setup(T, { slots: v, emit: Y, expose: Z }) { const { idFor: ee, labelId: te, state: le, disabled: ae, loading: ne, size: ie, validateField: oe, getFieldValue: re, setFieldValue: se } = We(V), e = $e("upload", T, { state: je(le), locale: null, url: { default: "", static: !0 }, fileList: { default: () => re(), static: !0 }, multiple: !1, tip: "", accept: null, filter: "", maxSize: { default: null, validator: (t) => t >= 0 }, field: "file", data: () => ({}), headers: () => ({}), withCredentials: !1, manual: !1, hiddenFiles: !1, countLimit: { default: 0, validator: (t) => t >= 0 }, allowDrag: !1, onBeforeUpload: { default: null, isFunc: !0 }, onBeforeSelect: { default: null, isFunc: !0 }, iconRenderer: { default: null, isFunc: !0 }, selectToAdd: !1, listType: { default: "name", validator: (t) => Qe.includes(t) }, block: !1, loadingText: null, directory: !1, pathField: "path", disabledClick: !1, buttonLabel: null, disabled: () => ae.value, loading: () => ne.value, loadingIcon: Ge(), loadingLock: !1, loadingEffect: null, image: !1, defaultFiles: () => [], // canPreview: don't set, using UploadFile default value listStyle: null, name: { default: "", static: !0 }, customFetch: { default: null, isFunc: !0 }, slots: () => ({}) }), n = Me("upload"), O = Ve("upload", Be(e, "locale")), p = _e(), c = I([]), b = I(!1), z = I(), N = I(), R = I(), P = S(() => e.loading && e.loadingLock), ue = S(() => [n.b(), n.bs("vars"), n.bm(`type-${e.listType}`), { [n.bm("inherit")]: e.inherit, [n.bm(e.state)]: e.state !== "default", [n.bm("multiple")]: e.multiple, [n.bm("drag")]: e.allowDrag, [n.bm("to-add")]: e.selectToAdd, [n.bm("block")]: e.block, [n.bm("drag-only")]: e.disabledClick, [n.bm("image")]: e.image, [n.bm("has-file")]: !e.hiddenFiles && $.value.length, [n.bm("readonly")]: P.value, [n.bm("loading")]: e.loading }]), ce = S(() => e.image ? { [n.be("image-control")]: !0, [n.bem("image-control", "drag-over")]: b.value, [n.bem("image-control", "disabled")]: e.disabled } : { [n.be("control")]: !0, [n.bem("control", "drag-over")]: b.value }), de = S(() => { var l; const t = e.image ? (l = e.accept) != null && l.length ? e.accept : "image/*" : e.accept; return t && (typeof t == "string" ? t : t.join()); }), fe = S(() => e.defaultFiles.map((t) => G(t))), $ = S(() => fe.value.concat(c.value).filter((t) => t.status !== d.DELETE)); Ue(() => e.fileList, (t) => { const l = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(); for (const a of c.value) He(a.id) && l.set(a.id, a), a.source && i.set(a.source, a); c.value = (t || []).map((a) => G(a, a.id ? l.get(a.id) : a.source ? i.get(a.source) : void 0)), j(); }, { immediate: !0, deep: !0 }), Z({ isDragOver: b, execute: K, handleDelete: q, focus: V, blur: () => { var t, l; (t = N.value) == null || t.$el.blur(), (l = R.value) == null || l.blur(); } }); function V(t) { var l, i; (l = N.value) != null && l.$el ? N.value.$el.focus(t) : (i = R.value) == null || i.focus(t); } function _() { var t; e.disabled || P.value || !e.disabledClick && ((t = z.value) == null || t.click()); } function pe(t) { const l = t.code || t.key; (l === "Enter" || l === "Space") && _(); } function me(t) { const l = t.target; l != null && l.files && H(l.files); } async function H(t) { const l = Array.from(t || []), a = e.selectToAdd ? Array.from(c.value) : []; for (const o of l) { o.path || (o.path = o.webkitRelativePath); let f = ge(o); if (f ? f.status !== d.SUCCESS && f.status !== d.UPLOADING && (f.status = d.PENDING) : f = G({ name: o.name, size: o.size, type: o.type, source: o }), typeof e.onBeforeSelect == "function") { let s = e.onBeforeSelect(f, a); if (Q(s) && (s = await s), W(s)) continue; } a.includes(f) || a.push(f); } const u = e.countLimit; if (u > 0 && a.length > u) { const o = a.slice(u); y(e.onExceed, o), c.value = a.slice(0, u); } else c.value = a; j(), k(), e.manual || K(); } function k() { Y("update:file-list", c.value), se(c.value), y(e.onChange, c.value), oe(); } function ge(t) { const { name: l, size: i, type: a } = t, u = t.path || t.webkitRelativePath; return c.value.find(({ source: o }) => o && (o.path || o.webkitRelativePath) === u && o.name === l && o.size === i && o.type === a); } function G(t, l = et()) { const { id: i, name: a, size: u, type: o, base64: f, status: s, percentage: h, source: m, url: U, path: g } = t; return Object.assign(l, { id: i ?? l.id ?? X(), name: a || "", size: u || 0, type: o || "", base64: f || null, status: s ?? d.PENDING, percentage: h || 0, source: m || null, url: U || null, path: g || "", xhr: null, response: null, error: null }), l; } function be(t) { return t.name.split(".").pop().toLocaleLowerCase(); } async function K() { if (!e.url || !he()) return !1; const t = c.value.filter((i) => i.status !== d.SUCCESS && i.status !== d.DELETE), l = []; for (const i of t) l.push(ve(i).catch(L)); return await Promise.all(l).then((i) => i.filter((a) => a)); } async function ve(t) { if (typeof e.onBeforeUpload == "function") { let s = e.onBeforeUpload(t, c.value.filter((h) => h.status !== d.SUCCESS && h.status !== d.DELETE)); if (Q(s)) try { s = await s; } catch { return; } if (W(s)) return; s instanceof Blob && (s instanceof File ? t.source = s : t.source = new File([s], t.name, { type: t.type })); } if (!t.source) return; t.status = d.UPLOADING; const { url: l, headers: i, withCredentials: a, data: u, field: o, pathField: f } = e; return await new Promise((s, h) => { t.abort = (e.customFetch || Je)({ url: l, headers: i, withCredentials: a, data: u, field: o, pathField: f, file: t.source, onProgress: (m) => { Ee(m, t); }, onSuccess: (m) => { De(m, t), s(m); }, onError: (m) => { we(m, t), h(m); }, onAbort: () => { s(null); } }); }); } function he() { const t = e.maxSize ? e.maxSize * 1024 : 1 / 0, l = typeof e.filter == "string" ? e.filter ? [e.filter] : [] : e.filter.filter((i) => i); for (let i = 0, a = c.value.length; i < a; ++i) { const u = c.value[i], o = be(u); if (l.length && !l.includes(o)) return y(e.onFilterError, u), !1; if (u.size > t) return y(e.onSizeError, u), !1; } return !0; } function q(t) { var l; t.status = d.DELETE, (l = t.abort) == null || l.call(t), j(), y(e.onDelete, t), k(); } function ye(t) { y(e.onPreview, t); } function j() { if (!Ke) return; const t = new DataTransfer(); c.value = c.value.filter((l) => l.status !== d.DELETE), c.value.forEach((l) => { l.source && t.items.add(l.source); }), z.value && (z.value.files = t.files); } function Ee(t, l) { l.status !== d.DELETE && (l.percentage = t, y(e.onProgress, l, t), k()); } function De(t, l) { l.status !== d.DELETE && (l.status = d.SUCCESS, l.response = t, l.error = null, y(e.onSuccess, l, t), k()); } function we(t, l) { l.status !== d.DELETE && (l.status = d.FAIL, l.error = t, y(e.onError, l, t), k()); } let B; Oe(() => { clearTimeout(B); }); async function Fe(t) { if (!(!e.allowDrag || e.disabled || P.value) && (clearTimeout(B), t.preventDefault(), b.value = !1, t.dataTransfer)) { const l = await Le(t.dataTransfer); l.length && H(l); } } function Se(t) { !e.allowDrag || e.disabled || P.value || (clearTimeout(B), t.preventDefault(), b.value = !0); } function Ce(t) { !e.allowDrag || e.disabled || P.value || (t.preventDefault(), B = setTimeout(() => { b.value = !1; }, 100)); } async function Le(t) { var m, U; const { items: l, files: i } = t; if (!l.length) return []; const a = [], u = [], o = []; for (let g = 0, D = l.length; g < D; ++g) { const E = (U = (m = l[g]).webkitGetAsEntry) == null ? void 0 : U.call(m); if (!E) return i; E.isFile ? a.push(i[g]) : u.push({ dir: E, prefix: "" }); } if (!e.directory || !u.length) return a; const f = []; let s = e.countLimit - (e.selectToAdd ? c.value.length : 0); s = Math.round(s) > 0 ? s : 100; const h = () => { for (; u.length; ) { const g = u.shift(), D = g.dir, E = g.prefix ? `${g.prefix}/${D.name}` : D.name, x = D.createReader(); o.push(new Promise((Ie) => { x.readEntries((Ae) => { Ae.forEach((M) => { M.isFile ? f.push({ entry: M, prefix: E }) : u.push({ dir: M, prefix: E }); }), Ie(); }); })); } }; for (; h(), await Promise.all(o), !(!u.length || f.length >= s); ) ; return f.length > 0 ? a.concat(await Promise.all(f.map(({ entry: g, prefix: D }) => new Promise((E) => g.file((x) => { x.path = `${D}/${x.name}`, E(x); }))))) : a; } function Te(t) { t.preventDefault(); } function Pe() { return !e.allowDrag && !e.disabledClick ? r(Re, null, [r(Xe, { ref: N, inherit: !0, size: ie.value, type: e.state, disabled: e.disabled, loading: e.loading }, { default: () => e.buttonLabel ?? O.value.upload, icon: () => r(C, p.value.upload, null), loading: () => r(C, A(p.value.loading, { class: n.be("loading-icon"), effect: e.loadingEffect || p.value.loading.effect, icon: e.loadingIcon || p.value.loading.icon, label: "loading" }), null) }), w(v, "tip", void 0, () => [r(F, { renderer: e.slots.tip }, { default: () => [e.tip && r("p", { class: n.be("tip") }, [e.tip])] })])]) : r("div", { ref: R, class: [n.be("drag-panel"), e.disabled && n.bem("drag-panel", "disabled")], tabindex: 0 }, [w(v, "cloud", void 0, () => [r(F, { renderer: e.slots.cloud }, { default: () => [r(C, A(p.value.uploadCloud, { class: [n.be("cloud"), e.disabled && n.bem("cloud", "disabled")], scale: +(p.value.uploadCloud.scale || 1) * 4 }), null)] })]), w(v, "tip", void 0, () => [r(F, { renderer: e.slots.tip }, { default: () => [r("p", { class: n.be("tip") }, [e.tip || O.value.dragOrClick])] })]), r(C, A(p.value.loading, { class: n.be("loading-icon"), effect: e.loadingEffect || p.value.loading.effect, icon: e.loadingIcon || p.value.loading.icon, label: "loading", style: { opacity: e.loading ? "100%" : "0%" } }), null)]); } function ke() { return r("button", { class: [n.be("image-action"), e.disabled && n.bem("image-action", "disabled")], type: "button" }, [w(v, "default", { isDragOver: (e.allowDrag || e.disabledClick) && b.value }, () => [r(F, { renderer: e.slots.default, data: { isDragOver: (e.allowDrag || e.disabledClick) && b.value } }, { default: () => [e.loading ? r(C, A(p.value.loading, { class: n.be("loading-icon"), effect: e.loadingEffect || p.value.loading.effect, icon: e.loadingIcon || p.value.loading.icon, label: "loading", style: { marginBottom: "6px" } }), null) : r(C, A(p.value.plus, { class: [n.be("cloud"), e.disabled && n.bem("cloud", "disabled")], scale: +(p.value.plus.scale || 1) * 1.2, style: { marginBottom: "6px" } }), null), r("span", null, [e.buttonLabel ?? O.value.upload])] })])]); } function J() { const t = e.image ? "li" : "div"; return r(t, { class: ce.value, tabindex: -1, onClick: _, onDrop: Fe, onDragover: Se, onDragleave: Ce, onKeydown: pe }, { default: () => [!e.disabledClick && r("input", { ref: z, type: "file", class: n.be("input"), disabled: e.disabled, multiple: e.multiple, name: e.name, accept: de.value, webkitdirectory: e.directory || void 0, onChange: me, onSubmit: Te }, null), e.image ? ke() : w(v, "default", { isDragOver: (e.allowDrag || e.disabledClick) && b.value }, () => { let l; return [r(F, { renderer: e.slots.default, data: { isDragOver: (e.allowDrag || e.disabledClick) && b.value } }, Ze(l = Pe()) ? l : { default: () => [l] })]; })] }); } function xe() { return r(Ye, { inherit: !0, files: $.value, "select-to-add": e.selectToAdd, type: e.image ? "thumbnail" : e.listType, "icon-renderer": e.iconRenderer, "loading-text": e.loadingText, "can-preview": e.canPreview, style: e.listStyle, onDelete: q, onPreview: ye }, { item: v.item || e.slots.item ? (t) => w(v, "item", t, () => [r(F, { renderer: e.slots.item, data: t }, null)]) : null, icon: v.icon || e.slots.icon ? (t) => w(v, "icon", t, () => [r(F, { renderer: e.slots.icon, data: t }, null)]) : null, suffix: () => e.image && (!e.countLimit || $.value.length < e.countLimit) ? J() : null }); } return () => r("div", { id: ee.value, class: ue.value, role: "group", "aria-labelledby": te.value }, [!e.image && J(), !e.hiddenFiles && xe()]); }, methods: { execute: L, handleDelete: L, focus: L, blur: L } }); export { vt as default }; //# sourceMappingURL=upload.mjs.map