vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
571 lines (570 loc) • 17.2 kB
JavaScript
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