@sia.soul/sia-react-ui 0.1.35 → 0.1.37

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/index.cjs CHANGED
@@ -1131,6 +1131,17 @@ var coreIconPaths = {
1131
1131
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "10.8", cy: "10.8", r: "6.8" }),
1132
1132
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m15.8 15.8 5.2 5.2M7.8 10.8h6" })
1133
1133
  ] }),
1134
+ // 图片变换工具使用独立图标,便于在预览及其他编辑界面复用。
1135
+ "flip-horizontal": /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 3v18M3 6h5v12H3zM16 6h5v12h-5z" }) }),
1136
+ "flip-vertical": /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 12h18M6 3h12v5H6zM6 16h12v5H6z" }) }),
1137
+ "rotate-left": /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1138
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M4 9a8 8 0 1 1 0 6M4 3v6h6" }),
1139
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "9", y: "9", width: "6", height: "6", rx: "1" })
1140
+ ] }),
1141
+ "rotate-right": /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1142
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M20 9a8 8 0 1 0 0 6M20 3v6h-6" }),
1143
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "9", y: "9", width: "6", height: "6", rx: "1" })
1144
+ ] }),
1134
1145
  download: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 3v12M7 10l5 5 5-5M4 20h16" }) }),
1135
1146
  upload: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 16V4M7 9l5-5 5 5M4 20h16" }) }),
1136
1147
  refresh: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
