@wfrog/vc
Version:
vue3 组件库 vc
1,383 lines (1,362 loc) • 46.6 kB
JavaScript
import './index.css'
import { c as buildProps, d as definePropType, u as useNamespace, j as isFunction, h as isString, t as throwError, i as isArray, k as isNil, N as NOOP, l as isPlainObject, e as debugWarn } from '../../chunk/E_WRn0OP.mjs';
import { v as vLoading } from '../../chunk/BeMzzYc5.mjs';
import { E as ElButton } from '../../chunk/BT7IBuxS.mjs';
import { defineComponent, computed, createElementBlock, openBlock, normalizeClass, unref, createCommentVNode, createElementVNode, normalizeStyle, renderSlot, toDisplayString, createBlock, withCtx, resolveDynamicComponent, ref, TransitionGroup, Fragment, renderList, withKeys, withModifiers, createVNode, inject, shallowRef, watch, nextTick, onBeforeUnmount, provide, toRef, createSlots, mergeProps, isRef, withDirectives, createTextVNode } from 'vue';
import { d as defaultWindow } from '../../chunk/BdDihk0t.mjs';
import Draggable from 'vuedraggable-es-fix';
import { C as Component$1 } from '../dialog/dialog.mjs';
import { C as Component$2 } from '../el-icon/el-icon.mjs';
import { E as ElIcon } from '../../chunk/m2vp1CCf.mjs';
import { WarningFilled, CircleCheck, CircleClose, Check, Close, Document, ZoomIn, Delete } from '@element-plus/icons-vue';
import { _ as _export_sfc, w as withInstall } from '../../chunk/D389hx_T.mjs';
import { m as mutable } from '../../chunk/B-rxnVJv.mjs';
import { u as useLocale } from '../../chunk/-m34CPRn.mjs';
import { b as useFormDisabled } from '../../chunk/BOAz6rgm.mjs';
import { e as entriesOf } from '../../chunk/DVNTpOBR.mjs';
import { c as cloneDeep } from '../../chunk/CyxEcbcy.mjs';
import { i as isEqual } from '../../chunk/-EkpfdcW.mjs';
import { a as useVModel } from '../../chunk/CEClY-_T.mjs';
import { _ as _export_sfc$1 } from '../../chunk/pcqpp-6-.mjs';
const progressProps = buildProps({
type: {
type: String,
default: "line",
values: ["line", "circle", "dashboard"]
},
percentage: {
type: Number,
default: 0,
validator: (val) => val >= 0 && val <= 100
},
status: {
type: String,
default: "",
values: ["", "success", "exception", "warning"]
},
indeterminate: Boolean,
duration: {
type: Number,
default: 3
},
strokeWidth: {
type: Number,
default: 6
},
strokeLinecap: {
type: definePropType(String),
default: "round"
},
textInside: Boolean,
width: {
type: Number,
default: 126
},
showText: {
type: Boolean,
default: true
},
color: {
type: definePropType([
String,
Array,
Function
]),
default: ""
},
striped: Boolean,
stripedFlow: Boolean,
format: {
type: definePropType(Function),
default: (percentage) => `${percentage}%`
}
});
const __default__$4 = defineComponent({
name: "ElProgress"
});
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
...__default__$4,
props: progressProps,
setup(__props) {
const props = __props;
const STATUS_COLOR_MAP = {
success: "#13ce66",
exception: "#ff4949",
warning: "#e6a23c",
default: "#20a0ff"
};
const ns = useNamespace("progress");
const barStyle = computed(() => {
const barStyle2 = {
width: `${props.percentage}%`,
animationDuration: `${props.duration}s`
};
const color = getCurrentColor(props.percentage);
if (color.includes("gradient")) {
barStyle2.background = color;
} else {
barStyle2.backgroundColor = color;
}
return barStyle2;
});
const relativeStrokeWidth = computed(() => (props.strokeWidth / props.width * 100).toFixed(1));
const radius = computed(() => {
if (["circle", "dashboard"].includes(props.type)) {
return Number.parseInt(`${50 - Number.parseFloat(relativeStrokeWidth.value) / 2}`, 10);
}
return 0;
});
const trackPath = computed(() => {
const r = radius.value;
const isDashboard = props.type === "dashboard";
return `
M 50 50
m 0 ${isDashboard ? "" : "-"}${r}
a ${r} ${r} 0 1 1 0 ${isDashboard ? "-" : ""}${r * 2}
a ${r} ${r} 0 1 1 0 ${isDashboard ? "" : "-"}${r * 2}
`;
});
const perimeter = computed(() => 2 * Math.PI * radius.value);
const rate = computed(() => props.type === "dashboard" ? 0.75 : 1);
const strokeDashoffset = computed(() => {
const offset = -1 * perimeter.value * (1 - rate.value) / 2;
return `${offset}px`;
});
const trailPathStyle = computed(() => ({
strokeDasharray: `${perimeter.value * rate.value}px, ${perimeter.value}px`,
strokeDashoffset: strokeDashoffset.value
}));
const circlePathStyle = computed(() => ({
strokeDasharray: `${perimeter.value * rate.value * (props.percentage / 100)}px, ${perimeter.value}px`,
strokeDashoffset: strokeDashoffset.value,
transition: "stroke-dasharray 0.6s ease 0s, stroke 0.6s ease, opacity ease 0.6s"
}));
const stroke = computed(() => {
let ret;
if (props.color) {
ret = getCurrentColor(props.percentage);
} else {
ret = STATUS_COLOR_MAP[props.status] || STATUS_COLOR_MAP.default;
}
return ret;
});
const statusIcon = computed(() => {
if (props.status === "warning") {
return WarningFilled;
}
if (props.type === "line") {
return props.status === "success" ? CircleCheck : CircleClose;
} else {
return props.status === "success" ? Check : Close;
}
});
const progressTextSize = computed(() => {
return props.type === "line" ? 12 + props.strokeWidth * 0.4 : props.width * 0.111111 + 2;
});
const content = computed(() => props.format(props.percentage));
function getColors(color) {
const span = 100 / color.length;
const seriesColors = color.map((seriesColor, index) => {
if (isString(seriesColor)) {
return {
color: seriesColor,
percentage: (index + 1) * span
};
}
return seriesColor;
});
return seriesColors.sort((a, b) => a.percentage - b.percentage);
}
const getCurrentColor = (percentage) => {
var _a;
const { color } = props;
if (isFunction(color)) {
return color(percentage);
} else if (isString(color)) {
return color;
} else {
const colors = getColors(color);
for (const color2 of colors) {
if (color2.percentage > percentage)
return color2.color;
}
return (_a = colors[colors.length - 1]) == null ? void 0 : _a.color;
}
};
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
class: normalizeClass([
unref(ns).b(),
unref(ns).m(_ctx.type),
unref(ns).is(_ctx.status),
{
[unref(ns).m("without-text")]: !_ctx.showText,
[unref(ns).m("text-inside")]: _ctx.textInside
}
]),
role: "progressbar",
"aria-valuenow": _ctx.percentage,
"aria-valuemin": "0",
"aria-valuemax": "100"
}, [
_ctx.type === "line" ? (openBlock(), createElementBlock("div", {
key: 0,
class: normalizeClass(unref(ns).b("bar"))
}, [
createElementVNode("div", {
class: normalizeClass(unref(ns).be("bar", "outer")),
style: normalizeStyle({ height: `${_ctx.strokeWidth}px` })
}, [
createElementVNode("div", {
class: normalizeClass([
unref(ns).be("bar", "inner"),
{ [unref(ns).bem("bar", "inner", "indeterminate")]: _ctx.indeterminate },
{ [unref(ns).bem("bar", "inner", "striped")]: _ctx.striped },
{ [unref(ns).bem("bar", "inner", "striped-flow")]: _ctx.stripedFlow }
]),
style: normalizeStyle(unref(barStyle))
}, [
(_ctx.showText || _ctx.$slots.default) && _ctx.textInside ? (openBlock(), createElementBlock("div", {
key: 0,
class: normalizeClass(unref(ns).be("bar", "innerText"))
}, [
renderSlot(_ctx.$slots, "default", { percentage: _ctx.percentage }, () => [
createElementVNode("span", null, toDisplayString(unref(content)), 1)
])
], 2)) : createCommentVNode("v-if", true)
], 6)
], 6)
], 2)) : (openBlock(), createElementBlock("div", {
key: 1,
class: normalizeClass(unref(ns).b("circle")),
style: normalizeStyle({ height: `${_ctx.width}px`, width: `${_ctx.width}px` })
}, [
(openBlock(), createElementBlock("svg", { viewBox: "0 0 100 100" }, [
createElementVNode("path", {
class: normalizeClass(unref(ns).be("circle", "track")),
d: unref(trackPath),
stroke: `var(${unref(ns).cssVarName("fill-color-light")}, #e5e9f2)`,
"stroke-linecap": _ctx.strokeLinecap,
"stroke-width": unref(relativeStrokeWidth),
fill: "none",
style: normalizeStyle(unref(trailPathStyle))
}, null, 14, ["d", "stroke", "stroke-linecap", "stroke-width"]),
createElementVNode("path", {
class: normalizeClass(unref(ns).be("circle", "path")),
d: unref(trackPath),
stroke: unref(stroke),
fill: "none",
opacity: _ctx.percentage ? 1 : 0,
"stroke-linecap": _ctx.strokeLinecap,
"stroke-width": unref(relativeStrokeWidth),
style: normalizeStyle(unref(circlePathStyle))
}, null, 14, ["d", "stroke", "opacity", "stroke-linecap", "stroke-width"])
]))
], 6)),
(_ctx.showText || _ctx.$slots.default) && !_ctx.textInside ? (openBlock(), createElementBlock("div", {
key: 2,
class: normalizeClass(unref(ns).e("text")),
style: normalizeStyle({ fontSize: `${unref(progressTextSize)}px` })
}, [
renderSlot(_ctx.$slots, "default", { percentage: _ctx.percentage }, () => [
!_ctx.status ? (openBlock(), createElementBlock("span", { key: 0 }, toDisplayString(unref(content)), 1)) : (openBlock(), createBlock(unref(ElIcon), { key: 1 }, {
default: withCtx(() => [
(openBlock(), createBlock(resolveDynamicComponent(unref(statusIcon))))
]),
_: 1
}))
])
], 6)) : createCommentVNode("v-if", true)
], 10, ["aria-valuenow"]);
};
}
});
var Progress = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__file", "progress.vue"]]);
const ElProgress = withInstall(Progress);
const uploadContextKey = Symbol("uploadContextKey");
const SCOPE$1 = "ElUpload";
class UploadAjaxError extends Error {
constructor(message, status, method, url) {
super(message);
this.name = "UploadAjaxError";
this.status = status;
this.method = method;
this.url = url;
}
}
function getError(action, option, xhr) {
let msg;
if (xhr.response) {
msg = `${xhr.response.error || xhr.response}`;
} else if (xhr.responseText) {
msg = `${xhr.responseText}`;
} else {
msg = `fail to ${option.method} ${action} ${xhr.status}`;
}
return new UploadAjaxError(msg, xhr.status, option.method, action);
}
function getBody(xhr) {
const text = xhr.responseText || xhr.response;
if (!text) {
return text;
}
try {
return JSON.parse(text);
} catch (e) {
return text;
}
}
const ajaxUpload = (option) => {
if (typeof XMLHttpRequest === "undefined")
throwError(SCOPE$1, "XMLHttpRequest is undefined");
const xhr = new XMLHttpRequest();
const action = option.action;
if (xhr.upload) {
xhr.upload.addEventListener("progress", (evt) => {
const progressEvt = evt;
progressEvt.percent = evt.total > 0 ? evt.loaded / evt.total * 100 : 0;
option.onProgress(progressEvt);
});
}
const formData = new FormData();
if (option.data) {
for (const [key, value] of Object.entries(option.data)) {
if (isArray(value) && value.length)
formData.append(key, ...value);
else
formData.append(key, value);
}
}
formData.append(option.filename, option.file, option.file.name);
xhr.addEventListener("error", () => {
option.onError(getError(action, option, xhr));
});
xhr.addEventListener("load", () => {
if (xhr.status < 200 || xhr.status >= 300) {
return option.onError(getError(action, option, xhr));
}
option.onSuccess(getBody(xhr));
});
xhr.open(option.method, action, true);
if (option.withCredentials && "withCredentials" in xhr) {
xhr.withCredentials = true;
}
const headers = option.headers || {};
if (headers instanceof Headers) {
headers.forEach((value, key) => xhr.setRequestHeader(key, value));
} else {
for (const [key, value] of Object.entries(headers)) {
if (isNil(value))
continue;
xhr.setRequestHeader(key, String(value));
}
}
xhr.send(formData);
return xhr;
};
const uploadListTypes = ["text", "picture", "picture-card"];
let fileId = 1;
const genFileId = () => Date.now() + fileId++;
const uploadBaseProps = buildProps({
action: {
type: String,
default: "#"
},
headers: {
type: definePropType(Object)
},
method: {
type: String,
default: "post"
},
data: {
type: definePropType([Object, Function, Promise]),
default: () => mutable({})
},
multiple: Boolean,
name: {
type: String,
default: "file"
},
drag: Boolean,
withCredentials: Boolean,
showFileList: {
type: Boolean,
default: true
},
accept: {
type: String,
default: ""
},
fileList: {
type: definePropType(Array),
default: () => mutable([])
},
autoUpload: {
type: Boolean,
default: true
},
listType: {
type: String,
values: uploadListTypes,
default: "text"
},
httpRequest: {
type: definePropType(Function),
default: ajaxUpload
},
disabled: Boolean,
limit: Number
});
const uploadProps = buildProps({
...uploadBaseProps,
beforeUpload: {
type: definePropType(Function),
default: NOOP
},
beforeRemove: {
type: definePropType(Function)
},
onRemove: {
type: definePropType(Function),
default: NOOP
},
onChange: {
type: definePropType(Function),
default: NOOP
},
onPreview: {
type: definePropType(Function),
default: NOOP
},
onSuccess: {
type: definePropType(Function),
default: NOOP
},
onProgress: {
type: definePropType(Function),
default: NOOP
},
onError: {
type: definePropType(Function),
default: NOOP
},
onExceed: {
type: definePropType(Function),
default: NOOP
},
crossorigin: {
type: definePropType(String)
}
});
const uploadListProps = buildProps({
files: {
type: definePropType(Array),
default: () => mutable([])
},
disabled: Boolean,
handlePreview: {
type: definePropType(Function),
default: NOOP
},
listType: {
type: String,
values: uploadListTypes,
default: "text"
},
crossorigin: {
type: definePropType(String)
}
});
const uploadListEmits = {
remove: (file) => !!file
};
const __default__$3 = defineComponent({
name: "ElUploadList"
});
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
...__default__$3,
props: uploadListProps,
emits: uploadListEmits,
setup(__props, { emit }) {
const props = __props;
const { t } = useLocale();
const nsUpload = useNamespace("upload");
const nsIcon = useNamespace("icon");
const nsList = useNamespace("list");
const disabled = useFormDisabled();
const focusing = ref(false);
const containerKls = computed(() => [
nsUpload.b("list"),
nsUpload.bm("list", props.listType),
nsUpload.is("disabled", props.disabled)
]);
const handleRemove = (file) => {
emit("remove", file);
};
return (_ctx, _cache) => {
return openBlock(), createBlock(TransitionGroup, {
tag: "ul",
class: normalizeClass(unref(containerKls)),
name: unref(nsList).b()
}, {
default: withCtx(() => [
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.files, (file, index) => {
return openBlock(), createElementBlock("li", {
key: file.uid || file.name,
class: normalizeClass([
unref(nsUpload).be("list", "item"),
unref(nsUpload).is(file.status),
{ focusing: focusing.value }
]),
tabindex: unref(disabled) ? void 0 : 0,
"aria-disabled": unref(disabled),
role: "button",
onKeydown: withKeys(($event) => !unref(disabled) && handleRemove(file), ["delete"]),
onFocus: ($event) => focusing.value = true,
onBlur: ($event) => focusing.value = false,
onClick: ($event) => focusing.value = false
}, [
renderSlot(_ctx.$slots, "default", {
file,
index
}, () => [
_ctx.listType === "picture" || file.status !== "uploading" && _ctx.listType === "picture-card" ? (openBlock(), createElementBlock("img", {
key: 0,
class: normalizeClass(unref(nsUpload).be("list", "item-thumbnail")),
src: file.url,
crossorigin: _ctx.crossorigin,
alt: ""
}, null, 10, ["src", "crossorigin"])) : createCommentVNode("v-if", true),
file.status === "uploading" || _ctx.listType !== "picture-card" ? (openBlock(), createElementBlock("div", {
key: 1,
class: normalizeClass(unref(nsUpload).be("list", "item-info"))
}, [
createElementVNode("a", {
class: normalizeClass(unref(nsUpload).be("list", "item-name")),
onClick: withModifiers(($event) => _ctx.handlePreview(file), ["prevent"])
}, [
createVNode(unref(ElIcon), {
class: normalizeClass(unref(nsIcon).m("document"))
}, {
default: withCtx(() => [
createVNode(unref(Document))
]),
_: 1
}, 8, ["class"]),
createElementVNode("span", {
class: normalizeClass(unref(nsUpload).be("list", "item-file-name")),
title: file.name
}, toDisplayString(file.name), 11, ["title"])
], 10, ["onClick"]),
file.status === "uploading" ? (openBlock(), createBlock(unref(ElProgress), {
key: 0,
type: _ctx.listType === "picture-card" ? "circle" : "line",
"stroke-width": _ctx.listType === "picture-card" ? 6 : 2,
percentage: Number(file.percentage),
style: normalizeStyle(_ctx.listType === "picture-card" ? "" : "margin-top: 0.5rem")
}, null, 8, ["type", "stroke-width", "percentage", "style"])) : createCommentVNode("v-if", true)
], 2)) : createCommentVNode("v-if", true),
createElementVNode("label", {
class: normalizeClass(unref(nsUpload).be("list", "item-status-label"))
}, [
_ctx.listType === "text" ? (openBlock(), createBlock(unref(ElIcon), {
key: 0,
class: normalizeClass([unref(nsIcon).m("upload-success"), unref(nsIcon).m("circle-check")])
}, {
default: withCtx(() => [
createVNode(unref(CircleCheck))
]),
_: 1
}, 8, ["class"])) : ["picture-card", "picture"].includes(_ctx.listType) ? (openBlock(), createBlock(unref(ElIcon), {
key: 1,
class: normalizeClass([unref(nsIcon).m("upload-success"), unref(nsIcon).m("check")])
}, {
default: withCtx(() => [
createVNode(unref(Check))
]),
_: 1
}, 8, ["class"])) : createCommentVNode("v-if", true)
], 2),
!unref(disabled) ? (openBlock(), createBlock(unref(ElIcon), {
key: 2,
class: normalizeClass(unref(nsIcon).m("close")),
onClick: ($event) => handleRemove(file)
}, {
default: withCtx(() => [
createVNode(unref(Close))
]),
_: 2
}, 1032, ["class", "onClick"])) : createCommentVNode("v-if", true),
createCommentVNode(" Due to close btn only appears when li gets focused disappears after li gets blurred, thus keyboard navigation can never reach close btn"),
createCommentVNode(" This is a bug which needs to be fixed "),
createCommentVNode(" TODO: Fix the incorrect navigation interaction "),
!unref(disabled) ? (openBlock(), createElementBlock("i", {
key: 3,
class: normalizeClass(unref(nsIcon).m("close-tip"))
}, toDisplayString(unref(t)("el.upload.deleteTip")), 3)) : createCommentVNode("v-if", true),
_ctx.listType === "picture-card" ? (openBlock(), createElementBlock("span", {
key: 4,
class: normalizeClass(unref(nsUpload).be("list", "item-actions"))
}, [
createElementVNode("span", {
class: normalizeClass(unref(nsUpload).be("list", "item-preview")),
onClick: ($event) => _ctx.handlePreview(file)
}, [
createVNode(unref(ElIcon), {
class: normalizeClass(unref(nsIcon).m("zoom-in"))
}, {
default: withCtx(() => [
createVNode(unref(ZoomIn))
]),
_: 1
}, 8, ["class"])
], 10, ["onClick"]),
!unref(disabled) ? (openBlock(), createElementBlock("span", {
key: 0,
class: normalizeClass(unref(nsUpload).be("list", "item-delete")),
onClick: ($event) => handleRemove(file)
}, [
createVNode(unref(ElIcon), {
class: normalizeClass(unref(nsIcon).m("delete"))
}, {
default: withCtx(() => [
createVNode(unref(Delete))
]),
_: 1
}, 8, ["class"])
], 10, ["onClick"])) : createCommentVNode("v-if", true)
], 2)) : createCommentVNode("v-if", true)
])
], 42, ["tabindex", "aria-disabled", "onKeydown", "onFocus", "onBlur", "onClick"]);
}), 128)),
renderSlot(_ctx.$slots, "append")
]),
_: 3
}, 8, ["class", "name"]);
};
}
});
var UploadList = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__file", "upload-list.vue"]]);
const uploadDraggerProps = buildProps({
disabled: Boolean
});
const uploadDraggerEmits = {
file: (file) => isArray(file)
};
const COMPONENT_NAME = "ElUploadDrag";
const __default__$2 = defineComponent({
name: COMPONENT_NAME
});
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
...__default__$2,
props: uploadDraggerProps,
emits: uploadDraggerEmits,
setup(__props, { emit }) {
const uploaderContext = inject(uploadContextKey);
if (!uploaderContext) {
throwError(COMPONENT_NAME, "usage: <el-upload><el-upload-dragger /></el-upload>");
}
const ns = useNamespace("upload");
const dragover = ref(false);
const disabled = useFormDisabled();
const onDrop = (e) => {
if (disabled.value)
return;
dragover.value = false;
e.stopPropagation();
const files = Array.from(e.dataTransfer.files);
const items = e.dataTransfer.items || [];
files.forEach((file, index) => {
var _a;
const item = items[index];
const entry = (_a = item == null ? void 0 : item.webkitGetAsEntry) == null ? void 0 : _a.call(item);
if (entry) {
file.isDirectory = entry.isDirectory;
}
});
emit("file", files);
};
const onDragover = () => {
if (!disabled.value)
dragover.value = true;
};
const onDragleave = (e) => {
if (!e.currentTarget.contains(e.relatedTarget))
dragover.value = false;
};
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
class: normalizeClass([unref(ns).b("dragger"), unref(ns).is("dragover", dragover.value)]),
onDrop: withModifiers(onDrop, ["prevent"]),
onDragover: withModifiers(onDragover, ["prevent"]),
onDragleave: withModifiers(onDragleave, ["prevent"])
}, [
renderSlot(_ctx.$slots, "default")
], 42, ["onDrop", "onDragover", "onDragleave"]);
};
}
});
var UploadDragger = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__file", "upload-dragger.vue"]]);
const uploadContentProps = buildProps({
...uploadBaseProps,
beforeUpload: {
type: definePropType(Function),
default: NOOP
},
onRemove: {
type: definePropType(Function),
default: NOOP
},
onStart: {
type: definePropType(Function),
default: NOOP
},
onSuccess: {
type: definePropType(Function),
default: NOOP
},
onProgress: {
type: definePropType(Function),
default: NOOP
},
onError: {
type: definePropType(Function),
default: NOOP
},
onExceed: {
type: definePropType(Function),
default: NOOP
}
});
const __default__$1 = defineComponent({
name: "ElUploadContent",
inheritAttrs: false
});
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
...__default__$1,
props: uploadContentProps,
setup(__props, { expose }) {
const props = __props;
const ns = useNamespace("upload");
const disabled = useFormDisabled();
const requests = shallowRef({});
const inputRef = shallowRef();
const uploadFiles = (files) => {
if (files.length === 0)
return;
const { autoUpload, limit, fileList, multiple, onStart, onExceed } = props;
if (limit && fileList.length + files.length > limit) {
onExceed(files, fileList);
return;
}
if (!multiple) {
files = files.slice(0, 1);
}
for (const file of files) {
const rawFile = file;
rawFile.uid = genFileId();
onStart(rawFile);
if (autoUpload)
upload(rawFile);
}
};
const upload = async (rawFile) => {
inputRef.value.value = "";
if (!props.beforeUpload) {
return doUpload(rawFile);
}
let hookResult;
let beforeData = {};
try {
const originData = props.data;
const beforeUploadPromise = props.beforeUpload(rawFile);
beforeData = isPlainObject(props.data) ? cloneDeep(props.data) : props.data;
hookResult = await beforeUploadPromise;
if (isPlainObject(props.data) && isEqual(originData, beforeData)) {
beforeData = cloneDeep(props.data);
}
} catch (e) {
hookResult = false;
}
if (hookResult === false) {
props.onRemove(rawFile);
return;
}
let file = rawFile;
if (hookResult instanceof Blob) {
if (hookResult instanceof File) {
file = hookResult;
} else {
file = new File([hookResult], rawFile.name, {
type: rawFile.type
});
}
}
doUpload(Object.assign(file, {
uid: rawFile.uid
}), beforeData);
};
const resolveData = async (data, rawFile) => {
if (isFunction(data)) {
return data(rawFile);
}
return data;
};
const doUpload = async (rawFile, beforeData) => {
const {
headers,
data,
method,
withCredentials,
name: filename,
action,
onProgress,
onSuccess,
onError,
httpRequest
} = props;
try {
beforeData = await resolveData(beforeData != null ? beforeData : data, rawFile);
} catch (e) {
props.onRemove(rawFile);
return;
}
const { uid } = rawFile;
const options = {
headers: headers || {},
withCredentials,
file: rawFile,
data: beforeData,
method,
filename,
action,
onProgress: (evt) => {
onProgress(evt, rawFile);
},
onSuccess: (res) => {
onSuccess(res, rawFile);
delete requests.value[uid];
},
onError: (err) => {
onError(err, rawFile);
delete requests.value[uid];
}
};
const request = httpRequest(options);
requests.value[uid] = request;
if (request instanceof Promise) {
request.then(options.onSuccess, options.onError);
}
};
const handleChange = (e) => {
const files = e.target.files;
if (!files)
return;
uploadFiles(Array.from(files));
};
const handleClick = () => {
if (!disabled.value) {
inputRef.value.value = "";
inputRef.value.click();
}
};
const handleKeydown = () => {
handleClick();
};
const abort = (file) => {
const _reqs = entriesOf(requests.value).filter(file ? ([uid]) => String(file.uid) === uid : () => true);
_reqs.forEach(([uid, req]) => {
if (req instanceof XMLHttpRequest)
req.abort();
delete requests.value[uid];
});
};
expose({
abort,
upload
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
class: normalizeClass([
unref(ns).b(),
unref(ns).m(_ctx.listType),
unref(ns).is("drag", _ctx.drag),
unref(ns).is("disabled", unref(disabled))
]),
tabindex: unref(disabled) ? void 0 : 0,
"aria-disabled": unref(disabled),
role: "button",
onClick: handleClick,
onKeydown: withKeys(withModifiers(handleKeydown, ["self"]), ["enter", "space"])
}, [
_ctx.drag ? (openBlock(), createBlock(UploadDragger, {
key: 0,
disabled: unref(disabled),
onFile: uploadFiles
}, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "default")
]),
_: 3
}, 8, ["disabled"])) : renderSlot(_ctx.$slots, "default", { key: 1 }),
createElementVNode("input", {
ref_key: "inputRef",
ref: inputRef,
class: normalizeClass(unref(ns).e("input")),
name: _ctx.name,
disabled: unref(disabled),
multiple: _ctx.multiple,
accept: _ctx.accept,
type: "file",
onChange: handleChange,
onClick: withModifiers(() => {
}, ["stop"])
}, null, 42, ["name", "disabled", "multiple", "accept", "onClick"])
], 42, ["tabindex", "aria-disabled", "onKeydown"]);
};
}
});
var UploadContent = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__file", "upload-content.vue"]]);
const SCOPE = "ElUpload";
const revokeFileObjectURL = (file) => {
var _a;
if ((_a = file.url) == null ? void 0 : _a.startsWith("blob:")) {
URL.revokeObjectURL(file.url);
}
};
const useHandlers = (props, uploadRef) => {
const uploadFiles = useVModel(props, "fileList", void 0, { passive: true });
const getFile = (rawFile) => uploadFiles.value.find((file) => file.uid === rawFile.uid);
function abort(file) {
var _a;
(_a = uploadRef.value) == null ? void 0 : _a.abort(file);
}
function clearFiles(states = ["ready", "uploading", "success", "fail"]) {
uploadFiles.value = uploadFiles.value.filter((row) => !states.includes(row.status));
}
function removeFile(file) {
uploadFiles.value = uploadFiles.value.filter((uploadFile) => uploadFile.uid !== file.uid);
}
const emitChange = (file) => {
nextTick(() => props.onChange(file, uploadFiles.value));
};
const handleError = (err, rawFile) => {
const file = getFile(rawFile);
if (!file)
return;
console.error(err);
file.status = "fail";
removeFile(file);
props.onError(err, file, uploadFiles.value);
emitChange(file);
};
const handleProgress = (evt, rawFile) => {
const file = getFile(rawFile);
if (!file)
return;
props.onProgress(evt, file, uploadFiles.value);
file.status = "uploading";
file.percentage = Math.round(evt.percent);
};
const handleSuccess = (response, rawFile) => {
const file = getFile(rawFile);
if (!file)
return;
file.status = "success";
file.response = response;
props.onSuccess(response, file, uploadFiles.value);
emitChange(file);
};
const handleStart = (file) => {
if (isNil(file.uid))
file.uid = genFileId();
const uploadFile = {
name: file.name,
percentage: 0,
status: "ready",
size: file.size,
raw: file,
uid: file.uid
};
if (props.listType === "picture-card" || props.listType === "picture") {
try {
uploadFile.url = URL.createObjectURL(file);
} catch (err) {
debugWarn(SCOPE, err.message);
props.onError(err, uploadFile, uploadFiles.value);
}
}
uploadFiles.value = [...uploadFiles.value, uploadFile];
emitChange(uploadFile);
};
const handleRemove = async (file) => {
const uploadFile = file instanceof File ? getFile(file) : file;
if (!uploadFile)
throwError(SCOPE, "file to be removed not found");
const doRemove = (file2) => {
abort(file2);
removeFile(file2);
props.onRemove(file2, uploadFiles.value);
revokeFileObjectURL(file2);
};
if (props.beforeRemove) {
const before = await props.beforeRemove(uploadFile, uploadFiles.value);
if (before !== false)
doRemove(uploadFile);
} else {
doRemove(uploadFile);
}
};
function submit() {
uploadFiles.value.filter(({ status }) => status === "ready").forEach(({ raw }) => {
var _a;
return raw && ((_a = uploadRef.value) == null ? void 0 : _a.upload(raw));
});
}
watch(() => props.listType, (val) => {
if (val !== "picture-card" && val !== "picture") {
return;
}
uploadFiles.value = uploadFiles.value.map((file) => {
const { raw, url } = file;
if (!url && raw) {
try {
file.url = URL.createObjectURL(raw);
} catch (err) {
props.onError(err, file, uploadFiles.value);
}
}
return file;
});
});
watch(uploadFiles, (files) => {
for (const file of files) {
file.uid || (file.uid = genFileId());
file.status || (file.status = "success");
}
}, { immediate: true, deep: true });
return {
uploadFiles,
abort,
clearFiles,
handleError,
handleProgress,
handleStart,
handleSuccess,
handleRemove,
submit,
revokeFileObjectURL
};
};
const __default__ = defineComponent({
name: "ElUpload"
});
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
...__default__,
props: uploadProps,
setup(__props, { expose }) {
const props = __props;
const disabled = useFormDisabled();
const uploadRef = shallowRef();
const {
abort,
submit,
clearFiles,
uploadFiles,
handleStart,
handleError,
handleRemove,
handleSuccess,
handleProgress,
revokeFileObjectURL
} = useHandlers(props, uploadRef);
const isPictureCard = computed(() => props.listType === "picture-card");
const uploadContentProps = computed(() => ({
...props,
fileList: uploadFiles.value,
onStart: handleStart,
onProgress: handleProgress,
onSuccess: handleSuccess,
onError: handleError,
onRemove: handleRemove
}));
onBeforeUnmount(() => {
uploadFiles.value.forEach(revokeFileObjectURL);
});
provide(uploadContextKey, {
accept: toRef(props, "accept")
});
expose({
abort,
submit,
clearFiles,
handleStart,
handleRemove
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", null, [
unref(isPictureCard) && _ctx.showFileList ? (openBlock(), createBlock(UploadList, {
key: 0,
disabled: unref(disabled),
"list-type": _ctx.listType,
files: unref(uploadFiles),
crossorigin: _ctx.crossorigin,
"handle-preview": _ctx.onPreview,
onRemove: unref(handleRemove)
}, createSlots({
append: withCtx(() => [
createVNode(UploadContent, mergeProps({
ref_key: "uploadRef",
ref: uploadRef
}, unref(uploadContentProps)), {
default: withCtx(() => [
_ctx.$slots.trigger ? renderSlot(_ctx.$slots, "trigger", { key: 0 }) : createCommentVNode("v-if", true),
!_ctx.$slots.trigger && _ctx.$slots.default ? renderSlot(_ctx.$slots, "default", { key: 1 }) : createCommentVNode("v-if", true)
]),
_: 3
}, 16)
]),
_: 2
}, [
_ctx.$slots.file ? {
name: "default",
fn: withCtx(({ file, index }) => [
renderSlot(_ctx.$slots, "file", {
file,
index
})
])
} : void 0
]), 1032, ["disabled", "list-type", "files", "crossorigin", "handle-preview", "onRemove"])) : createCommentVNode("v-if", true),
!unref(isPictureCard) || unref(isPictureCard) && !_ctx.showFileList ? (openBlock(), createBlock(UploadContent, mergeProps({
key: 1,
ref_key: "uploadRef",
ref: uploadRef
}, unref(uploadContentProps)), {
default: withCtx(() => [
_ctx.$slots.trigger ? renderSlot(_ctx.$slots, "trigger", { key: 0 }) : createCommentVNode("v-if", true),
!_ctx.$slots.trigger && _ctx.$slots.default ? renderSlot(_ctx.$slots, "default", { key: 1 }) : createCommentVNode("v-if", true)
]),
_: 3
}, 16)) : createCommentVNode("v-if", true),
_ctx.$slots.trigger ? renderSlot(_ctx.$slots, "default", { key: 2 }) : createCommentVNode("v-if", true),
renderSlot(_ctx.$slots, "tip"),
!unref(isPictureCard) && _ctx.showFileList ? (openBlock(), createBlock(UploadList, {
key: 3,
disabled: unref(disabled),
"list-type": _ctx.listType,
files: unref(uploadFiles),
crossorigin: _ctx.crossorigin,
"handle-preview": _ctx.onPreview,
onRemove: unref(handleRemove)
}, createSlots({
_: 2
}, [
_ctx.$slots.file ? {
name: "default",
fn: withCtx(({ file, index }) => [
renderSlot(_ctx.$slots, "file", {
file,
index
})
])
} : void 0
]), 1032, ["disabled", "list-type", "files", "crossorigin", "handle-preview", "onRemove"])) : createCommentVNode("v-if", true)
]);
};
}
});
var Upload = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__file", "upload.vue"]]);
const ElUpload = withInstall(Upload);
const _hoisted_1 = { class: "el-upload-list__item" };
const _hoisted_2 = ["src"];
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "dialog-upload-images",
props: {
modelValue: {},
visible: { type: Boolean },
destroyOnClose: { type: Boolean, default: false },
limit: { default: 5 },
maxSize: { default: 2 * 1024 * 1024 },
httpRequest: {},
beforeUpload: { type: Function, default: () => true },
beforeRemove: { type: Function, default: () => true }
},
emits: ["update:visible", "update:modelValue", "error", "close"],
setup(__props, { emit: __emit }) {
const props = __props;
const emits = __emit;
const loading = ref(false);
const imgList = shallowRef(props.modelValue);
const dialogVisible = computed({
get: () => props.visible,
set: (val) => {
emits("update:visible", val);
if (!val) {
emits("close");
}
}
});
function getImgUrl(file) {
if (!defaultWindow) {
return "";
}
const data = file;
if (data.url) {
return data.url;
}
return defaultWindow.URL.createObjectURL(data);
}
function handleConfirm() {
emits("update:modelValue", imgList.value);
dialogVisible.value = false;
}
async function handleHttpRequest({ file }) {
const myUploadFile = await props.httpRequest(file) || file;
imgList.value = [...imgList.value, myUploadFile];
loading.value = false;
}
function handleBeforeUpload(file) {
if (file.size > props.maxSize) {
const message = `文件大小不能超过${props.maxSize / 1024 / 1024}M`;
emits("error", message);
return false;
}
if (props.beforeUpload) {
if (props.beforeUpload(file)) {
loading.value = true;
return true;
}
return false;
}
loading.value = true;
return true;
}
async function handleBeforeRemove(file, fileList) {
if (props.beforeRemove) {
loading.value = true;
const result = await props.beforeRemove(file, fileList);
loading.value = false;
return result;
}
return true;
}
async function handleOnRemove(file) {
const result = await handleBeforeRemove(file, imgList.value);
if (!result) {
return;
}
const index = imgList.value.findIndex((item) => item === file);
imgList.value.splice(index, 1);
imgList.value = [...imgList.value];
}
function handleOnExceed() {
const message = `文件数量不能超过 ${props.limit} 个`;
emits("error", message);
}
function handleOnPreview(file) {
defaultWindow && defaultWindow.open(getImgUrl(file));
}
return (_ctx, _cache) => {
const _component_ElUpload = ElUpload;
const _component_ElButton = ElButton;
const _directive_loading = vLoading;
return openBlock(), createBlock(Component$1, mergeProps({
modelValue: unref(dialogVisible),
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => isRef(dialogVisible) ? dialogVisible.value = $event : null),
title: "上传图片",
"close-on-click-modal": false,
class: _ctx.$style.dialog,
width: 862,
"show-close": false,
"destroy-on-close": __props.destroyOnClose,
"append-to-body": ""
}, _ctx.$attrs), {
footer: withCtx(() => [
createVNode(_component_ElButton, {
type: "primary",
loading: unref(loading),
onClick: handleConfirm
}, {
default: withCtx(() => [..._cache[2] || (_cache[2] = [
createTextVNode("确 定", -1)
])]),
_: 1
}, 8, ["loading"])
]),
default: withCtx(() => [
createVNode(unref(Draggable), {
modelValue: unref(imgList),
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(imgList) ? imgList.value = $event : null),
"item-key": "uid",
class: normalizeClass(["el-upload-list--picture-card", [_ctx.$style.draggable]])
}, {
header: withCtx(() => [
withDirectives((openBlock(), createBlock(_component_ElUpload, {
multiple: "",
action: "",
"file-list": __props.modelValue,
"show-file-list": false,
"http-request": handleHttpRequest,
"before-upload": handleBeforeUpload,
accept: ".jpg,.jpeg,.png",
class: normalizeClass(_ctx.$style.upload),
limit: __props.limit,
"on-exceed": handleOnExceed
}, {
default: withCtx(() => [
createVNode(Component$2, { name: "Plus" })
]),
_: 1
}, 8, ["file-list", "class", "limit"])), [
[_directive_loading, unref(loading)]
])
]),
item: withCtx(({ element }) => [
createElementVNode("div", _hoisted_1, [
createElementVNode("img", {
class: "el-upload-list__item-thumbnail",
src: getImgUrl(element)
}, null, 8, _hoisted_2),
createElementVNode("span", {
class: normalizeClass(["el-upload-list__item-actions", [_ctx.$style.opration]])
}, [
createVNode(Component$2, {
name: "ZoomIn",
onClick: ($event) => handleOnPreview(element)
}, null, 8, ["onClick"]),
createVNode(Component$2, {
name: "Delete",
onClick: ($event) => handleOnRemove(element)
}, null, 8, ["onClick"])
], 2)
])
]),
_: 1
}, 8, ["modelValue", "class"])
]),
_: 1
}, 16, ["modelValue", "class", "destroy-on-close"]);
};
}
});
/* unplugin-vue-components disabled */const dialog = "_dialog_1gadx_1";
const upload = "_upload_1gadx_9";
const opration = "_opration_1gadx_35";
const draggable = "_draggable_1gadx_48";
const style0 = {
dialog: dialog,
upload: upload,
opration: opration,
draggable: draggable
};
const cssModules = {
"$style": style0
};
const Component = /* @__PURE__ */ _export_sfc$1(_sfc_main, [["__cssModules", cssModules]]);
const __vite_glob_0_12 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
__proto__: null,
default: Component
}, Symbol.toStringTag, { value: 'Module' }));
export { Component as C, __vite_glob_0_12 as _ };