@sia.soul/sia-react-ui 0.1.27 → 0.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-5MW3NE2V.js → chunk-DQYNL6VZ.js} +62 -10
- package/dist/{chunk-NAOV53NK.js → chunk-I5KAI6FC.js} +386 -96
- package/dist/{chunk-IQU4GGLM.js → chunk-T2EKKSCH.js} +1 -1
- package/dist/{core-BM-wnJRa.d.cts → core-C_aAA7OF.d.cts} +135 -78
- package/dist/{core-CLqv6btD.d.ts → core-CuszFlw9.d.ts} +135 -78
- package/dist/core.cjs +372 -73
- package/dist/core.css +231 -3
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +2 -2
- package/dist/index.cjs +447 -109
- package/dist/index.css +231 -3
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +23 -27
- package/dist/select-date-range.js +2 -2
- package/package.json +1 -1
package/dist/core.cjs
CHANGED
|
@@ -2488,6 +2488,15 @@ function Collapse({ items, activeKey, defaultActiveKey = [], accordion = false,
|
|
|
2488
2488
|
] }, item.key);
|
|
2489
2489
|
}) });
|
|
2490
2490
|
}
|
|
2491
|
+
function ImagePreview({ open, src, alt = "", onOpenChange }) {
|
|
2492
|
+
const previewRef = (0, import_react15.useRef)(null);
|
|
2493
|
+
useOverlayLifecycle(open, previewRef, () => onOpenChange(false));
|
|
2494
|
+
if (!open || !src || typeof document === "undefined") return null;
|
|
2495
|
+
return (0, import_react_dom5.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { ref: previewRef, className: "sia-image-preview", role: "dialog", "aria-modal": "true", "aria-label": "\u56FE\u7247\u9884\u89C8", tabIndex: -1, onClick: () => onOpenChange(false), children: [
|
|
2496
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", "aria-label": "\u5173\u95ED\u9884\u89C8", onClick: () => onOpenChange(false), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "close" }) }),
|
|
2497
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("img", { src, alt, onClick: (event) => event.stopPropagation() })
|
|
2498
|
+
] }), document.body);
|
|
2499
|
+
}
|
|
2491
2500
|
|
|
2492
2501
|
// src/components/FloatingPlaceholder.tsx
|
|
2493
2502
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
@@ -3930,136 +3939,426 @@ var Select = (0, import_react22.forwardRef)(function Select2({
|
|
|
3930
3939
|
|
|
3931
3940
|
// src/components/Upload.tsx
|
|
3932
3941
|
var import_react23 = require("react");
|
|
3942
|
+
|
|
3943
|
+
// src/components/uploadFiles.ts
|
|
3944
|
+
function acceptsUploadFile(file, accept) {
|
|
3945
|
+
if (!accept?.trim()) return true;
|
|
3946
|
+
return accept.split(",").some((part) => {
|
|
3947
|
+
const rule = part.trim().toLowerCase();
|
|
3948
|
+
const type = file.type.toLowerCase();
|
|
3949
|
+
return rule.startsWith(".") ? file.name.toLowerCase().endsWith(rule) : rule.endsWith("/*") ? type.startsWith(rule.slice(0, -1)) : type === rule;
|
|
3950
|
+
});
|
|
3951
|
+
}
|
|
3952
|
+
function includeUploadPath(path, recursive) {
|
|
3953
|
+
return recursive || path.split("/").filter(Boolean).length <= 2;
|
|
3954
|
+
}
|
|
3955
|
+
async function readUploadEntries(entries, recursive) {
|
|
3956
|
+
const files = [];
|
|
3957
|
+
async function visit(entry, path, depth) {
|
|
3958
|
+
if (entry.isFile) {
|
|
3959
|
+
const file = await new Promise((resolve, reject) => entry.file(resolve, reject));
|
|
3960
|
+
files.push({ file, path });
|
|
3961
|
+
} else if (entry.isDirectory && (recursive || depth === 0)) {
|
|
3962
|
+
const reader = entry.createReader();
|
|
3963
|
+
while (true) {
|
|
3964
|
+
const batch = await new Promise((resolve, reject) => reader.readEntries(resolve, reject));
|
|
3965
|
+
if (!batch.length) break;
|
|
3966
|
+
for (const child of batch) await visit(child, `${path}/${child.name}`, depth + 1);
|
|
3967
|
+
}
|
|
3968
|
+
}
|
|
3969
|
+
}
|
|
3970
|
+
for (const entry of entries) await visit(entry, entry.name, 0);
|
|
3971
|
+
return files;
|
|
3972
|
+
}
|
|
3973
|
+
|
|
3974
|
+
// src/components/uploadRequest.ts
|
|
3975
|
+
function sendUploadRequest(config, options) {
|
|
3976
|
+
const xhr = new XMLHttpRequest();
|
|
3977
|
+
const abort = () => xhr.abort();
|
|
3978
|
+
const cleanup2 = () => options.signal.removeEventListener("abort", abort);
|
|
3979
|
+
xhr.open(config.method ?? "POST", config.action, true);
|
|
3980
|
+
xhr.withCredentials = config.withCredentials ?? false;
|
|
3981
|
+
xhr.timeout = config.timeout ?? 0;
|
|
3982
|
+
for (const [name, value] of Object.entries(config.headers ?? {})) xhr.setRequestHeader(name, value);
|
|
3983
|
+
xhr.upload.onprogress = (event) => {
|
|
3984
|
+
if (event.lengthComputable) options.onProgress(event.loaded / event.total * 100);
|
|
3985
|
+
};
|
|
3986
|
+
xhr.onload = () => {
|
|
3987
|
+
cleanup2();
|
|
3988
|
+
if (xhr.status < 200 || xhr.status >= 300) {
|
|
3989
|
+
options.onError(new Error(`\u4E0A\u4F20\u5931\u8D25\uFF1AHTTP ${xhr.status}`));
|
|
3990
|
+
return;
|
|
3991
|
+
}
|
|
3992
|
+
let response = xhr.responseText;
|
|
3993
|
+
try {
|
|
3994
|
+
response = JSON.parse(xhr.responseText);
|
|
3995
|
+
} catch {
|
|
3996
|
+
}
|
|
3997
|
+
options.onSuccess(response, config.url);
|
|
3998
|
+
};
|
|
3999
|
+
xhr.onerror = () => {
|
|
4000
|
+
cleanup2();
|
|
4001
|
+
options.onError(new Error("\u4E0A\u4F20\u7F51\u7EDC\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u8FDE\u63A5\u4E0E\u8DE8\u57DF\u914D\u7F6E"));
|
|
4002
|
+
};
|
|
4003
|
+
xhr.ontimeout = () => {
|
|
4004
|
+
cleanup2();
|
|
4005
|
+
options.onError(new Error("\u4E0A\u4F20\u8D85\u65F6"));
|
|
4006
|
+
};
|
|
4007
|
+
xhr.onabort = cleanup2;
|
|
4008
|
+
options.signal.addEventListener("abort", abort, { once: true });
|
|
4009
|
+
if (options.signal.aborted) {
|
|
4010
|
+
cleanup2();
|
|
4011
|
+
return { abort };
|
|
4012
|
+
}
|
|
4013
|
+
try {
|
|
4014
|
+
if (config.body === "file") xhr.send(options.file);
|
|
4015
|
+
else {
|
|
4016
|
+
const body = new FormData();
|
|
4017
|
+
for (const [name, value] of Object.entries(config.data ?? {})) body.append(name, value);
|
|
4018
|
+
body.append(config.name ?? "file", options.file, options.filename);
|
|
4019
|
+
xhr.send(body);
|
|
4020
|
+
}
|
|
4021
|
+
} catch (error) {
|
|
4022
|
+
cleanup2();
|
|
4023
|
+
throw error;
|
|
4024
|
+
}
|
|
4025
|
+
return { abort };
|
|
4026
|
+
}
|
|
4027
|
+
|
|
4028
|
+
// src/components/Upload.tsx
|
|
3933
4029
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3934
4030
|
var LIST_IGNORE = /* @__PURE__ */ Symbol("SIA_UPLOAD_LIST_IGNORE");
|
|
3935
|
-
function
|
|
4031
|
+
function useThumbnail(file) {
|
|
4032
|
+
const [local, setLocal] = (0, import_react23.useState)();
|
|
4033
|
+
(0, import_react23.useEffect)(() => {
|
|
4034
|
+
if (!file?.thumbUrl && file?.originFileObj?.type.startsWith("image/")) {
|
|
4035
|
+
const url = URL.createObjectURL(file.originFileObj);
|
|
4036
|
+
setLocal(url);
|
|
4037
|
+
return () => URL.revokeObjectURL(url);
|
|
4038
|
+
}
|
|
4039
|
+
setLocal(void 0);
|
|
4040
|
+
}, [file?.originFileObj, file?.thumbUrl]);
|
|
4041
|
+
return file?.thumbUrl || local || (file?.type?.startsWith("image/") || /\.(png|jpe?g|gif|webp|avif|svg)(\?|$)/i.test(file?.url ?? "") ? file?.url : void 0);
|
|
4042
|
+
}
|
|
4043
|
+
function UploadItem({ file, files, props, actions }) {
|
|
4044
|
+
const source = useThumbnail(file);
|
|
4045
|
+
const [failed, setFailed] = (0, import_react23.useState)(false);
|
|
4046
|
+
(0, import_react23.useEffect)(() => setFailed(false), [source]);
|
|
4047
|
+
const node = /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: `sia-upload__item sia-upload__item--${file.status ?? "ready"}`, children: [
|
|
4048
|
+
props.listType !== "text" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { variant: "text", className: "sia-upload__thumbnail", "aria-label": `\u9884\u89C8 ${file.name}`, onClick: actions.preview, disabled: !source && !props.onPreview, children: source && !failed ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("img", { src: source, alt: file.name, onError: () => setFailed(true) }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Icon, { name: file.type?.startsWith("image/") ? "image" : "file", size: 28 }) }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Icon, { name: file.status === "done" ? "circle-check" : "file", size: 16 }),
|
|
4049
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-upload__name", ...withTitleTooltip({ title: file.relativePath || file.name }), children: file.url ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { href: file.url, target: "_blank", rel: "noreferrer", children: file.name }) : file.name }),
|
|
4050
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { variant: "text", className: "sia-upload__remove", disabled: props.disabled, "aria-label": `\u79FB\u9664 ${file.name}`, onClick: () => void actions.remove(), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Icon, { name: "close", size: 14 }) }),
|
|
4051
|
+
file.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sia-upload__uploading", children: [
|
|
4052
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { children: [
|
|
4053
|
+
"\u4E0A\u4F20\u4E2D ",
|
|
4054
|
+
Math.round(file.percent ?? 0),
|
|
4055
|
+
"%"
|
|
4056
|
+
] }),
|
|
4057
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-upload__progress", role: "progressbar", "aria-label": `${file.name} \u4E0A\u4F20\u8FDB\u5EA6`, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": file.percent ?? 0, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { width: `${file.percent ?? 0}%` } }) })
|
|
4058
|
+
] }),
|
|
4059
|
+
file.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-upload__error", children: "\u4E0A\u4F20\u5931\u8D25" })
|
|
4060
|
+
] });
|
|
4061
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, { children: props.itemRender ? props.itemRender(node, file, files, actions) : node });
|
|
4062
|
+
}
|
|
4063
|
+
var UploadRoot = (0, import_react23.forwardRef)(function UploadRoot2({
|
|
3936
4064
|
accept,
|
|
3937
4065
|
multiple = false,
|
|
3938
4066
|
directory = false,
|
|
4067
|
+
recursive = true,
|
|
4068
|
+
pastable = false,
|
|
3939
4069
|
disabled = false,
|
|
4070
|
+
autoUpload = true,
|
|
3940
4071
|
maxCount: maxCount2,
|
|
3941
4072
|
fileList,
|
|
3942
4073
|
defaultFileList = [],
|
|
3943
4074
|
listType = "text",
|
|
3944
4075
|
showUploadList = true,
|
|
3945
4076
|
beforeUpload,
|
|
4077
|
+
request,
|
|
3946
4078
|
customRequest,
|
|
3947
4079
|
onChange,
|
|
3948
4080
|
onRemove,
|
|
4081
|
+
onReject,
|
|
4082
|
+
onReadError,
|
|
4083
|
+
onPreview,
|
|
4084
|
+
itemRender,
|
|
3949
4085
|
children,
|
|
3950
4086
|
className = "",
|
|
3951
4087
|
onDragOver,
|
|
4088
|
+
onDragLeave,
|
|
3952
4089
|
onDrop,
|
|
4090
|
+
onPaste,
|
|
4091
|
+
tabIndex,
|
|
3953
4092
|
...props
|
|
3954
|
-
}) {
|
|
4093
|
+
}, ref) {
|
|
3955
4094
|
const inputRef = (0, import_react23.useRef)(null);
|
|
3956
|
-
const
|
|
3957
|
-
const
|
|
3958
|
-
const
|
|
4095
|
+
const [internalFiles, setInternalFiles] = (0, import_react23.useState)(defaultFileList);
|
|
4096
|
+
const files = fileList ?? internalFiles;
|
|
4097
|
+
const filesRef = (0, import_react23.useRef)(files);
|
|
3959
4098
|
filesRef.current = files;
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
4099
|
+
const tasks = (0, import_react23.useRef)(/* @__PURE__ */ new Map());
|
|
4100
|
+
const mounted = (0, import_react23.useRef)(true);
|
|
4101
|
+
const [dragging, setDragging] = (0, import_react23.useState)(false);
|
|
4102
|
+
const [preview, setPreview] = (0, import_react23.useState)();
|
|
4103
|
+
const previewSource = useThumbnail(preview);
|
|
4104
|
+
const limit = maxCount2 === void 0 || !Number.isFinite(maxCount2) ? Infinity : Math.max(0, Math.floor(maxCount2));
|
|
4105
|
+
const full = files.length >= limit;
|
|
4106
|
+
const current = (0, import_react23.useRef)({ disabled, directory, recursive });
|
|
4107
|
+
current.current = { disabled, directory, recursive };
|
|
4108
|
+
function cancel(uid) {
|
|
4109
|
+
const task = tasks.current.get(uid);
|
|
4110
|
+
tasks.current.delete(uid);
|
|
4111
|
+
task?.controller.abort();
|
|
4112
|
+
try {
|
|
4113
|
+
task?.handle?.abort?.();
|
|
4114
|
+
} catch {
|
|
3972
4115
|
}
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
4116
|
+
task?.finish();
|
|
4117
|
+
}
|
|
4118
|
+
(0, import_react23.useEffect)(() => {
|
|
4119
|
+
mounted.current = true;
|
|
4120
|
+
return () => {
|
|
4121
|
+
mounted.current = false;
|
|
4122
|
+
[...tasks.current.keys()].forEach(cancel);
|
|
4123
|
+
};
|
|
4124
|
+
}, []);
|
|
4125
|
+
(0, import_react23.useEffect)(() => {
|
|
4126
|
+
for (const uid of tasks.current.keys()) if (!files.some((file) => file.uid === uid)) cancel(uid);
|
|
4127
|
+
if (preview && !files.some((file) => file.uid === preview.uid)) setPreview(void 0);
|
|
4128
|
+
}, [files, preview]);
|
|
4129
|
+
function emit(file, next, event) {
|
|
4130
|
+
if (!mounted.current) return;
|
|
4131
|
+
filesRef.current = next;
|
|
4132
|
+
if (fileList === void 0) setInternalFiles(next);
|
|
4133
|
+
onChange?.({ file, fileList: next, event });
|
|
4134
|
+
}
|
|
4135
|
+
function start(file) {
|
|
4136
|
+
if (current.current.disabled || !mounted.current || file.status === "done" || !file.originFileObj) return Promise.resolve();
|
|
4137
|
+
const existing = tasks.current.get(file.uid);
|
|
4138
|
+
if (existing) return existing.done;
|
|
4139
|
+
let finish = () => {
|
|
4140
|
+
};
|
|
4141
|
+
const done = new Promise((resolve) => {
|
|
4142
|
+
finish = resolve;
|
|
4143
|
+
});
|
|
4144
|
+
const task = { controller: new AbortController(), done, finish };
|
|
4145
|
+
tasks.current.set(file.uid, task);
|
|
4146
|
+
const active = () => mounted.current && tasks.current.get(file.uid) === task && !task.controller.signal.aborted && filesRef.current.some((entry) => entry.uid === file.uid);
|
|
4147
|
+
const update = (patch, event) => {
|
|
4148
|
+
if (!active()) return;
|
|
4149
|
+
const next = { ...filesRef.current.find((entry) => entry.uid === file.uid), ...patch };
|
|
4150
|
+
emit(next, filesRef.current.map((entry) => entry.uid === file.uid ? next : entry), event);
|
|
4151
|
+
};
|
|
4152
|
+
const settle = () => {
|
|
4153
|
+
if (tasks.current.get(file.uid) === task) tasks.current.delete(file.uid);
|
|
4154
|
+
finish();
|
|
4155
|
+
};
|
|
4156
|
+
const options = {
|
|
4157
|
+
file: file.originFileObj,
|
|
4158
|
+
filename: file.name,
|
|
4159
|
+
uploadFile: file,
|
|
4160
|
+
relativePath: file.relativePath || file.name,
|
|
4161
|
+
signal: task.controller.signal,
|
|
3980
4162
|
onProgress: (percent) => {
|
|
3981
|
-
|
|
3982
|
-
const progressList = filesRef.current.map((entry) => entry.uid === item.uid ? progressing : entry);
|
|
3983
|
-
emit(progressing, progressList);
|
|
4163
|
+
if (Number.isFinite(percent)) update({ percent: Math.max(0, Math.min(100, percent)) }, "progress");
|
|
3984
4164
|
},
|
|
3985
|
-
onSuccess: (response) => {
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
4165
|
+
onSuccess: (response, url) => {
|
|
4166
|
+
if (!active()) return;
|
|
4167
|
+
update({ status: "done", percent: 100, response, ...url ? { url } : {} }, "success");
|
|
4168
|
+
settle();
|
|
3989
4169
|
},
|
|
3990
4170
|
onError: (error) => {
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
4171
|
+
if (!active()) return;
|
|
4172
|
+
update({ status: "error", error }, "error");
|
|
4173
|
+
settle();
|
|
3994
4174
|
}
|
|
3995
4175
|
};
|
|
3996
|
-
|
|
3997
|
-
|
|
4176
|
+
update({ status: "uploading", percent: 0, error: void 0 }, "start");
|
|
4177
|
+
void (async () => {
|
|
4178
|
+
try {
|
|
4179
|
+
if (!active()) return;
|
|
4180
|
+
const result = await beforeUpload?.(options.file, filesRef.current.flatMap((entry) => entry.originFileObj ? [entry.originFileObj] : []));
|
|
4181
|
+
if (!active()) return;
|
|
4182
|
+
if (result === LIST_IGNORE) {
|
|
4183
|
+
settle();
|
|
4184
|
+
emit(file, filesRef.current.filter((entry) => entry.uid !== file.uid), "remove");
|
|
4185
|
+
return;
|
|
4186
|
+
}
|
|
4187
|
+
if (result === false || !customRequest && !request) {
|
|
4188
|
+
update({ status: "ready" }, "cancel");
|
|
4189
|
+
settle();
|
|
4190
|
+
return;
|
|
4191
|
+
}
|
|
4192
|
+
if (result instanceof File) {
|
|
4193
|
+
options.file = result;
|
|
4194
|
+
options.filename = result.name;
|
|
4195
|
+
}
|
|
4196
|
+
if (customRequest) task.handle = await customRequest(options) || void 0;
|
|
4197
|
+
else {
|
|
4198
|
+
const config = typeof request === "function" ? await request({ ...file, originFileObj: options.file, name: options.filename }, task.controller.signal) : request;
|
|
4199
|
+
if (active()) task.handle = sendUploadRequest(config, options);
|
|
4200
|
+
}
|
|
4201
|
+
if (task.controller.signal.aborted) task.handle?.abort?.();
|
|
4202
|
+
} catch (error) {
|
|
4203
|
+
options.onError(error);
|
|
4204
|
+
}
|
|
4205
|
+
})();
|
|
4206
|
+
return done;
|
|
3998
4207
|
}
|
|
3999
|
-
function
|
|
4000
|
-
const
|
|
4001
|
-
|
|
4002
|
-
|
|
4208
|
+
function abort(uid) {
|
|
4209
|
+
const ids = uid ? [uid] : [...tasks.current.keys()];
|
|
4210
|
+
for (const id of ids) {
|
|
4211
|
+
if (!tasks.current.has(id)) continue;
|
|
4212
|
+
cancel(id);
|
|
4213
|
+
const file = filesRef.current.find((entry) => entry.uid === id);
|
|
4214
|
+
if (file) {
|
|
4215
|
+
const next = { ...file, status: "ready", percent: 0 };
|
|
4216
|
+
emit(next, filesRef.current.map((entry) => entry.uid === id ? next : entry), "cancel");
|
|
4217
|
+
}
|
|
4218
|
+
}
|
|
4219
|
+
}
|
|
4220
|
+
async function remove(uid) {
|
|
4221
|
+
if (current.current.disabled) return;
|
|
4222
|
+
const file = filesRef.current.find((entry) => entry.uid === uid);
|
|
4223
|
+
if (!file) return;
|
|
4224
|
+
try {
|
|
4225
|
+
if (await onRemove?.(file) === false || !mounted.current || current.current.disabled) return;
|
|
4226
|
+
cancel(uid);
|
|
4227
|
+
emit(file, filesRef.current.filter((entry) => entry.uid !== uid), "remove");
|
|
4228
|
+
} catch {
|
|
4229
|
+
}
|
|
4003
4230
|
}
|
|
4004
|
-
|
|
4231
|
+
(0, import_react23.useImperativeHandle)(ref, () => ({
|
|
4232
|
+
upload: async (uid) => {
|
|
4233
|
+
await Promise.all(filesRef.current.filter((file) => (!uid || file.uid === uid) && file.status !== "done").map(start));
|
|
4234
|
+
},
|
|
4235
|
+
abort,
|
|
4236
|
+
remove
|
|
4237
|
+
}));
|
|
4238
|
+
function ingest(entries) {
|
|
4239
|
+
if (current.current.disabled || !mounted.current) return;
|
|
4240
|
+
const filtered = directory ? entries.filter((entry) => includeUploadPath(entry.path, recursive)) : entries;
|
|
4241
|
+
const selected = multiple || directory ? filtered : filtered.slice(0, 1);
|
|
4242
|
+
const added = [];
|
|
4243
|
+
for (const { file, path } of selected) {
|
|
4244
|
+
if (!acceptsUploadFile(file, accept)) {
|
|
4245
|
+
onReject?.({ file, reason: "accept" });
|
|
4246
|
+
continue;
|
|
4247
|
+
}
|
|
4248
|
+
if (filesRef.current.length >= limit) {
|
|
4249
|
+
onReject?.({ file, reason: "max-count" });
|
|
4250
|
+
continue;
|
|
4251
|
+
}
|
|
4252
|
+
const item = { uid: `upload-${Date.now()}-${Math.random().toString(36).slice(2)}`, name: file.name, size: file.size, type: file.type, relativePath: path, originFileObj: file, status: "ready", percent: 0 };
|
|
4253
|
+
emit(item, [...filesRef.current, item], "add");
|
|
4254
|
+
added.push(item);
|
|
4255
|
+
}
|
|
4256
|
+
if (autoUpload) added.forEach((file) => {
|
|
4257
|
+
void start(file);
|
|
4258
|
+
});
|
|
4259
|
+
}
|
|
4260
|
+
async function handleDrop(event) {
|
|
4005
4261
|
onDrop?.(event);
|
|
4006
|
-
|
|
4262
|
+
setDragging(false);
|
|
4263
|
+
if (event.defaultPrevented) return;
|
|
4007
4264
|
event.preventDefault();
|
|
4008
|
-
|
|
4009
|
-
|
|
4265
|
+
if (disabled) return;
|
|
4266
|
+
const fallback = [...event.dataTransfer.files].map((file) => ({ file, path: file.webkitRelativePath || file.name }));
|
|
4267
|
+
const entries = [...event.dataTransfer.items].map((item) => item.webkitGetAsEntry?.()).filter((entry) => !!entry);
|
|
4268
|
+
try {
|
|
4269
|
+
if (entries.length) ingest(await readUploadEntries(entries.filter((entry) => directory || !entry.isDirectory), recursive));
|
|
4270
|
+
else ingest(fallback);
|
|
4271
|
+
} catch (error) {
|
|
4272
|
+
if (mounted.current) onReadError?.(error);
|
|
4273
|
+
}
|
|
4010
4274
|
}
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4275
|
+
function handlePaste(event) {
|
|
4276
|
+
onPaste?.(event);
|
|
4277
|
+
if (event.defaultPrevented || disabled || !pastable) return;
|
|
4278
|
+
const selected = [...event.clipboardData.files];
|
|
4279
|
+
if (!selected.length) return;
|
|
4280
|
+
event.preventDefault();
|
|
4281
|
+
ingest(selected.map((file) => ({ file, path: file.name })));
|
|
4015
4282
|
}
|
|
4283
|
+
const trigger = !(listType === "picture-card" && full) && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sia-upload__trigger", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { className: "sia-upload__choose", disabled: disabled || full, onClick: () => inputRef.current?.click(), children: children ?? (listType === "picture-card" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
4284
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Icon, { name: "plus", size: 24 }),
|
|
4285
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: "\u4E0A\u4F20\u56FE\u7247" })
|
|
4286
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
4287
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Icon, { name: "upload", size: 16 }),
|
|
4288
|
+
directory ? "\u9009\u62E9\u6587\u4EF6\u5939" : "\u9009\u62E9\u6587\u4EF6"
|
|
4289
|
+
] })) }) });
|
|
4016
4290
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4017
4291
|
"div",
|
|
4018
4292
|
{
|
|
4019
|
-
|
|
4293
|
+
...withTitleTooltip(props),
|
|
4294
|
+
className: `sia-upload sia-upload--${listType}${dragging ? " is-dragging" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(),
|
|
4295
|
+
tabIndex: tabIndex ?? (pastable && !disabled ? 0 : void 0),
|
|
4296
|
+
onPaste: handlePaste,
|
|
4020
4297
|
onDragOver: (event) => {
|
|
4021
4298
|
onDragOver?.(event);
|
|
4022
|
-
if (!event.defaultPrevented
|
|
4299
|
+
if (!event.defaultPrevented) {
|
|
4300
|
+
event.preventDefault();
|
|
4301
|
+
if (!disabled) setDragging(true);
|
|
4302
|
+
}
|
|
4023
4303
|
},
|
|
4024
|
-
|
|
4025
|
-
|
|
4304
|
+
onDragLeave: (event) => {
|
|
4305
|
+
onDragLeave?.(event);
|
|
4306
|
+
if (!event.currentTarget.contains(event.relatedTarget)) setDragging(false);
|
|
4307
|
+
},
|
|
4308
|
+
onDrop: (event) => void handleDrop(event),
|
|
4026
4309
|
children: [
|
|
4027
4310
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4028
4311
|
"input",
|
|
4029
4312
|
{
|
|
4030
4313
|
ref: inputRef,
|
|
4031
|
-
id,
|
|
4032
4314
|
className: "sia-upload__input",
|
|
4033
4315
|
type: "file",
|
|
4034
4316
|
accept,
|
|
4035
|
-
multiple,
|
|
4036
|
-
disabled,
|
|
4037
|
-
...
|
|
4038
|
-
onChange:
|
|
4317
|
+
multiple: multiple || directory,
|
|
4318
|
+
disabled: disabled || full,
|
|
4319
|
+
...directory ? { webkitdirectory: "", directory: "" } : {},
|
|
4320
|
+
onChange: (event) => {
|
|
4321
|
+
ingest([...event.currentTarget.files ?? []].map((file) => ({ file, path: file.webkitRelativePath || file.name })));
|
|
4322
|
+
event.currentTarget.value = "";
|
|
4323
|
+
}
|
|
4039
4324
|
}
|
|
4040
4325
|
),
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4326
|
+
listType !== "picture-card" && trigger,
|
|
4327
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sia-upload__list", children: [
|
|
4328
|
+
showUploadList && files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(UploadItem, { file, files, props: { listType, disabled, itemRender, onPreview }, actions: {
|
|
4329
|
+
upload: () => start(file),
|
|
4330
|
+
abort: () => abort(file.uid),
|
|
4331
|
+
remove: () => remove(file.uid),
|
|
4332
|
+
preview: () => {
|
|
4333
|
+
if (onPreview) onPreview(file);
|
|
4334
|
+
else setPreview(file);
|
|
4335
|
+
}
|
|
4336
|
+
} }, file.uid)),
|
|
4337
|
+
listType === "picture-card" && trigger
|
|
4338
|
+
] }),
|
|
4339
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ImagePreview, { open: !!preview && !!(preview.url || previewSource), src: preview?.url || previewSource, alt: preview?.name, onOpenChange: (open) => {
|
|
4340
|
+
if (!open) setPreview(void 0);
|
|
4341
|
+
} })
|
|
4048
4342
|
]
|
|
4049
4343
|
}
|
|
4050
4344
|
);
|
|
4051
|
-
}
|
|
4052
|
-
|
|
4053
|
-
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(UploadRoot, { ...props, className: `sia-upload-dragger ${className}`.trim(), children: children ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("
|
|
4054
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Icon, { name: "upload", size:
|
|
4055
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.
|
|
4056
|
-
|
|
4345
|
+
});
|
|
4346
|
+
var UploadDragger = (0, import_react23.forwardRef)(function UploadDragger2({ hint = "\u652F\u6301\u5355\u4E2A\u6216\u6279\u91CF\u4E0A\u4F20", children, className = "", ...props }, ref) {
|
|
4347
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(UploadRoot, { ...props, ref, className: `sia-upload-dragger ${className}`.trim(), children: children ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "sia-upload-dragger__content", children: [
|
|
4348
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Icon, { name: "upload", size: 32 }),
|
|
4349
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("strong", { children: [
|
|
4350
|
+
"\u70B9\u51FB\u6216\u62D6\u62FD",
|
|
4351
|
+
props.directory ? "\u6587\u4EF6\u5939" : "\u6587\u4EF6",
|
|
4352
|
+
"\u5230\u6B64\u533A\u57DF\u4E0A\u4F20"
|
|
4353
|
+
] }),
|
|
4354
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: hint }),
|
|
4355
|
+
props.pastable && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: "\u805A\u7126\u6B64\u533A\u57DF\u540E\u6309 Ctrl / \u2318 + V \u7C98\u8D34\u6587\u4EF6\u6216\u622A\u56FE" })
|
|
4057
4356
|
] }) });
|
|
4058
|
-
}
|
|
4357
|
+
});
|
|
4059
4358
|
var Upload = Object.assign(UploadRoot, {
|
|
4060
|
-
/**
|
|
4359
|
+
/** 可点击、键盘操作和拖拽的上传区域,ref 支持手动上传、取消及移除。 */
|
|
4061
4360
|
Dragger: UploadDragger,
|
|
4062
|
-
/** beforeUpload
|
|
4361
|
+
/** beforeUpload 返回时移除该文件,不进行上传。 */
|
|
4063
4362
|
LIST_IGNORE
|
|
4064
4363
|
});
|
|
4065
4364
|
|