@@ -4578,11 +4589,98 @@ function Collapse({ items, activeKey, defaultActiveKey = [], accordion = false,
4578
4589
  }
4579
4590
  function ImagePreview({ open, src, alt = "", onOpenChange }) {
4580
4591
  const previewRef = (0, import_react22.useRef)(null);
4592
+ const stageRef = (0, import_react22.useRef)(null);
4593
+ const [natural, setNatural] = (0, import_react22.useState)({ src: "", width: 0, height: 0 });
4594
+ const [area, setArea] = (0, import_react22.useState)({ width: 0, height: 0 });
4595
+ const [zoom, setZoom] = (0, import_react22.useState)(1);
4596
+ const [rotation, setRotation] = (0, import_react22.useState)(0);
4597
+ const [flip, setFlip] = (0, import_react22.useState)({ x: 1, y: 1 });
4598
+ const [pan, setPan] = (0, import_react22.useState)({ x: 0, y: 0 });
4599
+ const [failed, setFailed] = (0, import_react22.useState)(false);
4600
+ const drag = (0, import_react22.useRef)();
4581
4601
  useOverlayLifecycle(open, previewRef, () => onOpenChange(false));
4602
+ const reset = () => {
4603
+ setZoom(1);
4604
+ setRotation(0);
4605
+ setFlip({ x: 1, y: 1 });
4606
+ setPan({ x: 0, y: 0 });
4607
+ drag.current = void 0;
4608
+ };
4609
+ (0, import_react22.useEffect)(() => {
4610
+ reset();
4611
+ setFailed(false);
4612
+ }, [open, src]);
4613
+ (0, import_react22.useEffect)(() => {
4614
+ const stage = stageRef.current;
4615
+ if (!open || !stage) return;
4616
+ const measure = () => {
4617
+ setArea({ width: stage.clientWidth, height: stage.clientHeight });
4618
+ setPan({ x: 0, y: 0 });
4619
+ };
4620
+ measure();
4621
+ const observer = new ResizeObserver(measure);
4622
+ observer.observe(stage);
4623
+ return () => observer.disconnect();
4624
+ }, [open, src]);
4625
+ const ready = natural.src === src && natural.width > 0 && area.width > 0 && area.height > 0 && !failed;
4626
+ const sideways = Math.abs(rotation % 180) === 90;
4627
+ const fit = ready ? Math.min(1, area.width / (sideways ? natural.height : natural.width), area.height / (sideways ? natural.width : natural.height)) : 0;
4628
+ const changeZoom = (factor) => setZoom((value) => Math.max(0.25, Math.min(8, value * factor)));
4582
4629
  if (!open || !src || typeof document === "undefined") return null;
4583
4630
  return (0, import_react_dom4.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime20.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: [
4584
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", "aria-label": "\u5173\u95ED\u9884\u89C8", onClick: () => onOpenChange(false), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "close" }) }),
4585
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("img", { src, alt, onClick: (event) => event.stopPropagation() })
4631
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { variant: "text", className: "sia-image-preview__close", "aria-label": "\u5173\u95ED\u9884\u89C8", onClick: (event) => {
4632
+ event.stopPropagation();
4633
+ onOpenChange(false);
4634
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "close" }) }),
4635
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { ref: stageRef, className: "sia-image-preview__stage", children: failed ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sia-image-preview__error", children: "\u56FE\u7247\u52A0\u8F7D\u5931\u8D25" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4636
+ "img",
4637
+ {
4638
+ src,
4639
+ alt,
4640
+ draggable: false,
4641
+ 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})` },
4642
+ onLoad: (event) => setNatural({ src, width: event.currentTarget.naturalWidth, height: event.currentTarget.naturalHeight }),
4643
+ onError: () => setFailed(true),
4644
+ onClick: (event) => event.stopPropagation(),
4645
+ onPointerDown: (event) => {
4646
+ if (event.button !== 0) return;
4647
+ event.preventDefault();
4648
+ event.stopPropagation();
4649
+ event.currentTarget.setPointerCapture(event.pointerId);
4650
+ drag.current = { id: event.pointerId, x: event.clientX, y: event.clientY, left: pan.x, top: pan.y };
4651
+ },
4652
+ onPointerMove: (event) => {
4653
+ const start = drag.current;
4654
+ if (start?.id === event.pointerId) setPan({ x: start.left + event.clientX - start.x, y: start.top + event.clientY - start.y });
4655
+ },
4656
+ onPointerUp: () => {
4657
+ drag.current = void 0;
4658
+ },
4659
+ onPointerCancel: () => {
4660
+ drag.current = void 0;
4661
+ },
4662
+ onLostPointerCapture: () => {
4663
+ drag.current = void 0;
4664
+ }
4665
+ },
4666
+ src
4667
+ ) }),
4668
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "sia-image-preview__toolbar", role: "toolbar", "aria-label": "\u56FE\u7247\u64CD\u4F5C", onClick: (event) => event.stopPropagation(), children: [
4669
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(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__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "flip-horizontal", size: 20 }) }),
4670
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(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__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "flip-vertical", size: 20 }) }),
4671
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { variant: "text", title: "\u5411\u5DE6\u65CB\u8F6C", "aria-label": "\u5411\u5DE6\u65CB\u8F6C", disabled: !ready, onClick: () => {
4672
+ setRotation((value) => value - 90);
4673
+ setPan({ x: 0, y: 0 });
4674
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "rotate-left", size: 20 }) }),
4675
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { variant: "text", title: "\u5411\u53F3\u65CB\u8F6C", "aria-label": "\u5411\u53F3\u65CB\u8F6C", disabled: !ready, onClick: () => {
4676
+ setRotation((value) => value + 90);
4677
+ setPan({ x: 0, y: 0 });
4678
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "rotate-right", size: 20 }) }),
4679
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { variant: "text", title: "\u7F29\u5C0F", "aria-label": "\u7F29\u5C0F", disabled: !ready || zoom <= 0.25, onClick: () => changeZoom(1 / 1.25), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "zoom-out", size: 20 }) }),
4680
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("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" }),
4681
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { variant: "text", title: "\u653E\u5927", "aria-label": "\u653E\u5927", disabled: !ready || zoom >= 8, onClick: () => changeZoom(1.25), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "zoom-in", size: 20 }) }),
4682
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { variant: "text", title: "\u9002\u5E94\u7A97\u53E3", "aria-label": "\u9002\u5E94\u7A97\u53E3", disabled: !ready, onClick: reset, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "refresh", size: 20 }) })
4683
+ ] })
4586
4684
  ] }), document.body);
4587
4685
  }
4588
4686
  function Image2({ fallback, placeholder, preview = true, rootClassName = "", className = "", src, alt = "", onError, style, ...props }) {
@@ -6183,7 +6281,7 @@ function FormItem({
6183
6281
  const hasError = status === "error" && Boolean(helpContent);
6184
6282
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { ref: itemRef, className: `sia-form-item${status ? ` sia-form-item--${status}` : ""} ${className}`.trim(), "data-sia-form-field": key || void 0, children: [
6185
6283
  label ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { id: labelId, className: "sia-form-item__label", children: [
6186
- ruleRequired ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": "true", children: "*" }) : null,
6284
+ ruleRequired ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "sia-form-item__required-mark", "aria-hidden": "true", children: "*" }) : null,
6187
6285
  label
6188
6286
  ] }) : null,
6189
6287
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "sia-form-item__control", children: [
@@ -6237,7 +6335,7 @@ function FormErrorList({ errors = [] }) {
6237
6335
  return errors.length ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "sia-form-error-list", children: errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { children: error }, index)) }) : null;
6238
6336
  }
6239
6337
  var Form = Object.assign(FormRoot, {
6240
- /** 表单字段,负责字段值绑定、校验和标签布局;默认下外边距为 6px。 */
6338
+ /** 表单字段,负责字段值绑定、校验和标签布局。 */
6241
6339
  Item: FormItem,
6242
6340
  /** 动态表单列表,提供字段索引以及新增、删除、移动操作。 */
6243
6341
  List: FormList,
@@ -8215,10 +8313,158 @@ function sendUploadRequest(config, options) {
8215
8313
  return { abort };
8216
8314
  }
8217
8315
 
8218
- // src/components/Upload.tsx
8316
+ // src/components/uploadDownload.ts
8317
+ async function downloadUploadFile(file, request) {
8318
+ let blob;
8319
+ if (request) blob = await request(file);
8320
+ else if (file.url) {
8321
+ const response = await fetch(file.url);
8322
+ if (!response.ok) throw new Error(`\u4E0B\u8F7D\u5931\u8D25\uFF08HTTP ${response.status}\uFF09`);
8323
+ blob = await response.blob();
8324
+ } else if (file.originFileObj) blob = file.originFileObj;
8325
+ else throw new Error("\u6587\u4EF6\u7F3A\u5C11\u4E0B\u8F7D\u5730\u5740\u6216\u539F\u59CB\u5185\u5BB9");
8326
+ if (!(blob instanceof Blob)) throw new Error("\u4E0B\u8F7D\u8BF7\u6C42\u5FC5\u987B\u8FD4\u56DE Blob \u6587\u4EF6\u5185\u5BB9");
8327
+ const url = URL.createObjectURL(blob);
8328
+ const anchor = document.createElement("a");
8329
+ anchor.href = url;
8330
+ anchor.download = file.name;
8331
+ anchor.hidden = true;
8332
+ document.body.append(anchor);
8333
+ try {
8334
+ anchor.click();
8335
+ } finally {
8336
+ anchor.remove();
8337
+ window.setTimeout(() => URL.revokeObjectURL(url), 6e4);
8338
+ }
8339
+ }
8340
+
8341
+ // src/components/uploadImage.ts
8342
+ var imageExtension = /\.(png|jpe?g|gif|webp|avif|svg|bmp|ico|apng)$/i;
8343
+ function isUploadImage(file, accept) {
8344
+ if (!file) return false;
8345
+ if (file.thumbUrl) return true;
8346
+ const type = (file.type || file.originFileObj?.type || "").toLowerCase();
8347
+ if (type && type !== "application/octet-stream") return type.startsWith("image/");
8348
+ if (/^data:image\//i.test(file.url || "")) return true;
8349
+ let pathname = "";
8350
+ try {
8351
+ pathname = new URL(file.url || "", "https://upload.invalid").pathname;
8352
+ } catch {
8353
+ }
8354
+ if (imageExtension.test(file.name) || imageExtension.test(pathname)) return true;
8355
+ const rules = (accept || "").split(",").map((rule) => rule.trim().toLowerCase()).filter(Boolean);
8356
+ return Boolean(file.url) && rules.length > 0 && rules.every((rule) => rule.startsWith("image/") || imageExtension.test(rule));
8357
+ }
8358
+
8359
+ // src/components/Message.tsx
8360
+ var import_client5 = require("react-dom/client");
8219
8361
  var import_jsx_runtime37 = require("react/jsx-runtime");
8362
+ var messageSeed = 0;
8363
+ var messageRoot = null;
8364
+ var messageContainer = null;
8365
+ var messageItems = [];
8366
+ var defaultDuration = 3;
8367
+ var maxCount = 5;
8368
+ var messageTimers = /* @__PURE__ */ new Map();
8369
+ var messageIcons = {
8370
+ info: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: "info", size: 18 }),
8371
+ success: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: "circle-check", size: 18 }),
8372
+ warning: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: "warning", size: 18 }),
8373
+ error: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: "circle-close", size: 18 }),
8374
+ loading: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: "loader", size: 18, spin: true })
8375
+ };
8376
+ function ensureMessageRoot() {
8377
+ if (typeof document === "undefined") return false;
8378
+ if (!messageContainer) {
8379
+ messageContainer = document.createElement("div");
8380
+ messageContainer.className = "sia-message-root";
8381
+ document.body.appendChild(messageContainer);
8382
+ messageRoot = (0, import_client5.createRoot)(messageContainer);
8383
+ }
8384
+ return true;
8385
+ }
8386
+ function renderMessages() {
8387
+ if (!ensureMessageRoot()) return;
8388
+ messageRoot.render(/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "sia-message-list", "aria-live": "polite", children: messageItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: `sia-message sia-message--${item.type}`, role: item.type === "loading" ? "status" : "alert", children: [
8389
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "sia-message__icon", "aria-hidden": "true", children: messageIcons[item.type] }),
8390
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "sia-message__content", children: item.content }),
8391
+ item.closable ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: "sia-message__close", "aria-label": "\u5173\u95ED\u63D0\u793A", onClick: () => closeMessage(item.key), children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: "close", size: 14 }) }) : null
8392
+ ] }, item.key)) }));
8393
+ }
8394
+ function closeMessage(key) {
8395
+ const item = messageItems.find((candidate) => candidate.key === key);
8396
+ const timer = messageTimers.get(key);
8397
+ if (timer !== void 0) window.clearTimeout(timer);
8398
+ messageTimers.delete(key);
8399
+ messageItems = messageItems.filter((candidate) => candidate.key !== key);
8400
+ item?.onClose?.();
8401
+ renderMessages();
8402
+ }
8403
+ function scheduleMessage(item) {
8404
+ const existingTimer = messageTimers.get(item.key);
8405
+ if (existingTimer !== void 0) window.clearTimeout(existingTimer);
8406
+ const duration = item.duration ?? (item.type === "loading" ? 0 : defaultDuration);
8407
+ if (duration > 0) {
8408
+ messageTimers.set(item.key, window.setTimeout(() => closeMessage(item.key), duration * 1e3));
8409
+ }
8410
+ }
8411
+ function openMessage(input) {
8412
+ const config = typeof input === "object" && input !== null && "content" in input ? input : { content: input };
8413
+ const key = config.key ?? `sia-message-${++messageSeed}`;
8414
+ const item = { ...config, key, type: config.type ?? "info" };
8415
+ const existingIndex = messageItems.findIndex((candidate) => candidate.key === key);
8416
+ if (existingIndex >= 0) messageItems = messageItems.map((candidate, index) => index === existingIndex ? item : candidate);
8417
+ else messageItems = [...messageItems, item];
8418
+ while (messageItems.length > maxCount) closeMessage(messageItems[0].key);
8419
+ renderMessages();
8420
+ scheduleMessage(item);
8421
+ return {
8422
+ close: () => closeMessage(key),
8423
+ update(next) {
8424
+ const current = messageItems.find((candidate) => candidate.key === key);
8425
+ if (!current) return;
8426
+ const updated = { ...current, ...next, key, type: next.type ?? current.type };
8427
+ messageItems = messageItems.map((candidate) => candidate.key === key ? updated : candidate);
8428
+ renderMessages();
8429
+ scheduleMessage(updated);
8430
+ }
8431
+ };
8432
+ }
8433
+ function shortcut(type) {
8434
+ return (content, duration) => openMessage({ content, duration, type });
8435
+ }
8436
+ var message = {
8437
+ /** 直接打开实例,返回可用于更新或关闭的操作句柄。 */
8438
+ open: openMessage,
8439
+ /** 显示普通信息提示。 */
8440
+ info: shortcut("info"),
8441
+ /** 显示成功提示。 */
8442
+ success: shortcut("success"),
8443
+ /** 显示警告提示。 */
8444
+ warning: shortcut("warning"),
8445
+ /** 显示错误提示。 */
8446
+ error: shortcut("error"),
8447
+ /** 显示持续加载提示。 */
8448
+ loading: shortcut("loading"),
8449
+ /** 关闭指定实例;未指定标识时关闭所有实例。 */
8450
+ destroy(key) {
8451
+ if (key !== void 0) {
8452
+ closeMessage(key);
8453
+ return;
8454
+ }
8455
+ [...messageItems].forEach((item) => closeMessage(item.key));
8456
+ },
8457
+ /** 配置消息默认持续时间和最大同时显示数量。 */
8458
+ config(config) {
8459
+ if (config.duration !== void 0) defaultDuration = config.duration;
8460
+ if (config.maxCount !== void 0) maxCount = Math.max(1, config.maxCount);
8461
+ }
8462
+ };
8463
+
8464
+ // src/components/Upload.tsx
8465
+ var import_jsx_runtime38 = require("react/jsx-runtime");
8220
8466
  var LIST_IGNORE = /* @__PURE__ */ Symbol("SIA_UPLOAD_LIST_IGNORE");
8221
- function useThumbnail(file) {
8467
+ function useThumbnail(file, accept) {
8222
8468
  const [local, setLocal] = (0, import_react37.useState)();
8223
8469
  (0, import_react37.useEffect)(() => {
8224
8470
  if (!file?.thumbUrl && file?.originFileObj?.type.startsWith("image/")) {
@@ -8228,27 +8474,48 @@ function useThumbnail(file) {
8228
8474
  }
8229
8475
  setLocal(void 0);
8230
8476
  }, [file?.originFileObj, file?.thumbUrl]);
8231
- return file?.thumbUrl || local || (file?.type?.startsWith("image/") || /\.(png|jpe?g|gif|webp|avif|svg)(\?|$)/i.test(file?.url ?? "") ? file?.url : void 0);
8477
+ return file?.thumbUrl || local || (isUploadImage(file, accept) ? file?.url : void 0);
8232
8478
  }
8233
8479
  function UploadItem({ file, files, props, actions }) {
8234
- const source = useThumbnail(file);
8480
+ const source = useThumbnail(file, props.accept);
8235
8481
  const [failed, setFailed] = (0, import_react37.useState)(false);
8482
+ const [downloading, setDownloading] = (0, import_react37.useState)(false);
8483
+ const downloadingRef = (0, import_react37.useRef)(false);
8484
+ const canPreview = !!(source || file.url || file.originFileObj || props.onPreview);
8485
+ const canDownload = !!(file.url || file.originFileObj || props.downloadRequest);
8486
+ async function download() {
8487
+ if (downloadingRef.current) return;
8488
+ downloadingRef.current = true;
8489
+ setDownloading(true);
8490
+ try {
8491
+ await actions.download();
8492
+ } catch {
8493
+ message.error("\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u6587\u4EF6\u5730\u5740\u3001\u8BBF\u95EE\u6743\u9650\u6216\u8DE8\u57DF\u914D\u7F6E");
8494
+ } finally {
8495
+ downloadingRef.current = false;
8496
+ setDownloading(false);
8497
+ }
8498
+ }
8236
8499
  (0, import_react37.useEffect)(() => setFailed(false), [source]);
8237
- const node = /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: `sia-upload__item sia-upload__item--${file.status ?? "ready"}`, children: [
8238
- props.listType !== "text" ? /* @__PURE__ */ (0, import_jsx_runtime37.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_runtime37.jsx)("img", { src: source, alt: file.name, onError: () => setFailed(true) }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: file.type?.startsWith("image/") ? "image" : "file", size: 28 }) }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: file.status === "done" ? "circle-check" : "file", size: 16 }),
8239
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "sia-upload__name", ...withTitleTooltip({ title: file.relativePath || file.name }), children: file.url ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("a", { href: file.url, target: "_blank", rel: "noreferrer", children: file.name }) : file.name }),
8240
- /* @__PURE__ */ (0, import_jsx_runtime37.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_runtime37.jsx)(Icon, { name: "close", size: 14 }) }),
8241
- file.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "sia-upload__uploading", children: [
8242
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { children: [
8500
+ const node = /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: `sia-upload__item sia-upload__item--${file.status ?? "ready"}`, children: [
8501
+ props.listType !== "text" ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(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__ */ (0, import_jsx_runtime38.jsx)("img", { src: source, alt: file.name, onError: () => setFailed(true) }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: file.type?.startsWith("image/") ? "image" : "file", size: 28 }) }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: file.status === "done" ? "circle-check" : "file", size: 16 }),
8502
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "sia-upload__name", ...withTitleTooltip({ title: file.relativePath || file.name }), children: file.url ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("a", { href: file.url, target: "_blank", rel: "noreferrer", children: file.name }) : file.name }),
8503
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "sia-upload__actions", children: [
8504
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Button, { variant: "text", title: "\u9884\u89C8", "aria-label": `\u9884\u89C8 ${file.name}`, disabled: !canPreview, onClick: actions.preview, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: "eye", size: 14 }) }),
8505
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Button, { variant: "text", title: "\u4E0B\u8F7D", "aria-label": `\u4E0B\u8F7D ${file.name}`, disabled: !canDownload, loading: downloading, onClick: () => void download(), children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: "download", size: 14 }) }),
8506
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(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__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: "close", size: 14 }) })
8507
+ ] }),
8508
+ file.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "sia-upload__uploading", children: [
8509
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { children: [
8243
8510
  "\u4E0A\u4F20\u4E2D ",
8244
8511
  Math.round(file.percent ?? 0),
8245
8512
  "%"
8246
8513
  ] }),
8247
- /* @__PURE__ */ (0, import_jsx_runtime37.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_runtime37.jsx)("span", { style: { width: `${file.percent ?? 0}%` } }) })
8514
+ /* @__PURE__ */ (0, import_jsx_runtime38.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_runtime38.jsx)("span", { style: { width: `${file.percent ?? 0}%` } }) })
8248
8515
  ] }),
8249
- file.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "sia-upload__error", children: "\u4E0A\u4F20\u5931\u8D25" })
8516
+ file.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "sia-upload__error", children: "\u4E0A\u4F20\u5931\u8D25" })
8250
8517
  ] });
8251
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_jsx_runtime37.Fragment, { children: props.itemRender ? props.itemRender(node, file, files, actions) : node });
8518
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_jsx_runtime38.Fragment, { children: props.itemRender ? props.itemRender(node, file, files, actions) : node });
8252
8519
  }
8253
8520
  var UploadRoot = (0, import_react37.forwardRef)(function UploadRoot2({
8254
8521
  accept,
@@ -8262,6 +8529,7 @@ var UploadRoot = (0, import_react37.forwardRef)(function UploadRoot2({
8262
8529
  fileList,
8263
8530
  defaultFileList = [],
8264
8531
  listType = "text",
8532
+ cardSize,
8265
8533
  showUploadList = true,
8266
8534
  beforeUpload,
8267
8535
  request,
@@ -8271,9 +8539,11 @@ var UploadRoot = (0, import_react37.forwardRef)(function UploadRoot2({
8271
8539
  onReject,
8272
8540
  onReadError,
8273
8541
  onPreview,
8542
+ downloadRequest,
8274
8543
  itemRender,
8275
8544
  children,
8276
8545
  className = "",
8546
+ style,
8277
8547
  onDragOver,
8278
8548
  onDragLeave,
8279
8549
  onDrop,
@@ -8281,6 +8551,10 @@ var UploadRoot = (0, import_react37.forwardRef)(function UploadRoot2({
8281
8551
  tabIndex,
8282
8552
  ...props
8283
8553
  }, ref) {
8554
+ const cardDimension = (value) => value !== void 0 && Number.isFinite(value) ? Math.max(48, value) : 112;
8555
+ const cardWidth = cardDimension(typeof cardSize === "number" ? cardSize : cardSize?.width);
8556
+ const cardHeight = cardDimension(typeof cardSize === "number" ? cardSize : cardSize?.height);
8557
+ const compactCard = listType === "picture-card" && (cardWidth < 88 || cardHeight < 88);
8284
8558
  const inputRef = (0, import_react37.useRef)(null);
8285
8559
  const [internalFiles, setInternalFiles] = (0, import_react37.useState)(defaultFileList);
8286
8560
  const files = fileList ?? internalFiles;
@@ -8290,7 +8564,7 @@ var UploadRoot = (0, import_react37.forwardRef)(function UploadRoot2({
8290
8564
  const mounted = (0, import_react37.useRef)(true);
8291
8565
  const [dragging, setDragging] = (0, import_react37.useState)(false);
8292
8566
  const [preview, setPreview] = (0, import_react37.useState)();
8293
- const previewSource = useThumbnail(preview);
8567
+ const previewSource = useThumbnail(preview, accept);
8294
8568
  const limit = maxCount2 === void 0 || !Number.isFinite(maxCount2) ? Infinity : Math.max(0, Math.floor(maxCount2));
8295
8569
  const full = files.length >= limit;
8296
8570
  const current = (0, import_react37.useRef)({ disabled, directory, recursive });
@@ -8470,18 +8744,19 @@ var UploadRoot = (0, import_react37.forwardRef)(function UploadRoot2({
8470
8744
  event.preventDefault();
8471
8745
  ingest(selected.map((file) => ({ file, path: file.name })));
8472
8746
  }
8473
- const trigger = !(listType === "picture-card" && full) && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "sia-upload__trigger", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Button, { className: "sia-upload__choose", disabled: disabled || full, onClick: () => inputRef.current?.click(), children: children ?? (listType === "picture-card" ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
8474
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: "plus", size: 24 }),
8475
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: "\u4E0A\u4F20\u56FE\u7247" })
8476
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
8477
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: "upload", size: 16 }),
8747
+ const trigger = !(listType === "picture-card" && full) && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "sia-upload__trigger", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(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__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
8748
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: "plus", size: 24 }),
8749
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: "\u4E0A\u4F20\u56FE\u7247" })
8750
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
8751
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: "upload", size: 16 }),
8478
8752
  directory ? "\u9009\u62E9\u6587\u4EF6\u5939" : "\u9009\u62E9\u6587\u4EF6"
8479
8753
  ] })) }) });
8480
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
8754
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
8481
8755
  "div",
8482
8756
  {
8483
8757
  ...withTitleTooltip(props),
8484
- className: `sia-upload sia-upload--${listType}${dragging ? " is-dragging" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(),
8758
+ className: `sia-upload sia-upload--${listType}${compactCard ? " sia-upload--compact-card" : ""}${dragging ? " is-dragging" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(),
8759
+ style: listType === "picture-card" ? { "--sia-upload-card-width": `${cardWidth}px`, "--sia-upload-card-height": `${cardHeight}px`, ...style } : style,
8485
8760
  tabIndex: tabIndex ?? (pastable && !disabled ? 0 : void 0),
8486
8761
  onPaste: handlePaste,
8487
8762
  onDragOver: (event) => {
@@ -8497,7 +8772,7 @@ var UploadRoot = (0, import_react37.forwardRef)(function UploadRoot2({
8497
8772
  },
8498
8773
  onDrop: (event) => void handleDrop(event),
8499
8774
  children: [
8500
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8775
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
8501
8776
  "input",
8502
8777
  {
8503
8778
  ref: inputRef,
@@ -8514,19 +8789,25 @@ var UploadRoot = (0, import_react37.forwardRef)(function UploadRoot2({
8514
8789
  }
8515
8790
  ),
8516
8791
  listType !== "picture-card" && trigger,
8517
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "sia-upload__list", children: [
8518
- showUploadList && files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(UploadItem, { file, files, props: { listType, disabled, itemRender, onPreview }, actions: {
8792
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "sia-upload__list", children: [
8793
+ showUploadList && files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(UploadItem, { file, files, props: { listType, disabled, itemRender, onPreview, downloadRequest, accept }, actions: {
8519
8794
  upload: () => start(file),
8520
8795
  abort: () => abort(file.uid),
8521
8796
  remove: () => remove(file.uid),
8797
+ download: () => downloadUploadFile(file, downloadRequest),
8522
8798
  preview: () => {
8523
8799
  if (onPreview) onPreview(file);
8524
- else setPreview(file);
8800
+ else if (isUploadImage(file, accept)) setPreview(file);
8801
+ else if (file.url || file.originFileObj) {
8802
+ const url = file.url || URL.createObjectURL(file.originFileObj);
8803
+ window.open(url, "_blank", "noopener,noreferrer");
8804
+ if (!file.url) window.setTimeout(() => URL.revokeObjectURL(url), 6e4);
8805
+ } else if (file.thumbUrl) setPreview(file);
8525
8806
  }
8526
8807
  } }, file.uid)),
8527
8808
  listType === "picture-card" && trigger
8528
8809
  ] }),
8529
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ImagePreview, { open: !!preview && !!(preview.url || previewSource), src: preview?.url || previewSource, alt: preview?.name, onOpenChange: (open) => {
8810
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ImagePreview, { open: !!preview && !!(preview.url || previewSource), src: preview?.url || previewSource, alt: preview?.name, onOpenChange: (open) => {
8530
8811
  if (!open) setPreview(void 0);
8531
8812
  } })
8532
8813
  ]
@@ -8534,15 +8815,15 @@ var UploadRoot = (0, import_react37.forwardRef)(function UploadRoot2({
8534
8815
  );
8535
8816
  });
8536
8817
  var UploadDragger = (0, import_react37.forwardRef)(function UploadDragger2({ hint = "\u652F\u6301\u5355\u4E2A\u6216\u6279\u91CF\u4E0A\u4F20", children, className = "", ...props }, ref) {
8537
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(UploadRoot, { ...props, ref, className: `sia-upload-dragger ${className}`.trim(), children: children ?? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "sia-upload-dragger__content", children: [
8538
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: "upload", size: 32 }),
8539
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("strong", { children: [
8818
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(UploadRoot, { ...props, ref, className: `sia-upload-dragger ${className}`.trim(), children: children ?? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "sia-upload-dragger__content", children: [
8819
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: "upload", size: 32 }),
8820
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("strong", { children: [
8540
8821
  "\u70B9\u51FB\u6216\u62D6\u62FD",
8541
8822
  props.directory ? "\u6587\u4EF6\u5939" : "\u6587\u4EF6",
8542
8823
  "\u5230\u6B64\u533A\u57DF\u4E0A\u4F20"
8543
8824
  ] }),
8544
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: hint }),
8545
- props.pastable && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: "\u805A\u7126\u6B64\u533A\u57DF\u540E\u6309 Ctrl / \u2318 + V \u7C98\u8D34\u6587\u4EF6\u6216\u622A\u56FE" })
8825
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: hint }),
8826
+ props.pastable && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: "\u805A\u7126\u6B64\u533A\u57DF\u540E\u6309 Ctrl / \u2318 + V \u7C98\u8D34\u6587\u4EF6\u6216\u622A\u56FE" })
8546
8827
  ] }) });
8547
8828
  });
8548
8829
  var Upload = Object.assign(UploadRoot, {
@@ -8554,7 +8835,7 @@ var Upload = Object.assign(UploadRoot, {
8554
8835
 
8555
8836
  // src/components/TextArea.tsx
8556
8837
  var import_react38 = require("react");
8557
- var import_jsx_runtime38 = require("react/jsx-runtime");
8838
+ var import_jsx_runtime39 = require("react/jsx-runtime");
8558
8839
  var TextArea = (0, import_react38.forwardRef)(function TextArea2({
8559
8840
  label,
8560
8841
  hint,
@@ -8584,8 +8865,8 @@ var TextArea = (0, import_react38.forwardRef)(function TextArea2({
8584
8865
  setUncontrolledValue(event.target.value);
8585
8866
  onChange?.(event);
8586
8867
  }
8587
- const control = /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: `sia-textarea-control sia-textarea-control--${size} sia-textarea-control--${status}${floating.className}${disabled ? " is-disabled" : ""}`, children: [
8588
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
8868
+ const control = /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: `sia-textarea-control sia-textarea-control--${size} sia-textarea-control--${status}${floating.className}${disabled ? " is-disabled" : ""}`, children: [
8869
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
8589
8870
  "textarea",
8590
8871
  {
8591
8872
  ...withTitleTooltip(props),
@@ -8603,16 +8884,16 @@ var TextArea = (0, import_react38.forwardRef)(function TextArea2({
8603
8884
  }
8604
8885
  ),
8605
8886
  floating.label,
8606
- showCount ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: `sia-textarea-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
8887
+ showCount ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: `sia-textarea-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
8607
8888
  currentText.length,
8608
8889
  maxLength !== void 0 ? `/${maxLength}` : null
8609
8890
  ] }) : null
8610
8891
  ] });
8611
- if (!label && !hint) return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: `sia-field ${className}`.trim(), children: control });
8612
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: `sia-field ${className}`.trim(), children: [
8613
- label ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("label", { className: "sia-field__label", htmlFor: textAreaId, children: label }) : null,
8892
+ if (!label && !hint) return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: `sia-field ${className}`.trim(), children: control });
8893
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: `sia-field ${className}`.trim(), children: [
8894
+ label ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("label", { className: "sia-field__label", htmlFor: textAreaId, children: label }) : null,
8614
8895
  control,
8615
- hint ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
8896
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
8616
8897
  ] });
8617
8898
  });
8618
8899
 
@@ -8630,7 +8911,7 @@ var import_extension_table_cell = __toESM(require("@tiptap/extension-table-cell"
8630
8911
  var import_extension_task_list = __toESM(require("@tiptap/extension-task-list"), 1);
8631
8912
  var import_extension_task_item = __toESM(require("@tiptap/extension-task-item"), 1);
8632
8913
  var import_markdown = require("@tiptap/markdown");
8633
- var import_jsx_runtime39 = require("react/jsx-runtime");
8914
+ var import_jsx_runtime40 = require("react/jsx-runtime");
8634
8915
  function escapeHtml(value) {
8635
8916
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#039;");
8636
8917
  }
@@ -8647,8 +8928,8 @@ function sanitizeContent(value) {
8647
8928
  }
8648
8929
  function RichTextContent({ content, emptyText = "\u6682\u65E0\u5185\u5BB9", className = "", ...props }) {
8649
8930
  const html = (0, import_react39.useMemo)(() => sanitizeContent(content), [content]);
8650
- if (!html.trim()) return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: `sia-rich-text-content sia-rich-text-content--empty ${className}`.trim(), children: emptyText });
8651
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("article", { className: `sia-rich-text-content ${className}`.trim(), dangerouslySetInnerHTML: { __html: html }, ...withTitleTooltip(props) });
8931
+ if (!html.trim()) return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: `sia-rich-text-content sia-rich-text-content--empty ${className}`.trim(), children: emptyText });
8932
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("article", { className: `sia-rich-text-content ${className}`.trim(), dangerouslySetInnerHTML: { __html: html }, ...withTitleTooltip(props) });
8652
8933
  }
8653
8934
  function RichTextEditor({
8654
8935
  value,
@@ -8790,7 +9071,7 @@ function RichTextEditor({
8790
9071
  setLinkEditorOpen(false);
8791
9072
  }
8792
9073
  function formatButton(label, action, active = false, disabledByState = false, content) {
8793
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
9074
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8794
9075
  Button,
8795
9076
  {
8796
9077
  type: "button",
@@ -8828,27 +9109,27 @@ function RichTextEditor({
8828
9109
  }
8829
9110
  };
8830
9111
  const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: editor ? !editor.isEmpty : Boolean(value ?? defaultValue) });
8831
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { ...withTitleTooltip(props), id, style: mergedStyle, className: `sia-rich-text-editor${floating.className}${disabled ? " is-disabled" : ""} sia-rich-text-editor--${toolbar} ${className}`.trim(), children: [
9112
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { ...withTitleTooltip(props), id, style: mergedStyle, className: `sia-rich-text-editor${floating.className}${disabled ? " is-disabled" : ""} sia-rich-text-editor--${toolbar} ${className}`.trim(), children: [
8832
9113
  floating.label,
8833
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "sia-rich-text-editor__toolbar", "aria-label": "\u6587\u672C\u683C\u5F0F\u5DE5\u5177\u680F", children: [
8834
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "sia-rich-text-editor__toolbar-main", children: [
8835
- toolbar === "full" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
8836
- formatButton("\u64A4\u9500", () => editor?.chain().focus().undo().run(), false, !editor?.can().undo(), /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: "undo" })),
8837
- formatButton("\u91CD\u505A", () => editor?.chain().focus().redo().run(), false, !editor?.can().redo(), /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: "redo" })),
8838
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "sia-rich-text-editor__divider" }),
8839
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Dropdown, { menu: blockTypeMenu, trigger: ["click"], placement: "bottomLeft", disabled: disabled || !editor, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(Button, { type: "button", variant: "text", size: "small", className: "sia-rich-text-editor__block-type", disabled: disabled || !editor, "aria-label": "\u6BB5\u843D\u683C\u5F0F", title: "\u6BB5\u843D\u683C\u5F0F", onMouseDown: (event) => event.preventDefault(), children: [
9114
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "sia-rich-text-editor__toolbar", "aria-label": "\u6587\u672C\u683C\u5F0F\u5DE5\u5177\u680F", children: [
9115
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "sia-rich-text-editor__toolbar-main", children: [
9116
+ toolbar === "full" ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
9117
+ formatButton("\u64A4\u9500", () => editor?.chain().focus().undo().run(), false, !editor?.can().undo(), /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Icon, { name: "undo" })),
9118
+ formatButton("\u91CD\u505A", () => editor?.chain().focus().redo().run(), false, !editor?.can().redo(), /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Icon, { name: "redo" })),
9119
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "sia-rich-text-editor__divider" }),
9120
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Dropdown, { menu: blockTypeMenu, trigger: ["click"], placement: "bottomLeft", disabled: disabled || !editor, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Button, { type: "button", variant: "text", size: "small", className: "sia-rich-text-editor__block-type", disabled: disabled || !editor, "aria-label": "\u6BB5\u843D\u683C\u5F0F", title: "\u6BB5\u843D\u683C\u5F0F", onMouseDown: (event) => event.preventDefault(), children: [
8840
9121
  currentBlockLabel,
8841
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: "chevron-down", size: 13 })
9122
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Icon, { name: "chevron-down", size: 13 })
8842
9123
  ] }) }),
8843
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "sia-rich-text-editor__divider" })
9124
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "sia-rich-text-editor__divider" })
8844
9125
  ] }) : null,
8845
- formatButton("\u52A0\u7C97", () => editor?.chain().focus().toggleBold().run(), Boolean(editor?.isActive("bold")), false, /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("strong", { children: "B" })),
8846
- formatButton("\u659C\u4F53", () => editor?.chain().focus().toggleItalic().run(), Boolean(editor?.isActive("italic")), false, /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("em", { children: "I" })),
8847
- toolbar === "full" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
8848
- formatButton("\u4E0B\u5212\u7EBF", () => editor?.chain().focus().toggleUnderline().run(), Boolean(editor?.isActive("underline")), false, /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("u", { children: "U" })),
8849
- formatButton("\u5220\u9664\u7EBF", () => editor?.chain().focus().toggleStrike().run(), Boolean(editor?.isActive("strike")), false, /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("s", { children: "S" })),
9126
+ formatButton("\u52A0\u7C97", () => editor?.chain().focus().toggleBold().run(), Boolean(editor?.isActive("bold")), false, /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("strong", { children: "B" })),
9127
+ formatButton("\u659C\u4F53", () => editor?.chain().focus().toggleItalic().run(), Boolean(editor?.isActive("italic")), false, /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("em", { children: "I" })),
9128
+ toolbar === "full" ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
9129
+ formatButton("\u4E0B\u5212\u7EBF", () => editor?.chain().focus().toggleUnderline().run(), Boolean(editor?.isActive("underline")), false, /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("u", { children: "U" })),
9130
+ formatButton("\u5220\u9664\u7EBF", () => editor?.chain().focus().toggleStrike().run(), Boolean(editor?.isActive("strike")), false, /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("s", { children: "S" })),
8850
9131
  formatButton("\u884C\u5185\u4EE3\u7801", () => editor?.chain().focus().toggleCode().run(), Boolean(editor?.isActive("code")), false, "</>"),
8851
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
9132
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8852
9133
  Dropdown,
8853
9134
  {
8854
9135
  menu: { items: [] },
@@ -8858,48 +9139,48 @@ function RichTextEditor({
8858
9139
  disabled: disabled || !editor,
8859
9140
  onOpenChange: openLinkEditor,
8860
9141
  popupClassName: "sia-rich-text-editor__link-popup",
8861
- popupRender: () => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("form", { className: "sia-rich-text-editor__link-form", onSubmit: submitLink, children: [
8862
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Input, { autoFocus: true, "aria-label": "\u94FE\u63A5\u5730\u5740", value: linkHref, onChange: (event) => setLinkHref(event.target.value), placeholder: "https://example.com" }),
8863
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Button, { type: "submit", variant: "primary", size: "small", children: "\u5E94\u7528" }),
8864
- editor?.isActive("link") ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Button, { type: "button", size: "small", onClick: () => {
9142
+ popupRender: () => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("form", { className: "sia-rich-text-editor__link-form", onSubmit: submitLink, children: [
9143
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Input, { autoFocus: true, "aria-label": "\u94FE\u63A5\u5730\u5740", value: linkHref, onChange: (event) => setLinkHref(event.target.value), placeholder: "https://example.com" }),
9144
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Button, { type: "submit", variant: "primary", size: "small", children: "\u5E94\u7528" }),
9145
+ editor?.isActive("link") ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Button, { type: "button", size: "small", onClick: () => {
8865
9146
  setLinkHref("");
8866
9147
  editor.chain().focus().extendMarkRange("link").unsetLink().run();
8867
9148
  setLinkEditorOpen(false);
8868
9149
  }, children: "\u79FB\u9664" }) : null
8869
9150
  ] }),
8870
- children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Button, { type: "button", variant: "text", size: "small", className: `sia-rich-text-editor__tool${editor?.isActive("link") ? " is-active" : ""}`, disabled: disabled || !editor, "aria-label": "\u94FE\u63A5", "aria-pressed": editor?.isActive("link") || void 0, title: "\u94FE\u63A5", onMouseDown: (event) => event.preventDefault(), children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: "link" }) })
9151
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Button, { type: "button", variant: "text", size: "small", className: `sia-rich-text-editor__tool${editor?.isActive("link") ? " is-active" : ""}`, disabled: disabled || !editor, "aria-label": "\u94FE\u63A5", "aria-pressed": editor?.isActive("link") || void 0, title: "\u94FE\u63A5", onMouseDown: (event) => event.preventDefault(), children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Icon, { name: "link" }) })
8871
9152
  }
8872
9153
  ),
8873
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "sia-rich-text-editor__divider" })
9154
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "sia-rich-text-editor__divider" })
8874
9155
  ] }) : null,
8875
9156
  formatButton("\u65E0\u5E8F\u5217\u8868", () => editor?.chain().focus().toggleBulletList().run(), Boolean(editor?.isActive("bulletList")), false, "\u2022 \u5217\u8868"),
8876
9157
  formatButton("\u6709\u5E8F\u5217\u8868", () => editor?.chain().focus().toggleOrderedList().run(), Boolean(editor?.isActive("orderedList")), false, "1. \u5217\u8868"),
8877
- toolbar === "full" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
9158
+ toolbar === "full" ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
8878
9159
  formatButton("\u4EFB\u52A1\u5217\u8868", () => editor?.chain().focus().toggleTaskList().run(), Boolean(editor?.isActive("taskList")), false, "\u2611 \u4EFB\u52A1"),
8879
9160
  formatButton("\u5F15\u7528", () => editor?.chain().focus().toggleBlockquote().run(), Boolean(editor?.isActive("blockquote")), false, "\u275D \u5F15\u7528"),
8880
9161
  formatButton("\u4EE3\u7801\u5757", () => editor?.chain().focus().toggleCodeBlock().run(), Boolean(editor?.isActive("codeBlock")), false, "\u4EE3\u7801\u5757"),
8881
9162
  formatButton("\u63D2\u5165\u8868\u683C", () => editor?.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(), Boolean(editor?.isActive("table")), false, "\u8868\u683C"),
8882
- formatButton("\u5206\u5272\u7EBF", () => editor?.chain().focus().setHorizontalRule().run(), false, false, /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: "minus" }))
9163
+ formatButton("\u5206\u5272\u7EBF", () => editor?.chain().focus().setHorizontalRule().run(), false, false, /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Icon, { name: "minus" }))
8883
9164
  ] }) : null
8884
9165
  ] }),
8885
- onPasteImage ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("small", { children: [
8886
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: "image", size: 14 }),
9166
+ onPasteImage ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("small", { children: [
9167
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Icon, { name: "image", size: 14 }),
8887
9168
  pasteImageHint
8888
9169
  ] }) : null
8889
9170
  ] }),
8890
- toolbar === "full" && editor?.isActive("table") ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "sia-rich-text-editor__table-toolbar", "aria-label": "\u8868\u683C\u5DE5\u5177\u680F", children: [
8891
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: "\u8868\u683C" }),
9171
+ toolbar === "full" && editor?.isActive("table") ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "sia-rich-text-editor__table-toolbar", "aria-label": "\u8868\u683C\u5DE5\u5177\u680F", children: [
9172
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { children: "\u8868\u683C" }),
8892
9173
  formatButton("\u524D\u65B9\u63D2\u5165\u5217", () => editor.chain().focus().addColumnBefore().run(), false, !editor.can().addColumnBefore(), "\u524D\u63D2\u5217"),
8893
9174
  formatButton("\u540E\u65B9\u63D2\u5165\u5217", () => editor.chain().focus().addColumnAfter().run(), false, !editor.can().addColumnAfter(), "\u540E\u63D2\u5217"),
8894
9175
  formatButton("\u5220\u9664\u5F53\u524D\u5217", () => editor.chain().focus().deleteColumn().run(), false, !editor.can().deleteColumn(), "\u5220\u5217"),
8895
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "sia-rich-text-editor__divider" }),
9176
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "sia-rich-text-editor__divider" }),
8896
9177
  formatButton("\u4E0A\u65B9\u63D2\u5165\u884C", () => editor.chain().focus().addRowBefore().run(), false, !editor.can().addRowBefore(), "\u4E0A\u63D2\u884C"),
8897
9178
  formatButton("\u4E0B\u65B9\u63D2\u5165\u884C", () => editor.chain().focus().addRowAfter().run(), false, !editor.can().addRowAfter(), "\u4E0B\u63D2\u884C"),
8898
9179
  formatButton("\u5220\u9664\u5F53\u524D\u884C", () => editor.chain().focus().deleteRow().run(), false, !editor.can().deleteRow(), "\u5220\u884C"),
8899
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "sia-rich-text-editor__divider" }),
9180
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "sia-rich-text-editor__divider" }),
8900
9181
  formatButton("\u5220\u9664\u8868\u683C", () => editor.chain().focus().deleteTable().run(), false, !editor.can().deleteTable(), "\u5220\u9664\u8868\u683C")
8901
9182
  ] }) : null,
8902
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { ref: editorElementRef, className: "sia-rich-text-editor__content" })
9183
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { ref: editorElementRef, className: "sia-rich-text-editor__content" })
8903
9184
  ] });
8904
9185
  }
8905
9186
 
@@ -9013,7 +9294,7 @@ var VDITOR_ZH_CN = {
9013
9294
  };
9014
9295
 
9015
9296
  // src/components/MarkdownEditor.tsx
9016
- var import_jsx_runtime40 = require("react/jsx-runtime");
9297
+ var import_jsx_runtime41 = require("react/jsx-runtime");
9017
9298
  var vditorLoaders = /* @__PURE__ */ new Map();
9018
9299
  var BASE_TOOLBAR = [
9019
9300
  "headings",
@@ -9273,7 +9554,7 @@ function MarkdownEditor({
9273
9554
  ...style,
9274
9555
  "--sia-markdown-editor-min-height": typeof minHeight === "number" ? `${minHeight}px` : minHeight
9275
9556
  };
9276
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
9557
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
9277
9558
  "div",
9278
9559
  {
9279
9560
  className: ["sia-markdown-editor", floating.className, disabled ? "is-disabled" : "", className].filter(Boolean).join(" "),
@@ -9287,8 +9568,8 @@ function MarkdownEditor({
9287
9568
  },
9288
9569
  children: [
9289
9570
  floating.label,
9290
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { ref: mountRef, className: "sia-markdown-editor__mount" }),
9291
- !ready ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "sia-markdown-editor__loading", "aria-live": "polite", children: loadError || "\u6B63\u5728\u52A0\u8F7D\u7F16\u8F91\u5668\u2026" }) : null
9571
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { ref: mountRef, className: "sia-markdown-editor__mount" }),
9572
+ !ready ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "sia-markdown-editor__loading", "aria-live": "polite", children: loadError || "\u6B63\u5728\u52A0\u8F7D\u7F16\u8F91\u5668\u2026" }) : null
9292
9573
  ]
9293
9574
  }
9294
9575
  );
@@ -9689,7 +9970,7 @@ function registerSqlLanguages(monaco) {
9689
9970
  }
9690
9971
 
9691
9972
  // src/components/Editor.tsx
9692
- var import_jsx_runtime41 = require("react/jsx-runtime");
9973
+ var import_jsx_runtime42 = require("react/jsx-runtime");
9693
9974
  var EDITOR_COMMAND_SHORTCUTS = {
9694
9975
  cut: "Ctrl+X",
9695
9976
  copy: "Ctrl+C",
@@ -10292,11 +10573,11 @@ function Editor({
10292
10573
  })));
10293
10574
  });
10294
10575
  }, [generatedId, loading, markers]);
10295
- const editorNode = /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: `sia-editor-control ${className}`.trim(), "data-loading": loading || void 0, children: [
10296
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "sia-editor-control__surface", ref: containerRef, "aria-label": ariaLabel }),
10297
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { ref: rangeHighlightRef, className: "sia-editor-control__range-highlight", "aria-hidden": "true" }),
10298
- loading ? /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "sia-editor-control__loading", role: "status", children: [
10299
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", {}),
10576
+ const editorNode = /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: `sia-editor-control ${className}`.trim(), "data-loading": loading || void 0, children: [
10577
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "sia-editor-control__surface", ref: containerRef, "aria-label": ariaLabel }),
10578
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { ref: rangeHighlightRef, className: "sia-editor-control__range-highlight", "aria-hidden": "true" }),
10579
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "sia-editor-control__loading", role: "status", children: [
10580
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", {}),
10300
10581
  loadingText
10301
10582
  ] }) : null
10302
10583
  ] });
@@ -10325,7 +10606,7 @@ function Editor({
10325
10606
  item.onClick?.(api);
10326
10607
  }
10327
10608
  }
10328
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10609
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
10329
10610
  Dropdown,
10330
10611
  {
10331
10612
  className: "sia-editor-control__context-menu",
@@ -10345,7 +10626,7 @@ function Editor({
10345
10626
  var import_react42 = require("react");
10346
10627
  var import_dompurify2 = __toESM(require("dompurify"), 1);
10347
10628
  var import_marked = require("marked");
10348
- var import_jsx_runtime42 = require("react/jsx-runtime");
10629
+ var import_jsx_runtime43 = require("react/jsx-runtime");
10349
10630
  function Markdown2({ content, emptyText = "\u6682\u65E0 Markdown \u5185\u5BB9", resolveImageSrc, imagePreview = true, className = "", onClick, onKeyDown, ...props }) {
10350
10631
  const rootRef = (0, import_react42.useRef)(null);
10351
10632
  const [previewImage, setPreviewImage] = (0, import_react42.useState)(null);
@@ -10411,11 +10692,11 @@ function Markdown2({ content, emptyText = "\u6682\u65E0 Markdown \u5185\u5BB9",
10411
10692
  onKeyDown?.(event);
10412
10693
  }
10413
10694
  if (!content.trim()) {
10414
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: `sia-markdown sia-markdown--empty ${className}`.trim(), children: emptyText });
10695
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: `sia-markdown sia-markdown--empty ${className}`.trim(), children: emptyText });
10415
10696
  }
10416
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
10417
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("article", { ...withTitleTooltip(props), ref: rootRef, className: `sia-markdown ${className}`.trim(), onClick: handleClick, onKeyDown: handleKeyDown, dangerouslySetInnerHTML: { __html: html } }),
10418
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ImagePreview, { open: Boolean(previewImage), src: previewImage?.src, alt: previewImage?.alt, onOpenChange: (open) => {
10697
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
10698
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("article", { ...withTitleTooltip(props), ref: rootRef, className: `sia-markdown ${className}`.trim(), onClick: handleClick, onKeyDown: handleKeyDown, dangerouslySetInnerHTML: { __html: html } }),
10699
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ImagePreview, { open: Boolean(previewImage), src: previewImage?.src, alt: previewImage?.alt, onOpenChange: (open) => {
10419
10700
  if (!open) setPreviewImage(null);
10420
10701
  } })
10421
10702
  ] });
@@ -10423,7 +10704,7 @@ function Markdown2({ content, emptyText = "\u6682\u65E0 Markdown \u5185\u5BB9",
10423
10704
 
10424
10705
  // src/components/InputNumber.tsx
10425
10706
  var import_react43 = require("react");
10426
- var import_jsx_runtime43 = require("react/jsx-runtime");
10707
+ var import_jsx_runtime44 = require("react/jsx-runtime");
10427
10708
  function formatValue(value, precision) {
10428
10709
  if (value === null || !Number.isFinite(value)) return "";
10429
10710
  return precision === void 0 ? String(value) : value.toFixed(precision);
@@ -10512,7 +10793,7 @@ var InputNumber = (0, import_react43.forwardRef)(function InputNumber2({
10512
10793
  const increaseDisabled = disabled || readOnly || max !== void 0 && currentValue !== null && currentValue >= max;
10513
10794
  const decreaseDisabled = disabled || readOnly || min !== void 0 && currentValue !== null && currentValue <= min;
10514
10795
  const floatingPlaceholder = usePlaceholderMode(placeholderMode) === "floating" && Boolean(placeholder);
10515
- const input = /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
10796
+ const input = /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
10516
10797
  "input",
10517
10798
  {
10518
10799
  ...withTitleTooltip(props),
@@ -10534,23 +10815,23 @@ var InputNumber = (0, import_react43.forwardRef)(function InputNumber2({
10534
10815
  onKeyDown: handleKeyDown
10535
10816
  }
10536
10817
  );
10537
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: `sia-input-number sia-input-number--${size} sia-input-number--${status}${floatingPlaceholder ? " sia-input-number--floating" : ""}${floatingPlaceholder && text.length > 0 ? " is-filled" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(), children: [
10538
- prefix ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "sia-input-number__affix", children: prefix }) : null,
10539
- floatingPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "sia-input-number__input-wrap", children: [
10818
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: `sia-input-number sia-input-number--${size} sia-input-number--${status}${floatingPlaceholder ? " sia-input-number--floating" : ""}${floatingPlaceholder && text.length > 0 ? " is-filled" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(), children: [
10819
+ prefix ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "sia-input-number__affix", children: prefix }) : null,
10820
+ floatingPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "sia-input-number__input-wrap", children: [
10540
10821
  input,
10541
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "sia-input-number__floating-placeholder", "aria-hidden": "true", children: placeholder })
10822
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "sia-input-number__floating-placeholder", "aria-hidden": "true", children: placeholder })
10542
10823
  ] }) : input,
10543
- suffix ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "sia-input-number__affix", children: suffix }) : null,
10544
- controls ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "sia-input-number__controls", children: [
10545
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", tabIndex: -1, "aria-label": "\u589E\u52A0\u6570\u503C", disabled: increaseDisabled, onClick: () => changeBy(1), children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Icon, { name: "chevron-up", size: 12 }) }),
10546
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", tabIndex: -1, "aria-label": "\u51CF\u5C11\u6570\u503C", disabled: decreaseDisabled, onClick: () => changeBy(-1), children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Icon, { name: "chevron-down", size: 12 }) })
10824
+ suffix ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "sia-input-number__affix", children: suffix }) : null,
10825
+ controls ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "sia-input-number__controls", children: [
10826
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("button", { type: "button", tabIndex: -1, "aria-label": "\u589E\u52A0\u6570\u503C", disabled: increaseDisabled, onClick: () => changeBy(1), children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Icon, { name: "chevron-up", size: 12 }) }),
10827
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("button", { type: "button", tabIndex: -1, "aria-label": "\u51CF\u5C11\u6570\u503C", disabled: decreaseDisabled, onClick: () => changeBy(-1), children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Icon, { name: "chevron-down", size: 12 }) })
10547
10828
  ] }) : null
10548
10829
  ] });
10549
10830
  });
10550
10831
 
10551
10832
  // src/components/SelectModal.tsx
10552
10833
  var import_react44 = require("react");
10553
- var import_jsx_runtime44 = require("react/jsx-runtime");
10834
+ var import_jsx_runtime45 = require("react/jsx-runtime");
10554
10835
  function SelectModalBody({ config, values, disabled, onChange }) {
10555
10836
  const [query, setQuery] = (0, import_react44.useState)("");
10556
10837
  const [selectedOnly, setSelectedOnly] = (0, import_react44.useState)(false);
@@ -10567,23 +10848,23 @@ function SelectModalBody({ config, values, disabled, onChange }) {
10567
10848
  });
10568
10849
  onChange([...next]);
10569
10850
  };
10570
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, { children: [
10571
- config.headerExtra != null && config.headerExtra !== false ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "sia-select-modal__header-extra", children: config.headerExtra }) : null,
10572
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "sia-select-modal__heading", children: [
10573
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { role: "tablist", "aria-label": "\u9009\u9879\u8303\u56F4", children: [
10574
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Button, { role: "tab", "aria-selected": !selectedOnly, variant: "link", onClick: () => setSelectedOnly(false), children: "\u5168\u90E8" }),
10575
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(Button, { role: "tab", "aria-selected": selectedOnly, variant: "link", onClick: () => setSelectedOnly(true), children: [
10851
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
10852
+ config.headerExtra != null && config.headerExtra !== false ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "sia-select-modal__header-extra", children: config.headerExtra }) : null,
10853
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "sia-select-modal__heading", children: [
10854
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { role: "tablist", "aria-label": "\u9009\u9879\u8303\u56F4", children: [
10855
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Button, { role: "tab", "aria-selected": !selectedOnly, variant: "link", onClick: () => setSelectedOnly(false), children: "\u5168\u90E8" }),
10856
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(Button, { role: "tab", "aria-selected": selectedOnly, variant: "link", onClick: () => setSelectedOnly(true), children: [
10576
10857
  "\u5DF2\u9009\u9879(",
10577
10858
  values.length,
10578
10859
  ")"
10579
10860
  ] })
10580
10861
  ] }),
10581
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
10862
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
10582
10863
  Input,
10583
10864
  {
10584
10865
  "aria-label": config.searchPlaceholder ?? "\u641C\u7D22\u9009\u9879",
10585
10866
  placeholder: config.searchPlaceholder ?? "\u641C\u7D22\u9009\u9879",
10586
- prefix: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Icon, { name: "search", size: 14 }),
10867
+ prefix: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Icon, { name: "search", size: 14 }),
10587
10868
  value: query,
10588
10869
  allowClear: true,
10589
10870
  disabled,
@@ -10594,8 +10875,8 @@ function SelectModalBody({ config, values, disabled, onChange }) {
10594
10875
  }
10595
10876
  )
10596
10877
  ] }),
10597
- multiple ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "sia-select-modal__actions", children: [
10598
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
10878
+ multiple ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "sia-select-modal__actions", children: [
10879
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
10599
10880
  Checkbox2,
10600
10881
  {
10601
10882
  checked: all,
@@ -10605,10 +10886,10 @@ function SelectModalBody({ config, values, disabled, onChange }) {
10605
10886
  children: "\u5168\u9009"
10606
10887
  }
10607
10888
  ),
10608
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Button, { variant: "link", size: "small", disabled: disabled || !enabled.length, onClick: () => batch("invert"), children: "\u53CD\u9009" }),
10609
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Button, { variant: "link", size: "small", danger: true, disabled: disabled || !values.length, onClick: () => onChange([]), children: "\u6E05\u7A7A" })
10889
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Button, { variant: "link", size: "small", disabled: disabled || !enabled.length, onClick: () => batch("invert"), children: "\u53CD\u9009" }),
10890
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Button, { variant: "link", size: "small", danger: true, disabled: disabled || !values.length, onClick: () => onChange([]), children: "\u6E05\u7A7A" })
10610
10891
  ] }) : null,
10611
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
10892
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
10612
10893
  SelectionPanel,
10613
10894
  {
10614
10895
  options: filtered,
@@ -10634,7 +10915,7 @@ function openSelectModal(config) {
10634
10915
  if (config.mode !== "multiple") values = values.slice(0, 1);
10635
10916
  let submitting = false;
10636
10917
  function body() {
10637
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(SelectModalBody, { config: current, values, disabled: submitting || Boolean(current.confirmLoading), onChange: (next) => {
10918
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(SelectModalBody, { config: current, values, disabled: submitting || Boolean(current.confirmLoading), onChange: (next) => {
10638
10919
  values = next;
10639
10920
  handle.update({ children: body() });
10640
10921
  } });
@@ -10676,111 +10957,6 @@ function openSelectModal(config) {
10676
10957
  };
10677
10958
  }
10678
10959
 
10679
- // src/components/Message.tsx
10680
- var import_client5 = require("react-dom/client");
10681
- var import_jsx_runtime45 = require("react/jsx-runtime");
10682
- var messageSeed = 0;
10683
- var messageRoot = null;
10684
- var messageContainer = null;
10685
- var messageItems = [];
10686
- var defaultDuration = 3;
10687
- var maxCount = 5;
10688
- var messageTimers = /* @__PURE__ */ new Map();
10689
- var messageIcons = {
10690
- info: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Icon, { name: "info", size: 18 }),
10691
- success: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Icon, { name: "circle-check", size: 18 }),
10692
- warning: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Icon, { name: "warning", size: 18 }),
10693
- error: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Icon, { name: "circle-close", size: 18 }),
10694
- loading: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Icon, { name: "loader", size: 18, spin: true })
10695
- };
10696
- function ensureMessageRoot() {
10697
- if (typeof document === "undefined") return false;
10698
- if (!messageContainer) {
10699
- messageContainer = document.createElement("div");
10700
- messageContainer.className = "sia-message-root";
10701
- document.body.appendChild(messageContainer);
10702
- messageRoot = (0, import_client5.createRoot)(messageContainer);
10703
- }
10704
- return true;
10705
- }
10706
- function renderMessages() {
10707
- if (!ensureMessageRoot()) return;
10708
- messageRoot.render(/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "sia-message-list", "aria-live": "polite", children: messageItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: `sia-message sia-message--${item.type}`, role: item.type === "loading" ? "status" : "alert", children: [
10709
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "sia-message__icon", "aria-hidden": "true", children: messageIcons[item.type] }),
10710
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "sia-message__content", children: item.content }),
10711
- item.closable ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", className: "sia-message__close", "aria-label": "\u5173\u95ED\u63D0\u793A", onClick: () => closeMessage(item.key), children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Icon, { name: "close", size: 14 }) }) : null
10712
- ] }, item.key)) }));
10713
- }
10714
- function closeMessage(key) {
10715
- const item = messageItems.find((candidate) => candidate.key === key);
10716
- const timer = messageTimers.get(key);
10717
- if (timer !== void 0) window.clearTimeout(timer);
10718
- messageTimers.delete(key);
10719
- messageItems = messageItems.filter((candidate) => candidate.key !== key);
10720
- item?.onClose?.();
10721
- renderMessages();
10722
- }
10723
- function scheduleMessage(item) {
10724
- const existingTimer = messageTimers.get(item.key);
10725
- if (existingTimer !== void 0) window.clearTimeout(existingTimer);
10726
- const duration = item.duration ?? (item.type === "loading" ? 0 : defaultDuration);
10727
- if (duration > 0) {
10728
- messageTimers.set(item.key, window.setTimeout(() => closeMessage(item.key), duration * 1e3));
10729
- }
10730
- }
10731
- function openMessage(input) {
10732
- const config = typeof input === "object" && input !== null && "content" in input ? input : { content: input };
10733
- const key = config.key ?? `sia-message-${++messageSeed}`;
10734
- const item = { ...config, key, type: config.type ?? "info" };
10735
- const existingIndex = messageItems.findIndex((candidate) => candidate.key === key);
10736
- if (existingIndex >= 0) messageItems = messageItems.map((candidate, index) => index === existingIndex ? item : candidate);
10737
- else messageItems = [...messageItems, item];
10738
- while (messageItems.length > maxCount) closeMessage(messageItems[0].key);
10739
- renderMessages();
10740
- scheduleMessage(item);
10741
- return {
10742
- close: () => closeMessage(key),
10743
- update(next) {
10744
- const current = messageItems.find((candidate) => candidate.key === key);
10745
- if (!current) return;
10746
- const updated = { ...current, ...next, key, type: next.type ?? current.type };
10747
- messageItems = messageItems.map((candidate) => candidate.key === key ? updated : candidate);
10748
- renderMessages();
10749
- scheduleMessage(updated);
10750
- }
10751
- };
10752
- }
10753
- function shortcut(type) {
10754
- return (content, duration) => openMessage({ content, duration, type });
10755
- }
10756
- var message = {
10757
- /** 直接打开实例,返回可用于更新或关闭的操作句柄。 */
10758
- open: openMessage,
10759
- /** 显示普通信息提示。 */
10760
- info: shortcut("info"),
10761
- /** 显示成功提示。 */
10762
- success: shortcut("success"),
10763
- /** 显示警告提示。 */
10764
- warning: shortcut("warning"),
10765
- /** 显示错误提示。 */
10766
- error: shortcut("error"),
10767
- /** 显示持续加载提示。 */
10768
- loading: shortcut("loading"),
10769
- /** 关闭指定实例;未指定标识时关闭所有实例。 */
10770
- destroy(key) {
10771
- if (key !== void 0) {
10772
- closeMessage(key);
10773
- return;
10774
- }
10775
- [...messageItems].forEach((item) => closeMessage(item.key));
10776
- },
10777
- /** 配置消息默认持续时间和最大同时显示数量。 */
10778
- config(config) {
10779
- if (config.duration !== void 0) defaultDuration = config.duration;
10780
- if (config.maxCount !== void 0) maxCount = Math.max(1, config.maxCount);
10781
- }
10782
- };
10783
-
10784
10960
  // src/components/Tag.tsx
10785
10961
  var import_jsx_runtime46 = require("react/jsx-runtime");
10786
10962
  function Tag({