UNPKG

@wfrog/vc

Version:

vue3 组件库 vc

1,383 lines (1,362 loc) 46.6 kB
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 _ };