@sia.soul/sia-react-ui 0.1.34 → 0.1.36
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-BR2SD6RD.js → chunk-6TLANQVX.js} +2 -2
- package/dist/{chunk-Z63VYNCR.js → chunk-7CPIEYS2.js} +284 -137
- package/dist/{chunk-HOU5JLNJ.js → chunk-XCVAVCIO.js} +11 -0
- package/dist/{chunk-MHUYOGCG.js → chunk-ZDC7PMZN.js} +1 -1
- package/dist/{chunk-QAVQEBIS.js → chunk-ZTJUFVJO.js} +1 -1
- package/dist/{core-CIj-Xevv.d.cts → core-CLt6U7oH.d.cts} +23 -8
- package/dist/{core-Cj9bxBwT.d.ts → core-vIHbXa6s.d.ts} +23 -8
- package/dist/core.cjs +292 -134
- package/dist/core.css +126 -30
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +3 -3
- package/dist/index.cjs +378 -220
- package/dist/index.css +126 -30
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +7 -7
- package/dist/rich-text-editor.cjs +11 -0
- package/dist/rich-text-editor.js +2 -2
- package/dist/select-date-range.cjs +11 -0
- package/dist/select-date-range.js +3 -3
- package/package.json +1 -1
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
Popover,
|
|
6
6
|
Tooltip,
|
|
7
7
|
useOverlayLifecycle
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ZTJUFVJO.js";
|
|
9
9
|
import {
|
|
10
10
|
Dropdown,
|
|
11
11
|
Icon
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-XCVAVCIO.js";
|
|
13
13
|
import {
|
|
14
14
|
Button
|
|
15
15
|
} from "./chunk-IKAMZNCK.js";
|
|
@@ -884,11 +884,98 @@ function Collapse({ items, activeKey, defaultActiveKey = [], accordion = false,
|
|
|
884
884
|
}
|
|
885
885
|
function ImagePreview({ open, src, alt = "", onOpenChange }) {
|
|
886
886
|
const previewRef = useRef4(null);
|
|
887
|
+
const stageRef = useRef4(null);
|
|
888
|
+
const [natural, setNatural] = useState5({ src: "", width: 0, height: 0 });
|
|
889
|
+
const [area, setArea] = useState5({ width: 0, height: 0 });
|
|
890
|
+
const [zoom, setZoom] = useState5(1);
|
|
891
|
+
const [rotation, setRotation] = useState5(0);
|
|
892
|
+
const [flip, setFlip] = useState5({ x: 1, y: 1 });
|
|
893
|
+
const [pan, setPan] = useState5({ x: 0, y: 0 });
|
|
894
|
+
const [failed, setFailed] = useState5(false);
|
|
895
|
+
const drag = useRef4();
|
|
887
896
|
useOverlayLifecycle(open, previewRef, () => onOpenChange(false));
|
|
897
|
+
const reset = () => {
|
|
898
|
+
setZoom(1);
|
|
899
|
+
setRotation(0);
|
|
900
|
+
setFlip({ x: 1, y: 1 });
|
|
901
|
+
setPan({ x: 0, y: 0 });
|
|
902
|
+
drag.current = void 0;
|
|
903
|
+
};
|
|
904
|
+
useEffect3(() => {
|
|
905
|
+
reset();
|
|
906
|
+
setFailed(false);
|
|
907
|
+
}, [open, src]);
|
|
908
|
+
useEffect3(() => {
|
|
909
|
+
const stage = stageRef.current;
|
|
910
|
+
if (!open || !stage) return;
|
|
911
|
+
const measure = () => {
|
|
912
|
+
setArea({ width: stage.clientWidth, height: stage.clientHeight });
|
|
913
|
+
setPan({ x: 0, y: 0 });
|
|
914
|
+
};
|
|
915
|
+
measure();
|
|
916
|
+
const observer = new ResizeObserver(measure);
|
|
917
|
+
observer.observe(stage);
|
|
918
|
+
return () => observer.disconnect();
|
|
919
|
+
}, [open, src]);
|
|
920
|
+
const ready = natural.src === src && natural.width > 0 && area.width > 0 && area.height > 0 && !failed;
|
|
921
|
+
const sideways = Math.abs(rotation % 180) === 90;
|
|
922
|
+
const fit = ready ? Math.min(1, area.width / (sideways ? natural.height : natural.width), area.height / (sideways ? natural.width : natural.height)) : 0;
|
|
923
|
+
const changeZoom = (factor) => setZoom((value) => Math.max(0.25, Math.min(8, value * factor)));
|
|
888
924
|
if (!open || !src || typeof document === "undefined") return null;
|
|
889
925
|
return createPortal2(/* @__PURE__ */ jsxs6("div", { ref: previewRef, className: "sia-image-preview", role: "dialog", "aria-modal": "true", "aria-label": "\u56FE\u7247\u9884\u89C8", tabIndex: -1, onClick: () => onOpenChange(false), children: [
|
|
890
|
-
/* @__PURE__ */ jsx6(
|
|
891
|
-
|
|
926
|
+
/* @__PURE__ */ jsx6(Button, { variant: "text", className: "sia-image-preview__close", "aria-label": "\u5173\u95ED\u9884\u89C8", onClick: (event) => {
|
|
927
|
+
event.stopPropagation();
|
|
928
|
+
onOpenChange(false);
|
|
929
|
+
}, children: /* @__PURE__ */ jsx6(Icon, { name: "close" }) }),
|
|
930
|
+
/* @__PURE__ */ jsx6("div", { ref: stageRef, className: "sia-image-preview__stage", children: failed ? /* @__PURE__ */ jsx6("span", { className: "sia-image-preview__error", children: "\u56FE\u7247\u52A0\u8F7D\u5931\u8D25" }) : /* @__PURE__ */ jsx6(
|
|
931
|
+
"img",
|
|
932
|
+
{
|
|
933
|
+
src,
|
|
934
|
+
alt,
|
|
935
|
+
draggable: false,
|
|
936
|
+
style: { width: natural.width * fit, height: natural.height * fit, visibility: ready ? "visible" : "hidden", transform: `translate(${pan.x}px, ${pan.y}px) rotate(${rotation}deg) scale(${zoom * flip.x}, ${zoom * flip.y})` },
|
|
937
|
+
onLoad: (event) => setNatural({ src, width: event.currentTarget.naturalWidth, height: event.currentTarget.naturalHeight }),
|
|
938
|
+
onError: () => setFailed(true),
|
|
939
|
+
onClick: (event) => event.stopPropagation(),
|
|
940
|
+
onPointerDown: (event) => {
|
|
941
|
+
if (event.button !== 0) return;
|
|
942
|
+
event.preventDefault();
|
|
943
|
+
event.stopPropagation();
|
|
944
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
945
|
+
drag.current = { id: event.pointerId, x: event.clientX, y: event.clientY, left: pan.x, top: pan.y };
|
|
946
|
+
},
|
|
947
|
+
onPointerMove: (event) => {
|
|
948
|
+
const start = drag.current;
|
|
949
|
+
if (start?.id === event.pointerId) setPan({ x: start.left + event.clientX - start.x, y: start.top + event.clientY - start.y });
|
|
950
|
+
},
|
|
951
|
+
onPointerUp: () => {
|
|
952
|
+
drag.current = void 0;
|
|
953
|
+
},
|
|
954
|
+
onPointerCancel: () => {
|
|
955
|
+
drag.current = void 0;
|
|
956
|
+
},
|
|
957
|
+
onLostPointerCapture: () => {
|
|
958
|
+
drag.current = void 0;
|
|
959
|
+
}
|
|
960
|
+
},
|
|
961
|
+
src
|
|
962
|
+
) }),
|
|
963
|
+
/* @__PURE__ */ jsxs6("div", { className: "sia-image-preview__toolbar", role: "toolbar", "aria-label": "\u56FE\u7247\u64CD\u4F5C", onClick: (event) => event.stopPropagation(), children: [
|
|
964
|
+
/* @__PURE__ */ jsx6(Button, { variant: "text", title: "\u6C34\u5E73\u7FFB\u8F6C", "aria-label": "\u6C34\u5E73\u7FFB\u8F6C", disabled: !ready, onClick: () => setFlip((value) => ({ ...value, x: -value.x })), children: /* @__PURE__ */ jsx6(Icon, { name: "flip-horizontal", size: 20 }) }),
|
|
965
|
+
/* @__PURE__ */ jsx6(Button, { variant: "text", title: "\u5782\u76F4\u7FFB\u8F6C", "aria-label": "\u5782\u76F4\u7FFB\u8F6C", disabled: !ready, onClick: () => setFlip((value) => ({ ...value, y: -value.y })), children: /* @__PURE__ */ jsx6(Icon, { name: "flip-vertical", size: 20 }) }),
|
|
966
|
+
/* @__PURE__ */ jsx6(Button, { variant: "text", title: "\u5411\u5DE6\u65CB\u8F6C", "aria-label": "\u5411\u5DE6\u65CB\u8F6C", disabled: !ready, onClick: () => {
|
|
967
|
+
setRotation((value) => value - 90);
|
|
968
|
+
setPan({ x: 0, y: 0 });
|
|
969
|
+
}, children: /* @__PURE__ */ jsx6(Icon, { name: "rotate-left", size: 20 }) }),
|
|
970
|
+
/* @__PURE__ */ jsx6(Button, { variant: "text", title: "\u5411\u53F3\u65CB\u8F6C", "aria-label": "\u5411\u53F3\u65CB\u8F6C", disabled: !ready, onClick: () => {
|
|
971
|
+
setRotation((value) => value + 90);
|
|
972
|
+
setPan({ x: 0, y: 0 });
|
|
973
|
+
}, children: /* @__PURE__ */ jsx6(Icon, { name: "rotate-right", size: 20 }) }),
|
|
974
|
+
/* @__PURE__ */ jsx6(Button, { variant: "text", title: "\u7F29\u5C0F", "aria-label": "\u7F29\u5C0F", disabled: !ready || zoom <= 0.25, onClick: () => changeZoom(1 / 1.25), children: /* @__PURE__ */ jsx6(Icon, { name: "zoom-out", size: 20 }) }),
|
|
975
|
+
/* @__PURE__ */ jsx6("output", { className: "sia-image-preview__scale", "aria-label": "\u5F53\u524D\u7F29\u653E\u6BD4\u4F8B", "aria-live": "polite", children: ready ? `${Math.round(fit * zoom * 100)}%` : "\u2014" }),
|
|
976
|
+
/* @__PURE__ */ jsx6(Button, { variant: "text", title: "\u653E\u5927", "aria-label": "\u653E\u5927", disabled: !ready || zoom >= 8, onClick: () => changeZoom(1.25), children: /* @__PURE__ */ jsx6(Icon, { name: "zoom-in", size: 20 }) }),
|
|
977
|
+
/* @__PURE__ */ jsx6(Button, { variant: "text", title: "\u9002\u5E94\u7A97\u53E3", "aria-label": "\u9002\u5E94\u7A97\u53E3", disabled: !ready, onClick: reset, children: /* @__PURE__ */ jsx6(Icon, { name: "refresh", size: 20 }) })
|
|
978
|
+
] })
|
|
892
979
|
] }), document.body);
|
|
893
980
|
}
|
|
894
981
|
function Image({ fallback, placeholder, preview = true, rootClassName = "", className = "", src, alt = "", onError, style, ...props }) {
|
|
@@ -922,6 +1009,111 @@ function Image({ fallback, placeholder, preview = true, rootClassName = "", clas
|
|
|
922
1009
|
] });
|
|
923
1010
|
}
|
|
924
1011
|
|
|
1012
|
+
// src/components/Message.tsx
|
|
1013
|
+
import { createRoot as createRoot2 } from "react-dom/client";
|
|
1014
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1015
|
+
var messageSeed = 0;
|
|
1016
|
+
var messageRoot = null;
|
|
1017
|
+
var messageContainer = null;
|
|
1018
|
+
var messageItems = [];
|
|
1019
|
+
var defaultDuration = 3;
|
|
1020
|
+
var maxCount = 5;
|
|
1021
|
+
var messageTimers = /* @__PURE__ */ new Map();
|
|
1022
|
+
var messageIcons = {
|
|
1023
|
+
info: /* @__PURE__ */ jsx7(Icon, { name: "info", size: 18 }),
|
|
1024
|
+
success: /* @__PURE__ */ jsx7(Icon, { name: "circle-check", size: 18 }),
|
|
1025
|
+
warning: /* @__PURE__ */ jsx7(Icon, { name: "warning", size: 18 }),
|
|
1026
|
+
error: /* @__PURE__ */ jsx7(Icon, { name: "circle-close", size: 18 }),
|
|
1027
|
+
loading: /* @__PURE__ */ jsx7(Icon, { name: "loader", size: 18, spin: true })
|
|
1028
|
+
};
|
|
1029
|
+
function ensureMessageRoot() {
|
|
1030
|
+
if (typeof document === "undefined") return false;
|
|
1031
|
+
if (!messageContainer) {
|
|
1032
|
+
messageContainer = document.createElement("div");
|
|
1033
|
+
messageContainer.className = "sia-message-root";
|
|
1034
|
+
document.body.appendChild(messageContainer);
|
|
1035
|
+
messageRoot = createRoot2(messageContainer);
|
|
1036
|
+
}
|
|
1037
|
+
return true;
|
|
1038
|
+
}
|
|
1039
|
+
function renderMessages() {
|
|
1040
|
+
if (!ensureMessageRoot()) return;
|
|
1041
|
+
messageRoot.render(/* @__PURE__ */ jsx7("div", { className: "sia-message-list", "aria-live": "polite", children: messageItems.map((item) => /* @__PURE__ */ jsxs7("div", { className: `sia-message sia-message--${item.type}`, role: item.type === "loading" ? "status" : "alert", children: [
|
|
1042
|
+
/* @__PURE__ */ jsx7("span", { className: "sia-message__icon", "aria-hidden": "true", children: messageIcons[item.type] }),
|
|
1043
|
+
/* @__PURE__ */ jsx7("span", { className: "sia-message__content", children: item.content }),
|
|
1044
|
+
item.closable ? /* @__PURE__ */ jsx7("button", { type: "button", className: "sia-message__close", "aria-label": "\u5173\u95ED\u63D0\u793A", onClick: () => closeMessage(item.key), children: /* @__PURE__ */ jsx7(Icon, { name: "close", size: 14 }) }) : null
|
|
1045
|
+
] }, item.key)) }));
|
|
1046
|
+
}
|
|
1047
|
+
function closeMessage(key) {
|
|
1048
|
+
const item = messageItems.find((candidate) => candidate.key === key);
|
|
1049
|
+
const timer = messageTimers.get(key);
|
|
1050
|
+
if (timer !== void 0) window.clearTimeout(timer);
|
|
1051
|
+
messageTimers.delete(key);
|
|
1052
|
+
messageItems = messageItems.filter((candidate) => candidate.key !== key);
|
|
1053
|
+
item?.onClose?.();
|
|
1054
|
+
renderMessages();
|
|
1055
|
+
}
|
|
1056
|
+
function scheduleMessage(item) {
|
|
1057
|
+
const existingTimer = messageTimers.get(item.key);
|
|
1058
|
+
if (existingTimer !== void 0) window.clearTimeout(existingTimer);
|
|
1059
|
+
const duration = item.duration ?? (item.type === "loading" ? 0 : defaultDuration);
|
|
1060
|
+
if (duration > 0) {
|
|
1061
|
+
messageTimers.set(item.key, window.setTimeout(() => closeMessage(item.key), duration * 1e3));
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
function openMessage(input) {
|
|
1065
|
+
const config = typeof input === "object" && input !== null && "content" in input ? input : { content: input };
|
|
1066
|
+
const key = config.key ?? `sia-message-${++messageSeed}`;
|
|
1067
|
+
const item = { ...config, key, type: config.type ?? "info" };
|
|
1068
|
+
const existingIndex = messageItems.findIndex((candidate) => candidate.key === key);
|
|
1069
|
+
if (existingIndex >= 0) messageItems = messageItems.map((candidate, index) => index === existingIndex ? item : candidate);
|
|
1070
|
+
else messageItems = [...messageItems, item];
|
|
1071
|
+
while (messageItems.length > maxCount) closeMessage(messageItems[0].key);
|
|
1072
|
+
renderMessages();
|
|
1073
|
+
scheduleMessage(item);
|
|
1074
|
+
return {
|
|
1075
|
+
close: () => closeMessage(key),
|
|
1076
|
+
update(next) {
|
|
1077
|
+
const current = messageItems.find((candidate) => candidate.key === key);
|
|
1078
|
+
if (!current) return;
|
|
1079
|
+
const updated = { ...current, ...next, key, type: next.type ?? current.type };
|
|
1080
|
+
messageItems = messageItems.map((candidate) => candidate.key === key ? updated : candidate);
|
|
1081
|
+
renderMessages();
|
|
1082
|
+
scheduleMessage(updated);
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
function shortcut(type) {
|
|
1087
|
+
return (content, duration) => openMessage({ content, duration, type });
|
|
1088
|
+
}
|
|
1089
|
+
var message = {
|
|
1090
|
+
/** 直接打开实例,返回可用于更新或关闭的操作句柄。 */
|
|
1091
|
+
open: openMessage,
|
|
1092
|
+
/** 显示普通信息提示。 */
|
|
1093
|
+
info: shortcut("info"),
|
|
1094
|
+
/** 显示成功提示。 */
|
|
1095
|
+
success: shortcut("success"),
|
|
1096
|
+
/** 显示警告提示。 */
|
|
1097
|
+
warning: shortcut("warning"),
|
|
1098
|
+
/** 显示错误提示。 */
|
|
1099
|
+
error: shortcut("error"),
|
|
1100
|
+
/** 显示持续加载提示。 */
|
|
1101
|
+
loading: shortcut("loading"),
|
|
1102
|
+
/** 关闭指定实例;未指定标识时关闭所有实例。 */
|
|
1103
|
+
destroy(key) {
|
|
1104
|
+
if (key !== void 0) {
|
|
1105
|
+
closeMessage(key);
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
[...messageItems].forEach((item) => closeMessage(item.key));
|
|
1109
|
+
},
|
|
1110
|
+
/** 配置消息默认持续时间和最大同时显示数量。 */
|
|
1111
|
+
config(config) {
|
|
1112
|
+
if (config.duration !== void 0) defaultDuration = config.duration;
|
|
1113
|
+
if (config.maxCount !== void 0) maxCount = Math.max(1, config.maxCount);
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
|
|
925
1117
|
// src/components/Upload.tsx
|
|
926
1118
|
import { forwardRef, useEffect as useEffect4, useImperativeHandle, useRef as useRef5, useState as useState6 } from "react";
|
|
927
1119
|
|
|
@@ -1010,8 +1202,33 @@ function sendUploadRequest(config, options) {
|
|
|
1010
1202
|
return { abort };
|
|
1011
1203
|
}
|
|
1012
1204
|
|
|
1205
|
+
// src/components/uploadDownload.ts
|
|
1206
|
+
async function downloadUploadFile(file, request) {
|
|
1207
|
+
let blob;
|
|
1208
|
+
if (request) blob = await request(file);
|
|
1209
|
+
else if (file.url) {
|
|
1210
|
+
const response = await fetch(file.url);
|
|
1211
|
+
if (!response.ok) throw new Error(`\u4E0B\u8F7D\u5931\u8D25\uFF08HTTP ${response.status}\uFF09`);
|
|
1212
|
+
blob = await response.blob();
|
|
1213
|
+
} else if (file.originFileObj) blob = file.originFileObj;
|
|
1214
|
+
else throw new Error("\u6587\u4EF6\u7F3A\u5C11\u4E0B\u8F7D\u5730\u5740\u6216\u539F\u59CB\u5185\u5BB9");
|
|
1215
|
+
if (!(blob instanceof Blob)) throw new Error("\u4E0B\u8F7D\u8BF7\u6C42\u5FC5\u987B\u8FD4\u56DE Blob \u6587\u4EF6\u5185\u5BB9");
|
|
1216
|
+
const url = URL.createObjectURL(blob);
|
|
1217
|
+
const anchor = document.createElement("a");
|
|
1218
|
+
anchor.href = url;
|
|
1219
|
+
anchor.download = file.name;
|
|
1220
|
+
anchor.hidden = true;
|
|
1221
|
+
document.body.append(anchor);
|
|
1222
|
+
try {
|
|
1223
|
+
anchor.click();
|
|
1224
|
+
} finally {
|
|
1225
|
+
anchor.remove();
|
|
1226
|
+
window.setTimeout(() => URL.revokeObjectURL(url), 6e4);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1013
1230
|
// src/components/Upload.tsx
|
|
1014
|
-
import { Fragment as Fragment4, jsx as
|
|
1231
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1015
1232
|
var LIST_IGNORE = /* @__PURE__ */ Symbol("SIA_UPLOAD_LIST_IGNORE");
|
|
1016
1233
|
function useThumbnail(file) {
|
|
1017
1234
|
const [local, setLocal] = useState6();
|
|
@@ -1028,22 +1245,43 @@ function useThumbnail(file) {
|
|
|
1028
1245
|
function UploadItem({ file, files, props, actions }) {
|
|
1029
1246
|
const source = useThumbnail(file);
|
|
1030
1247
|
const [failed, setFailed] = useState6(false);
|
|
1248
|
+
const [downloading, setDownloading] = useState6(false);
|
|
1249
|
+
const downloadingRef = useRef5(false);
|
|
1250
|
+
const canPreview = !!(source || file.url || file.originFileObj || props.onPreview);
|
|
1251
|
+
const canDownload = !!(file.url || file.originFileObj || props.downloadRequest);
|
|
1252
|
+
async function download() {
|
|
1253
|
+
if (downloadingRef.current) return;
|
|
1254
|
+
downloadingRef.current = true;
|
|
1255
|
+
setDownloading(true);
|
|
1256
|
+
try {
|
|
1257
|
+
await actions.download();
|
|
1258
|
+
} catch {
|
|
1259
|
+
message.error("\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u6587\u4EF6\u5730\u5740\u3001\u8BBF\u95EE\u6743\u9650\u6216\u8DE8\u57DF\u914D\u7F6E");
|
|
1260
|
+
} finally {
|
|
1261
|
+
downloadingRef.current = false;
|
|
1262
|
+
setDownloading(false);
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1031
1265
|
useEffect4(() => setFailed(false), [source]);
|
|
1032
|
-
const node = /* @__PURE__ */
|
|
1033
|
-
props.listType !== "text" ? /* @__PURE__ */
|
|
1034
|
-
/* @__PURE__ */
|
|
1035
|
-
/* @__PURE__ */
|
|
1036
|
-
|
|
1037
|
-
/* @__PURE__ */
|
|
1266
|
+
const node = /* @__PURE__ */ jsxs8("div", { className: `sia-upload__item sia-upload__item--${file.status ?? "ready"}`, children: [
|
|
1267
|
+
props.listType !== "text" ? /* @__PURE__ */ jsx8(Button, { variant: "text", className: "sia-upload__thumbnail", "aria-label": `\u9884\u89C8\u7F29\u7565\u56FE ${file.name}`, onClick: actions.preview, disabled: !canPreview, children: source && !failed ? /* @__PURE__ */ jsx8("img", { src: source, alt: file.name, onError: () => setFailed(true) }) : /* @__PURE__ */ jsx8(Icon, { name: file.type?.startsWith("image/") ? "image" : "file", size: 28 }) }) : /* @__PURE__ */ jsx8(Icon, { name: file.status === "done" ? "circle-check" : "file", size: 16 }),
|
|
1268
|
+
/* @__PURE__ */ jsx8("span", { className: "sia-upload__name", ...withTitleTooltip({ title: file.relativePath || file.name }), children: file.url ? /* @__PURE__ */ jsx8("a", { href: file.url, target: "_blank", rel: "noreferrer", children: file.name }) : file.name }),
|
|
1269
|
+
/* @__PURE__ */ jsxs8("span", { className: "sia-upload__actions", children: [
|
|
1270
|
+
/* @__PURE__ */ jsx8(Button, { variant: "text", title: "\u9884\u89C8", "aria-label": `\u9884\u89C8 ${file.name}`, disabled: !canPreview, onClick: actions.preview, children: /* @__PURE__ */ jsx8(Icon, { name: "eye", size: 14 }) }),
|
|
1271
|
+
/* @__PURE__ */ jsx8(Button, { variant: "text", title: "\u4E0B\u8F7D", "aria-label": `\u4E0B\u8F7D ${file.name}`, disabled: !canDownload, loading: downloading, onClick: () => void download(), children: /* @__PURE__ */ jsx8(Icon, { name: "download", size: 14 }) }),
|
|
1272
|
+
/* @__PURE__ */ jsx8(Button, { variant: "text", title: "\u79FB\u9664", className: "sia-upload__remove", disabled: props.disabled, "aria-label": `\u79FB\u9664 ${file.name}`, onClick: () => void actions.remove(), children: /* @__PURE__ */ jsx8(Icon, { name: "close", size: 14 }) })
|
|
1273
|
+
] }),
|
|
1274
|
+
file.status === "uploading" && /* @__PURE__ */ jsxs8("div", { className: "sia-upload__uploading", children: [
|
|
1275
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
1038
1276
|
"\u4E0A\u4F20\u4E2D ",
|
|
1039
1277
|
Math.round(file.percent ?? 0),
|
|
1040
1278
|
"%"
|
|
1041
1279
|
] }),
|
|
1042
|
-
/* @__PURE__ */
|
|
1280
|
+
/* @__PURE__ */ jsx8("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__ */ jsx8("span", { style: { width: `${file.percent ?? 0}%` } }) })
|
|
1043
1281
|
] }),
|
|
1044
|
-
file.status === "error" && /* @__PURE__ */
|
|
1282
|
+
file.status === "error" && /* @__PURE__ */ jsx8("span", { className: "sia-upload__error", children: "\u4E0A\u4F20\u5931\u8D25" })
|
|
1045
1283
|
] });
|
|
1046
|
-
return /* @__PURE__ */
|
|
1284
|
+
return /* @__PURE__ */ jsx8(Fragment4, { children: props.itemRender ? props.itemRender(node, file, files, actions) : node });
|
|
1047
1285
|
}
|
|
1048
1286
|
var UploadRoot = forwardRef(function UploadRoot2({
|
|
1049
1287
|
accept,
|
|
@@ -1057,6 +1295,7 @@ var UploadRoot = forwardRef(function UploadRoot2({
|
|
|
1057
1295
|
fileList,
|
|
1058
1296
|
defaultFileList = [],
|
|
1059
1297
|
listType = "text",
|
|
1298
|
+
cardSize,
|
|
1060
1299
|
showUploadList = true,
|
|
1061
1300
|
beforeUpload,
|
|
1062
1301
|
request,
|
|
@@ -1066,9 +1305,11 @@ var UploadRoot = forwardRef(function UploadRoot2({
|
|
|
1066
1305
|
onReject,
|
|
1067
1306
|
onReadError,
|
|
1068
1307
|
onPreview,
|
|
1308
|
+
downloadRequest,
|
|
1069
1309
|
itemRender,
|
|
1070
1310
|
children,
|
|
1071
1311
|
className = "",
|
|
1312
|
+
style,
|
|
1072
1313
|
onDragOver,
|
|
1073
1314
|
onDragLeave,
|
|
1074
1315
|
onDrop,
|
|
@@ -1076,6 +1317,10 @@ var UploadRoot = forwardRef(function UploadRoot2({
|
|
|
1076
1317
|
tabIndex,
|
|
1077
1318
|
...props
|
|
1078
1319
|
}, ref) {
|
|
1320
|
+
const cardDimension = (value) => value !== void 0 && Number.isFinite(value) ? Math.max(48, value) : 112;
|
|
1321
|
+
const cardWidth = cardDimension(typeof cardSize === "number" ? cardSize : cardSize?.width);
|
|
1322
|
+
const cardHeight = cardDimension(typeof cardSize === "number" ? cardSize : cardSize?.height);
|
|
1323
|
+
const compactCard = listType === "picture-card" && (cardWidth < 88 || cardHeight < 88);
|
|
1079
1324
|
const inputRef = useRef5(null);
|
|
1080
1325
|
const [internalFiles, setInternalFiles] = useState6(defaultFileList);
|
|
1081
1326
|
const files = fileList ?? internalFiles;
|
|
@@ -1265,18 +1510,19 @@ var UploadRoot = forwardRef(function UploadRoot2({
|
|
|
1265
1510
|
event.preventDefault();
|
|
1266
1511
|
ingest(selected.map((file) => ({ file, path: file.name })));
|
|
1267
1512
|
}
|
|
1268
|
-
const trigger = !(listType === "picture-card" && full) && /* @__PURE__ */
|
|
1269
|
-
/* @__PURE__ */
|
|
1270
|
-
/* @__PURE__ */
|
|
1271
|
-
] }) : /* @__PURE__ */
|
|
1272
|
-
/* @__PURE__ */
|
|
1513
|
+
const trigger = !(listType === "picture-card" && full) && /* @__PURE__ */ jsx8("div", { className: "sia-upload__trigger", children: /* @__PURE__ */ jsx8(Button, { className: "sia-upload__choose", "aria-label": compactCard ? directory ? "\u9009\u62E9\u6587\u4EF6\u5939" : "\u9009\u62E9\u6587\u4EF6" : void 0, disabled: disabled || full, onClick: () => inputRef.current?.click(), children: children ?? (listType === "picture-card" ? /* @__PURE__ */ jsxs8(Fragment4, { children: [
|
|
1514
|
+
/* @__PURE__ */ jsx8(Icon, { name: "plus", size: 24 }),
|
|
1515
|
+
/* @__PURE__ */ jsx8("span", { children: "\u4E0A\u4F20\u56FE\u7247" })
|
|
1516
|
+
] }) : /* @__PURE__ */ jsxs8(Fragment4, { children: [
|
|
1517
|
+
/* @__PURE__ */ jsx8(Icon, { name: "upload", size: 16 }),
|
|
1273
1518
|
directory ? "\u9009\u62E9\u6587\u4EF6\u5939" : "\u9009\u62E9\u6587\u4EF6"
|
|
1274
1519
|
] })) }) });
|
|
1275
|
-
return /* @__PURE__ */
|
|
1520
|
+
return /* @__PURE__ */ jsxs8(
|
|
1276
1521
|
"div",
|
|
1277
1522
|
{
|
|
1278
1523
|
...withTitleTooltip(props),
|
|
1279
|
-
className: `sia-upload sia-upload--${listType}${dragging ? " is-dragging" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(),
|
|
1524
|
+
className: `sia-upload sia-upload--${listType}${compactCard ? " sia-upload--compact-card" : ""}${dragging ? " is-dragging" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(),
|
|
1525
|
+
style: listType === "picture-card" ? { "--sia-upload-card-width": `${cardWidth}px`, "--sia-upload-card-height": `${cardHeight}px`, ...style } : style,
|
|
1280
1526
|
tabIndex: tabIndex ?? (pastable && !disabled ? 0 : void 0),
|
|
1281
1527
|
onPaste: handlePaste,
|
|
1282
1528
|
onDragOver: (event) => {
|
|
@@ -1292,7 +1538,7 @@ var UploadRoot = forwardRef(function UploadRoot2({
|
|
|
1292
1538
|
},
|
|
1293
1539
|
onDrop: (event) => void handleDrop(event),
|
|
1294
1540
|
children: [
|
|
1295
|
-
/* @__PURE__ */
|
|
1541
|
+
/* @__PURE__ */ jsx8(
|
|
1296
1542
|
"input",
|
|
1297
1543
|
{
|
|
1298
1544
|
ref: inputRef,
|
|
@@ -1309,19 +1555,25 @@ var UploadRoot = forwardRef(function UploadRoot2({
|
|
|
1309
1555
|
}
|
|
1310
1556
|
),
|
|
1311
1557
|
listType !== "picture-card" && trigger,
|
|
1312
|
-
/* @__PURE__ */
|
|
1313
|
-
showUploadList && files.map((file) => /* @__PURE__ */
|
|
1558
|
+
/* @__PURE__ */ jsxs8("div", { className: "sia-upload__list", children: [
|
|
1559
|
+
showUploadList && files.map((file) => /* @__PURE__ */ jsx8(UploadItem, { file, files, props: { listType, disabled, itemRender, onPreview, downloadRequest }, actions: {
|
|
1314
1560
|
upload: () => start(file),
|
|
1315
1561
|
abort: () => abort(file.uid),
|
|
1316
1562
|
remove: () => remove(file.uid),
|
|
1563
|
+
download: () => downloadUploadFile(file, downloadRequest),
|
|
1317
1564
|
preview: () => {
|
|
1318
1565
|
if (onPreview) onPreview(file);
|
|
1319
|
-
else setPreview(file);
|
|
1566
|
+
else if ((file.type || file.originFileObj?.type)?.startsWith("image/") || /\.(png|jpe?g|gif|webp|avif|svg)$/i.test(file.name)) setPreview(file);
|
|
1567
|
+
else if (file.url || file.originFileObj) {
|
|
1568
|
+
const url = file.url || URL.createObjectURL(file.originFileObj);
|
|
1569
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
1570
|
+
if (!file.url) window.setTimeout(() => URL.revokeObjectURL(url), 6e4);
|
|
1571
|
+
} else if (file.thumbUrl) setPreview(file);
|
|
1320
1572
|
}
|
|
1321
1573
|
} }, file.uid)),
|
|
1322
1574
|
listType === "picture-card" && trigger
|
|
1323
1575
|
] }),
|
|
1324
|
-
/* @__PURE__ */
|
|
1576
|
+
/* @__PURE__ */ jsx8(ImagePreview, { open: !!preview && !!(preview.url || previewSource), src: preview?.url || previewSource, alt: preview?.name, onOpenChange: (open) => {
|
|
1325
1577
|
if (!open) setPreview(void 0);
|
|
1326
1578
|
} })
|
|
1327
1579
|
]
|
|
@@ -1329,15 +1581,15 @@ var UploadRoot = forwardRef(function UploadRoot2({
|
|
|
1329
1581
|
);
|
|
1330
1582
|
});
|
|
1331
1583
|
var UploadDragger = forwardRef(function UploadDragger2({ hint = "\u652F\u6301\u5355\u4E2A\u6216\u6279\u91CF\u4E0A\u4F20", children, className = "", ...props }, ref) {
|
|
1332
|
-
return /* @__PURE__ */
|
|
1333
|
-
/* @__PURE__ */
|
|
1334
|
-
/* @__PURE__ */
|
|
1584
|
+
return /* @__PURE__ */ jsx8(UploadRoot, { ...props, ref, className: `sia-upload-dragger ${className}`.trim(), children: children ?? /* @__PURE__ */ jsxs8("span", { className: "sia-upload-dragger__content", children: [
|
|
1585
|
+
/* @__PURE__ */ jsx8(Icon, { name: "upload", size: 32 }),
|
|
1586
|
+
/* @__PURE__ */ jsxs8("strong", { children: [
|
|
1335
1587
|
"\u70B9\u51FB\u6216\u62D6\u62FD",
|
|
1336
1588
|
props.directory ? "\u6587\u4EF6\u5939" : "\u6587\u4EF6",
|
|
1337
1589
|
"\u5230\u6B64\u533A\u57DF\u4E0A\u4F20"
|
|
1338
1590
|
] }),
|
|
1339
|
-
/* @__PURE__ */
|
|
1340
|
-
props.pastable && /* @__PURE__ */
|
|
1591
|
+
/* @__PURE__ */ jsx8("span", { children: hint }),
|
|
1592
|
+
props.pastable && /* @__PURE__ */ jsx8("span", { children: "\u805A\u7126\u6B64\u533A\u57DF\u540E\u6309 Ctrl / \u2318 + V \u7C98\u8D34\u6587\u4EF6\u6216\u622A\u56FE" })
|
|
1341
1593
|
] }) });
|
|
1342
1594
|
});
|
|
1343
1595
|
var Upload = Object.assign(UploadRoot, {
|
|
@@ -1347,111 +1599,6 @@ var Upload = Object.assign(UploadRoot, {
|
|
|
1347
1599
|
LIST_IGNORE
|
|
1348
1600
|
});
|
|
1349
1601
|
|
|
1350
|
-
// src/components/Message.tsx
|
|
1351
|
-
import { createRoot as createRoot2 } from "react-dom/client";
|
|
1352
|
-
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1353
|
-
var messageSeed = 0;
|
|
1354
|
-
var messageRoot = null;
|
|
1355
|
-
var messageContainer = null;
|
|
1356
|
-
var messageItems = [];
|
|
1357
|
-
var defaultDuration = 3;
|
|
1358
|
-
var maxCount = 5;
|
|
1359
|
-
var messageTimers = /* @__PURE__ */ new Map();
|
|
1360
|
-
var messageIcons = {
|
|
1361
|
-
info: /* @__PURE__ */ jsx8(Icon, { name: "info", size: 18 }),
|
|
1362
|
-
success: /* @__PURE__ */ jsx8(Icon, { name: "circle-check", size: 18 }),
|
|
1363
|
-
warning: /* @__PURE__ */ jsx8(Icon, { name: "warning", size: 18 }),
|
|
1364
|
-
error: /* @__PURE__ */ jsx8(Icon, { name: "circle-close", size: 18 }),
|
|
1365
|
-
loading: /* @__PURE__ */ jsx8(Icon, { name: "loader", size: 18, spin: true })
|
|
1366
|
-
};
|
|
1367
|
-
function ensureMessageRoot() {
|
|
1368
|
-
if (typeof document === "undefined") return false;
|
|
1369
|
-
if (!messageContainer) {
|
|
1370
|
-
messageContainer = document.createElement("div");
|
|
1371
|
-
messageContainer.className = "sia-message-root";
|
|
1372
|
-
document.body.appendChild(messageContainer);
|
|
1373
|
-
messageRoot = createRoot2(messageContainer);
|
|
1374
|
-
}
|
|
1375
|
-
return true;
|
|
1376
|
-
}
|
|
1377
|
-
function renderMessages() {
|
|
1378
|
-
if (!ensureMessageRoot()) return;
|
|
1379
|
-
messageRoot.render(/* @__PURE__ */ jsx8("div", { className: "sia-message-list", "aria-live": "polite", children: messageItems.map((item) => /* @__PURE__ */ jsxs8("div", { className: `sia-message sia-message--${item.type}`, role: item.type === "loading" ? "status" : "alert", children: [
|
|
1380
|
-
/* @__PURE__ */ jsx8("span", { className: "sia-message__icon", "aria-hidden": "true", children: messageIcons[item.type] }),
|
|
1381
|
-
/* @__PURE__ */ jsx8("span", { className: "sia-message__content", children: item.content }),
|
|
1382
|
-
item.closable ? /* @__PURE__ */ jsx8("button", { type: "button", className: "sia-message__close", "aria-label": "\u5173\u95ED\u63D0\u793A", onClick: () => closeMessage(item.key), children: /* @__PURE__ */ jsx8(Icon, { name: "close", size: 14 }) }) : null
|
|
1383
|
-
] }, item.key)) }));
|
|
1384
|
-
}
|
|
1385
|
-
function closeMessage(key) {
|
|
1386
|
-
const item = messageItems.find((candidate) => candidate.key === key);
|
|
1387
|
-
const timer = messageTimers.get(key);
|
|
1388
|
-
if (timer !== void 0) window.clearTimeout(timer);
|
|
1389
|
-
messageTimers.delete(key);
|
|
1390
|
-
messageItems = messageItems.filter((candidate) => candidate.key !== key);
|
|
1391
|
-
item?.onClose?.();
|
|
1392
|
-
renderMessages();
|
|
1393
|
-
}
|
|
1394
|
-
function scheduleMessage(item) {
|
|
1395
|
-
const existingTimer = messageTimers.get(item.key);
|
|
1396
|
-
if (existingTimer !== void 0) window.clearTimeout(existingTimer);
|
|
1397
|
-
const duration = item.duration ?? (item.type === "loading" ? 0 : defaultDuration);
|
|
1398
|
-
if (duration > 0) {
|
|
1399
|
-
messageTimers.set(item.key, window.setTimeout(() => closeMessage(item.key), duration * 1e3));
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
function openMessage(input) {
|
|
1403
|
-
const config = typeof input === "object" && input !== null && "content" in input ? input : { content: input };
|
|
1404
|
-
const key = config.key ?? `sia-message-${++messageSeed}`;
|
|
1405
|
-
const item = { ...config, key, type: config.type ?? "info" };
|
|
1406
|
-
const existingIndex = messageItems.findIndex((candidate) => candidate.key === key);
|
|
1407
|
-
if (existingIndex >= 0) messageItems = messageItems.map((candidate, index) => index === existingIndex ? item : candidate);
|
|
1408
|
-
else messageItems = [...messageItems, item];
|
|
1409
|
-
while (messageItems.length > maxCount) closeMessage(messageItems[0].key);
|
|
1410
|
-
renderMessages();
|
|
1411
|
-
scheduleMessage(item);
|
|
1412
|
-
return {
|
|
1413
|
-
close: () => closeMessage(key),
|
|
1414
|
-
update(next) {
|
|
1415
|
-
const current = messageItems.find((candidate) => candidate.key === key);
|
|
1416
|
-
if (!current) return;
|
|
1417
|
-
const updated = { ...current, ...next, key, type: next.type ?? current.type };
|
|
1418
|
-
messageItems = messageItems.map((candidate) => candidate.key === key ? updated : candidate);
|
|
1419
|
-
renderMessages();
|
|
1420
|
-
scheduleMessage(updated);
|
|
1421
|
-
}
|
|
1422
|
-
};
|
|
1423
|
-
}
|
|
1424
|
-
function shortcut(type) {
|
|
1425
|
-
return (content, duration) => openMessage({ content, duration, type });
|
|
1426
|
-
}
|
|
1427
|
-
var message = {
|
|
1428
|
-
/** 直接打开实例,返回可用于更新或关闭的操作句柄。 */
|
|
1429
|
-
open: openMessage,
|
|
1430
|
-
/** 显示普通信息提示。 */
|
|
1431
|
-
info: shortcut("info"),
|
|
1432
|
-
/** 显示成功提示。 */
|
|
1433
|
-
success: shortcut("success"),
|
|
1434
|
-
/** 显示警告提示。 */
|
|
1435
|
-
warning: shortcut("warning"),
|
|
1436
|
-
/** 显示错误提示。 */
|
|
1437
|
-
error: shortcut("error"),
|
|
1438
|
-
/** 显示持续加载提示。 */
|
|
1439
|
-
loading: shortcut("loading"),
|
|
1440
|
-
/** 关闭指定实例;未指定标识时关闭所有实例。 */
|
|
1441
|
-
destroy(key) {
|
|
1442
|
-
if (key !== void 0) {
|
|
1443
|
-
closeMessage(key);
|
|
1444
|
-
return;
|
|
1445
|
-
}
|
|
1446
|
-
[...messageItems].forEach((item) => closeMessage(item.key));
|
|
1447
|
-
},
|
|
1448
|
-
/** 配置消息默认持续时间和最大同时显示数量。 */
|
|
1449
|
-
config(config) {
|
|
1450
|
-
if (config.duration !== void 0) defaultDuration = config.duration;
|
|
1451
|
-
if (config.maxCount !== void 0) maxCount = Math.max(1, config.maxCount);
|
|
1452
|
-
}
|
|
1453
|
-
};
|
|
1454
|
-
|
|
1455
1602
|
// src/components/Breadcrumb.tsx
|
|
1456
1603
|
import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1457
1604
|
function Breadcrumb({ items, separator = "/", itemRender, className = "", ...props }) {
|
|
@@ -1784,8 +1931,8 @@ export {
|
|
|
1784
1931
|
Collapse,
|
|
1785
1932
|
ImagePreview,
|
|
1786
1933
|
Image,
|
|
1787
|
-
Upload,
|
|
1788
1934
|
message,
|
|
1935
|
+
Upload,
|
|
1789
1936
|
Breadcrumb,
|
|
1790
1937
|
Typography,
|
|
1791
1938
|
FloatButton2 as FloatButton
|
|
@@ -612,6 +612,17 @@ var coreIconPaths = {
|
|
|
612
612
|
/* @__PURE__ */ jsx2("circle", { cx: "10.8", cy: "10.8", r: "6.8" }),
|
|
613
613
|
/* @__PURE__ */ jsx2("path", { d: "m15.8 15.8 5.2 5.2M7.8 10.8h6" })
|
|
614
614
|
] }),
|
|
615
|
+
// 图片变换工具使用独立图标,便于在预览及其他编辑界面复用。
|
|
616
|
+
"flip-horizontal": /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M12 3v18M3 6h5v12H3zM16 6h5v12h-5z" }) }),
|
|
617
|
+
"flip-vertical": /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M3 12h18M6 3h12v5H6zM6 16h12v5H6z" }) }),
|
|
618
|
+
"rotate-left": /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
619
|
+
/* @__PURE__ */ jsx2("path", { d: "M4 9a8 8 0 1 1 0 6M4 3v6h6" }),
|
|
620
|
+
/* @__PURE__ */ jsx2("rect", { x: "9", y: "9", width: "6", height: "6", rx: "1" })
|
|
621
|
+
] }),
|
|
622
|
+
"rotate-right": /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
623
|
+
/* @__PURE__ */ jsx2("path", { d: "M20 9a8 8 0 1 0 0 6M20 3v6h-6" }),
|
|
624
|
+
/* @__PURE__ */ jsx2("rect", { x: "9", y: "9", width: "6", height: "6", rx: "1" })
|
|
625
|
+
] }),
|
|
615
626
|
download: /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M12 3v12M7 10l5 5 5-5M4 20h16" }) }),
|
|
616
627
|
upload: /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M12 16V4M7 9l5-5 5 5M4 20h16" }) }),
|
|
617
628
|
refresh: /* @__PURE__ */ jsxs2(Fragment2, { children: [
|