@hkyhy/marsun-components-core 0.1.10 → 0.1.12

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.
Files changed (31) hide show
  1. package/dist/components/File/FilePreview/FilePreviewContent.js +54 -47
  2. package/dist/components/File/FilePreview/FilePreviewContent.js.map +1 -1
  3. package/dist/components/File/FilePreview/style.module.scss.js +17 -16
  4. package/dist/components/File/FilePreview/style.module.scss.js.map +1 -1
  5. package/dist/components/File/FilePreviewLink/index.d.ts +2 -0
  6. package/dist/components/File/FilePreviewLink/index.js +46 -33
  7. package/dist/components/File/FilePreviewLink/index.js.map +1 -1
  8. package/dist/components/File/FilePreviewLink/style.module.scss.js +7 -5
  9. package/dist/components/File/FilePreviewLink/style.module.scss.js.map +1 -1
  10. package/dist/components/LlmFormattedText/LlmFormattedText/index.d.ts +8 -0
  11. package/dist/components/LlmFormattedText/LlmFormattedText/index.js +42 -0
  12. package/dist/components/LlmFormattedText/LlmFormattedText/index.js.map +1 -0
  13. package/dist/components/LlmFormattedText/LlmFormattedText/style.module.scss.js +17 -0
  14. package/dist/components/LlmFormattedText/LlmFormattedText/style.module.scss.js.map +1 -0
  15. package/dist/components/LlmFormattedText/index.d.ts +4 -0
  16. package/dist/components/LlmFormattedText/parseLlmText.d.ts +14 -0
  17. package/dist/components/LlmFormattedText/parseLlmText.js +77 -0
  18. package/dist/components/LlmFormattedText/parseLlmText.js.map +1 -0
  19. package/dist/components/Sparkline/Sparkline/index.d.ts +11 -0
  20. package/dist/components/Sparkline/Sparkline/index.js +46 -0
  21. package/dist/components/Sparkline/Sparkline/index.js.map +1 -0
  22. package/dist/components/Sparkline/Sparkline/style.module.scss.js +8 -0
  23. package/dist/components/Sparkline/Sparkline/style.module.scss.js.map +1 -0
  24. package/dist/components/Sparkline/index.d.ts +2 -0
  25. package/dist/components/index.d.ts +2 -0
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.js +80 -73
  28. package/dist/index.js.map +1 -1
  29. package/dist/marsun-components-core.css +1 -1
  30. package/dist/styles/global.css +1 -1
  31. package/package.json +1 -1
@@ -1,83 +1,90 @@
1
- import { jsx as t } from "react/jsx-runtime";
2
- import { Empty as u, Spin as N } from "antd";
3
- import { useRef as v, useState as h, useEffect as x } from "react";
1
+ import { jsx as n } from "react/jsx-runtime";
2
+ import { Empty as u, Spin as x } from "antd";
3
+ import { useRef as h, useState as g, useEffect as N } from "react";
4
4
  import { getPreviewKind as E, needsBlobPreview as P } from "../previewKind.js";
5
- import s from "./style.module.scss.js";
5
+ import o from "./style.module.scss.js";
6
6
  import b from "classnames";
7
- async function B(i) {
8
- const e = await fetch(i);
7
+ async function H(r) {
8
+ const e = await fetch(r);
9
9
  if (!e.ok) throw new Error(`预览加载失败 (${e.status})`);
10
10
  return e.arrayBuffer();
11
11
  }
12
- async function T(i, e) {
13
- const [{ default: o }] = await Promise.all([
12
+ async function B(r, e) {
13
+ var d;
14
+ const [{ default: s }] = await Promise.all([
14
15
  import("@js-preview/excel"),
15
16
  Promise.resolve({ })
16
- ]), n = o.init(i);
17
- return await n.preview(e), () => n.destroy();
17
+ ]), a = Math.max(
18
+ ((d = r.parentElement) == null ? void 0 : d.clientHeight) ?? 0,
19
+ Math.round(window.innerHeight * 0.65),
20
+ 480
21
+ );
22
+ r.style.height = `${a}px`;
23
+ const t = s.init(r);
24
+ return await t.preview(e), () => t.destroy();
18
25
  }
19
- async function W(i, e) {
20
- const { renderAsync: o } = await import("docx-preview"), n = new Blob([e]);
21
- await o(n, i, i, {
26
+ async function C(r, e) {
27
+ const { renderAsync: s } = await import("docx-preview"), a = new Blob([e]);
28
+ await s(a, r, r, {
22
29
  inWrapper: !0,
23
30
  ignoreWidth: !1,
24
31
  ignoreHeight: !1,
25
32
  breakPages: !0
26
33
  });
27
34
  }
28
- async function k(i, e, o) {
29
- const { init: n } = await import("pptx-preview"), a = n(i, { width: o, height: Math.round(o * 0.5625), mode: "list" });
30
- return await a.preview(e), () => a.destroy();
35
+ async function M(r, e, s) {
36
+ const { init: a } = await import("pptx-preview"), t = a(r, { width: s, height: Math.round(s * 0.5625), mode: "list" });
37
+ return await t.preview(e), () => t.destroy();
31
38
  }
32
- function C(i, e) {
33
- const o = new TextDecoder("utf-8"), n = document.createElement("pre");
34
- n.className = s["file-preview-text"], n.textContent = o.decode(e), i.appendChild(n);
39
+ function T(r, e) {
40
+ const s = new TextDecoder("utf-8"), a = document.createElement("pre");
41
+ a.className = o["file-preview-text"], a.textContent = s.decode(e), r.appendChild(a);
35
42
  }
36
- const F = ({
37
- file: i,
43
+ const D = ({
44
+ file: r,
38
45
  previewUrl: e,
39
- unsupportedMessage: o = "暂不支持预览此文件类型"
46
+ unsupportedMessage: s = "暂不支持预览此文件类型"
40
47
  }) => {
41
- const n = v(null), a = v(void 0), [g, l] = h(!1), [m, p] = h(null), r = E(i);
42
- return x(() => {
43
- var w;
44
- const f = n.current;
48
+ const a = h(null), t = h(void 0), [d, m] = g(!1), [p, w] = g(null), i = E(r);
49
+ return N(() => {
50
+ var v;
51
+ const f = a.current;
45
52
  if (!f || !e) return;
46
- let d = !1;
47
- return (w = a.current) == null || w.call(a), a.current = void 0, f.innerHTML = "", p(null), (async () => {
48
- if (r !== "image" && !(r === "pdf" || r === "iframe") && !(r === "video" || r === "audio") && r !== "unsupported") {
49
- l(!0);
53
+ let l = !1;
54
+ return (v = t.current) == null || v.call(t), t.current = void 0, f.innerHTML = "", w(null), (async () => {
55
+ if (i !== "image" && !(i === "pdf" || i === "iframe") && !(i === "video" || i === "audio") && i !== "unsupported") {
56
+ m(!0);
50
57
  try {
51
- const c = await B(e);
52
- if (d) return;
53
- if (r === "excel")
54
- a.current = await T(f, c);
55
- else if (r === "word")
56
- await W(f, c);
57
- else if (r === "ppt") {
58
+ const c = await H(e);
59
+ if (l) return;
60
+ if (i === "excel")
61
+ t.current = await B(f, c);
62
+ else if (i === "word")
63
+ await C(f, c);
64
+ else if (i === "ppt") {
58
65
  const y = f.clientWidth || 852;
59
- a.current = await k(f, c, y);
60
- } else r === "text" && C(f, c);
66
+ t.current = await M(f, c, y);
67
+ } else i === "text" && T(f, c);
61
68
  } catch (c) {
62
- d || p(c instanceof Error ? c.message : "预览加载失败");
69
+ l || w(c instanceof Error ? c.message : "预览加载失败");
63
70
  } finally {
64
- d || l(!1);
71
+ l || m(!1);
65
72
  }
66
73
  }
67
74
  })(), () => {
68
75
  var c;
69
- d = !0, (c = a.current) == null || c.call(a), a.current = void 0, f.innerHTML = "";
76
+ l = !0, (c = t.current) == null || c.call(t), t.current = void 0, f.innerHTML = "";
70
77
  };
71
- }, [e, r, i.id, i.name]), e ? r === "image" ? /* @__PURE__ */ t("div", { className: s["file-preview-media-wrap"], children: /* @__PURE__ */ t("img", { src: e, alt: i.name, className: s["file-preview-image"] }) }) : r === "pdf" || r === "iframe" ? /* @__PURE__ */ t(
78
+ }, [e, i, r.id, r.name]), e ? i === "image" ? /* @__PURE__ */ n("div", { className: o["file-preview-media-wrap"], children: /* @__PURE__ */ n("img", { src: e, alt: r.name, className: o["file-preview-image"] }) }) : i === "pdf" || i === "iframe" ? /* @__PURE__ */ n(
72
79
  "iframe",
73
80
  {
74
81
  src: e,
75
- title: i.name,
76
- className: s["file-preview-iframe"]
82
+ title: r.name,
83
+ className: o["file-preview-iframe"]
77
84
  }
78
- ) : r === "video" ? /* @__PURE__ */ t("div", { className: s["file-preview-media-wrap"], children: /* @__PURE__ */ t("video", { src: e, controls: !0, className: s["file-preview-video"] }) }) : r === "audio" ? /* @__PURE__ */ t("div", { className: s["file-preview-audio-wrap"], children: /* @__PURE__ */ t("audio", { src: e, controls: !0, className: s["file-preview-audio"] }) }) : r === "unsupported" ? /* @__PURE__ */ t(u, { description: o }) : P(r) ? /* @__PURE__ */ t("div", { className: b(s["file-preview-office"], s["file-preview-office-wrap"]), children: /* @__PURE__ */ t(N, { spinning: g, children: m ? /* @__PURE__ */ t(u, { description: m }) : /* @__PURE__ */ t("div", { ref: n, className: s["file-preview-office-inner"] }) }) }) : /* @__PURE__ */ t(u, { description: o }) : /* @__PURE__ */ t(u, { description: "无可预览地址" });
85
+ ) : i === "video" ? /* @__PURE__ */ n("div", { className: o["file-preview-media-wrap"], children: /* @__PURE__ */ n("video", { src: e, controls: !0, className: o["file-preview-video"] }) }) : i === "audio" ? /* @__PURE__ */ n("div", { className: o["file-preview-audio-wrap"], children: /* @__PURE__ */ n("audio", { src: e, controls: !0, className: o["file-preview-audio"] }) }) : i === "unsupported" ? /* @__PURE__ */ n(u, { description: s }) : P(i) ? /* @__PURE__ */ n("div", { className: b(o["file-preview-office"], o["file-preview-office-wrap"]), children: /* @__PURE__ */ n(x, { spinning: d, wrapperClassName: o["file-preview-office-spin"], children: p ? /* @__PURE__ */ n(u, { description: p }) : /* @__PURE__ */ n("div", { ref: a, className: o["file-preview-office-inner"] }) }) }) : /* @__PURE__ */ n(u, { description: s }) : /* @__PURE__ */ n(u, { description: "无可预览地址" });
79
86
  };
80
87
  export {
81
- F as default
88
+ D as default
82
89
  };
83
90
  //# sourceMappingURL=FilePreviewContent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilePreviewContent.js","sources":["../../../../src/components/File/FilePreview/FilePreviewContent.tsx"],"sourcesContent":["import { Empty, Spin } from 'antd';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { getPreviewKind, needsBlobPreview } from '../previewKind';\nimport type { FileDisplayItem } from '../types';\nimport styles from './style.module.scss';\nimport classNames from 'classnames';\n\ninterface FilePreviewContentProps {\n file: FileDisplayItem;\n previewUrl?: string;\n unsupportedMessage?: string;\n}\n\nasync function fetchPreviewBlob(url: string): Promise<ArrayBuffer> {\n const res = await fetch(url);\n if (!res.ok) throw new Error(`预览加载失败 (${res.status})`);\n return res.arrayBuffer();\n}\n\nasync function renderExcel(container: HTMLElement, data: ArrayBuffer) {\n const [{ default: jsPreviewExcel }] = await Promise.all([\n import('@js-preview/excel'),\n import('@js-preview/excel/lib/index.css'),\n ]);\n const instance = jsPreviewExcel.init(container);\n await instance.preview(data);\n return () => instance.destroy();\n}\n\nasync function renderWord(container: HTMLElement, data: ArrayBuffer) {\n const { renderAsync } = await import('docx-preview');\n const blob = new Blob([data]);\n await renderAsync(blob, container, container, {\n inWrapper: true,\n ignoreWidth: false,\n ignoreHeight: false,\n breakPages: true,\n });\n}\n\nasync function renderPpt(container: HTMLElement, data: ArrayBuffer, width: number) {\n const { init } = await import('pptx-preview');\n const previewer = init(container, { width, height: Math.round(width * 0.5625), mode: 'list' });\n await previewer.preview(data);\n return () => previewer.destroy();\n}\n\nfunction renderText(container: HTMLElement, data: ArrayBuffer) {\n const decoder = new TextDecoder('utf-8');\n const pre = document.createElement('pre');\n pre.className = styles['file-preview-text'] ?? '';\n pre.textContent = decoder.decode(data);\n container.appendChild(pre);\n}\n\nconst FilePreviewContent: React.FC<FilePreviewContentProps> = ({\n file,\n previewUrl,\n unsupportedMessage = '暂不支持预览此文件类型',\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const cleanupRef = useRef<(() => void) | void>(undefined);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const kind = getPreviewKind(file);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !previewUrl) return undefined;\n\n let cancelled = false;\n cleanupRef.current?.();\n cleanupRef.current = undefined;\n container.innerHTML = '';\n setError(null);\n\n const run = async () => {\n if (kind === 'image') return;\n if (kind === 'pdf' || kind === 'iframe') return;\n if (kind === 'video' || kind === 'audio') return;\n if (kind === 'unsupported') return;\n\n setLoading(true);\n try {\n const data = await fetchPreviewBlob(previewUrl);\n if (cancelled) return;\n\n if (kind === 'excel') {\n cleanupRef.current = await renderExcel(container, data);\n } else if (kind === 'word') {\n await renderWord(container, data);\n } else if (kind === 'ppt') {\n const width = container.clientWidth || 852;\n cleanupRef.current = await renderPpt(container, data, width);\n } else if (kind === 'text') {\n renderText(container, data);\n }\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err.message : '预览加载失败');\n }\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n\n void run();\n\n return () => {\n cancelled = true;\n cleanupRef.current?.();\n cleanupRef.current = undefined;\n container.innerHTML = '';\n };\n }, [previewUrl, kind, file.id, file.name]);\n\n if (!previewUrl) {\n return <Empty description=\"无可预览地址\" />;\n }\n\n if (kind === 'image') {\n return (\n <div className={styles['file-preview-media-wrap']}>\n <img src={previewUrl} alt={file.name} className={styles['file-preview-image']} />\n </div>\n );\n }\n\n if (kind === 'pdf' || kind === 'iframe') {\n return (\n <iframe\n src={previewUrl}\n title={file.name}\n className={styles['file-preview-iframe']}\n />\n );\n }\n\n if (kind === 'video') {\n return (\n <div className={styles['file-preview-media-wrap']}>\n <video src={previewUrl} controls className={styles['file-preview-video']} />\n </div>\n );\n }\n\n if (kind === 'audio') {\n return (\n <div className={styles['file-preview-audio-wrap']}>\n <audio src={previewUrl} controls className={styles['file-preview-audio']} />\n </div>\n );\n }\n\n if (kind === 'unsupported') {\n return <Empty description={unsupportedMessage} />;\n }\n\n if (needsBlobPreview(kind)) {\n return (\n <div className={classNames(styles['file-preview-office'], styles['file-preview-office-wrap'])}>\n <Spin spinning={loading}>\n {error ? <Empty description={error} /> : <div ref={containerRef} className={styles['file-preview-office-inner']} />}\n </Spin>\n </div>\n );\n }\n\n return <Empty description={unsupportedMessage} />;\n};\n\nexport default FilePreviewContent;\n"],"names":["fetchPreviewBlob","url","res","renderExcel","container","data","jsPreviewExcel","instance","renderWord","renderAsync","blob","renderPpt","width","init","previewer","renderText","decoder","pre","styles","FilePreviewContent","file","previewUrl","unsupportedMessage","containerRef","useRef","cleanupRef","loading","setLoading","useState","error","setError","kind","getPreviewKind","useEffect","cancelled","_a","err","jsx","Empty","needsBlobPreview","classNames","Spin"],"mappings":";;;;;;AAaA,eAAeA,EAAiBC,GAAmC;AACjE,QAAMC,IAAM,MAAM,MAAMD,CAAG;AAC3B,MAAI,CAACC,EAAI,GAAI,OAAM,IAAI,MAAM,WAAWA,EAAI,MAAM,GAAG;AACrD,SAAOA,EAAI,YAAA;AACb;AAEA,eAAeC,EAAYC,GAAwBC,GAAmB;AACpE,QAAM,CAAC,EAAE,SAASC,EAAA,CAAgB,IAAI,MAAM,QAAQ,IAAI;AAAA,IACtD,OAAO,mBAAmB;AAAA,IAC1B,OAAO,0DAAiC;AAAA,EAAA,CACzC,GACKC,IAAWD,EAAe,KAAKF,CAAS;AAC9C,eAAMG,EAAS,QAAQF,CAAI,GACpB,MAAME,EAAS,QAAA;AACxB;AAEA,eAAeC,EAAWJ,GAAwBC,GAAmB;AACnE,QAAM,EAAE,aAAAI,EAAA,IAAgB,MAAM,OAAO,cAAc,GAC7CC,IAAO,IAAI,KAAK,CAACL,CAAI,CAAC;AAC5B,QAAMI,EAAYC,GAAMN,GAAWA,GAAW;AAAA,IAC5C,WAAW;AAAA,IACX,aAAa;AAAA,IACb,cAAc;AAAA,IACd,YAAY;AAAA,EAAA,CACb;AACH;AAEA,eAAeO,EAAUP,GAAwBC,GAAmBO,GAAe;AACjF,QAAM,EAAE,MAAAC,EAAA,IAAS,MAAM,OAAO,cAAc,GACtCC,IAAYD,EAAKT,GAAW,EAAE,OAAAQ,GAAO,QAAQ,KAAK,MAAMA,IAAQ,MAAM,GAAG,MAAM,QAAQ;AAC7F,eAAME,EAAU,QAAQT,CAAI,GACrB,MAAMS,EAAU,QAAA;AACzB;AAEA,SAASC,EAAWX,GAAwBC,GAAmB;AAC7D,QAAMW,IAAU,IAAI,YAAY,OAAO,GACjCC,IAAM,SAAS,cAAc,KAAK;AACxC,EAAAA,EAAI,YAAYC,EAAO,mBAAmB,GAC1CD,EAAI,cAAcD,EAAQ,OAAOX,CAAI,GACrCD,EAAU,YAAYa,CAAG;AAC3B;AAEA,MAAME,IAAwD,CAAC;AAAA,EAC7D,MAAAC;AAAA,EACA,YAAAC;AAAA,EACA,oBAAAC,IAAqB;AACvB,MAAM;AACJ,QAAMC,IAAeC,EAAuB,IAAI,GAC1CC,IAAaD,EAA4B,MAAS,GAClD,CAACE,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtC,CAACC,GAAOC,CAAQ,IAAIF,EAAwB,IAAI,GAChDG,IAAOC,EAAeZ,CAAI;AAoDhC,SAlDAa,EAAU,MAAM;;AACd,UAAM7B,IAAYmB,EAAa;AAC/B,QAAI,CAACnB,KAAa,CAACiB,EAAY;AAE/B,QAAIa,IAAY;AAChB,YAAAC,IAAAV,EAAW,YAAX,QAAAU,EAAA,KAAAV,IACAA,EAAW,UAAU,QACrBrB,EAAU,YAAY,IACtB0B,EAAS,IAAI,IAED,YAAY;AACtB,UAAIC,MAAS,WACT,EAAAA,MAAS,SAASA,MAAS,aAC3B,EAAAA,MAAS,WAAWA,MAAS,YAC7BA,MAAS,eAEb;AAAA,QAAAJ,EAAW,EAAI;AACf,YAAI;AACF,gBAAMtB,IAAO,MAAML,EAAiBqB,CAAU;AAC9C,cAAIa,EAAW;AAEf,cAAIH,MAAS;AACX,YAAAN,EAAW,UAAU,MAAMtB,EAAYC,GAAWC,CAAI;AAAA,mBAC7C0B,MAAS;AAClB,kBAAMvB,EAAWJ,GAAWC,CAAI;AAAA,mBACvB0B,MAAS,OAAO;AACzB,kBAAMnB,IAAQR,EAAU,eAAe;AACvC,YAAAqB,EAAW,UAAU,MAAMd,EAAUP,GAAWC,GAAMO,CAAK;AAAA,UAC7D,MAAA,CAAWmB,MAAS,UAClBhB,EAAWX,GAAWC,CAAI;AAAA,QAE9B,SAAS+B,GAAK;AACZ,UAAKF,KACHJ,EAASM,aAAe,QAAQA,EAAI,UAAU,QAAQ;AAAA,QAE1D,UAAA;AACE,UAAKF,KAAWP,EAAW,EAAK;AAAA,QAClC;AAAA;AAAA,IACF,GAEK,GAEE,MAAM;;AACX,MAAAO,IAAY,KACZC,IAAAV,EAAW,YAAX,QAAAU,EAAA,KAAAV,IACAA,EAAW,UAAU,QACrBrB,EAAU,YAAY;AAAA,IACxB;AAAA,EACF,GAAG,CAACiB,GAAYU,GAAMX,EAAK,IAAIA,EAAK,IAAI,CAAC,GAEpCC,IAIDU,MAAS,4BAER,OAAA,EAAI,WAAWb,EAAO,yBAAyB,GAC9C,UAAA,gBAAAmB,EAAC,OAAA,EAAI,KAAKhB,GAAY,KAAKD,EAAK,MAAM,WAAWF,EAAO,oBAAoB,GAAG,GACjF,IAIAa,MAAS,SAASA,MAAS,WAE3B,gBAAAM;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKhB;AAAA,MACL,OAAOD,EAAK;AAAA,MACZ,WAAWF,EAAO,qBAAqB;AAAA,IAAA;AAAA,EAAA,IAKzCa,MAAS,4BAER,OAAA,EAAI,WAAWb,EAAO,yBAAyB,GAC9C,UAAA,gBAAAmB,EAAC,SAAA,EAAM,KAAKhB,GAAY,UAAQ,IAAC,WAAWH,EAAO,oBAAoB,GAAG,GAC5E,IAIAa,MAAS,4BAER,OAAA,EAAI,WAAWb,EAAO,yBAAyB,GAC9C,UAAA,gBAAAmB,EAAC,SAAA,EAAM,KAAKhB,GAAY,UAAQ,IAAC,WAAWH,EAAO,oBAAoB,GAAG,GAC5E,IAIAa,MAAS,gBACJ,gBAAAM,EAACC,GAAA,EAAM,aAAahB,EAAA,CAAoB,IAG7CiB,EAAiBR,CAAI,IAErB,gBAAAM,EAAC,OAAA,EAAI,WAAWG,EAAWtB,EAAO,qBAAqB,GAAGA,EAAO,0BAA0B,CAAC,GAC1F,UAAA,gBAAAmB,EAACI,KAAK,UAAUf,GACb,UAAAG,IAAQ,gBAAAQ,EAACC,GAAA,EAAM,aAAaT,EAAA,CAAO,IAAK,gBAAAQ,EAAC,OAAA,EAAI,KAAKd,GAAc,WAAWL,EAAO,2BAA2B,EAAA,CAAG,GACnH,GACF,IAIG,gBAAAmB,EAACC,GAAA,EAAM,aAAahB,EAAA,CAAoB,IAnDtC,gBAAAe,EAACC,GAAA,EAAM,aAAY,SAAA,CAAS;AAoDvC;"}
1
+ {"version":3,"file":"FilePreviewContent.js","sources":["../../../../src/components/File/FilePreview/FilePreviewContent.tsx"],"sourcesContent":["import { Empty, Spin } from 'antd';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { getPreviewKind, needsBlobPreview } from '../previewKind';\nimport type { FileDisplayItem } from '../types';\nimport styles from './style.module.scss';\nimport classNames from 'classnames';\n\ninterface FilePreviewContentProps {\n file: FileDisplayItem;\n previewUrl?: string;\n unsupportedMessage?: string;\n}\n\nasync function fetchPreviewBlob(url: string): Promise<ArrayBuffer> {\n const res = await fetch(url);\n if (!res.ok) throw new Error(`预览加载失败 (${res.status})`);\n return res.arrayBuffer();\n}\n\nasync function renderExcel(container: HTMLElement, data: ArrayBuffer) {\n const [{ default: jsPreviewExcel }] = await Promise.all([\n import('@js-preview/excel'),\n import('@js-preview/excel/lib/index.css'),\n ]);\n const height = Math.max(\n container.parentElement?.clientHeight ?? 0,\n Math.round(window.innerHeight * 0.65),\n 480,\n );\n container.style.height = `${height}px`;\n const instance = jsPreviewExcel.init(container);\n await instance.preview(data);\n return () => instance.destroy();\n}\n\nasync function renderWord(container: HTMLElement, data: ArrayBuffer) {\n const { renderAsync } = await import('docx-preview');\n const blob = new Blob([data]);\n await renderAsync(blob, container, container, {\n inWrapper: true,\n ignoreWidth: false,\n ignoreHeight: false,\n breakPages: true,\n });\n}\n\nasync function renderPpt(container: HTMLElement, data: ArrayBuffer, width: number) {\n const { init } = await import('pptx-preview');\n const previewer = init(container, { width, height: Math.round(width * 0.5625), mode: 'list' });\n await previewer.preview(data);\n return () => previewer.destroy();\n}\n\nfunction renderText(container: HTMLElement, data: ArrayBuffer) {\n const decoder = new TextDecoder('utf-8');\n const pre = document.createElement('pre');\n pre.className = styles['file-preview-text'] ?? '';\n pre.textContent = decoder.decode(data);\n container.appendChild(pre);\n}\n\nconst FilePreviewContent: React.FC<FilePreviewContentProps> = ({\n file,\n previewUrl,\n unsupportedMessage = '暂不支持预览此文件类型',\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const cleanupRef = useRef<(() => void) | void>(undefined);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const kind = getPreviewKind(file);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !previewUrl) return undefined;\n\n let cancelled = false;\n cleanupRef.current?.();\n cleanupRef.current = undefined;\n container.innerHTML = '';\n setError(null);\n\n const run = async () => {\n if (kind === 'image') return;\n if (kind === 'pdf' || kind === 'iframe') return;\n if (kind === 'video' || kind === 'audio') return;\n if (kind === 'unsupported') return;\n\n setLoading(true);\n try {\n const data = await fetchPreviewBlob(previewUrl);\n if (cancelled) return;\n\n if (kind === 'excel') {\n cleanupRef.current = await renderExcel(container, data);\n } else if (kind === 'word') {\n await renderWord(container, data);\n } else if (kind === 'ppt') {\n const width = container.clientWidth || 852;\n cleanupRef.current = await renderPpt(container, data, width);\n } else if (kind === 'text') {\n renderText(container, data);\n }\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err.message : '预览加载失败');\n }\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n\n void run();\n\n return () => {\n cancelled = true;\n cleanupRef.current?.();\n cleanupRef.current = undefined;\n container.innerHTML = '';\n };\n }, [previewUrl, kind, file.id, file.name]);\n\n if (!previewUrl) {\n return <Empty description=\"无可预览地址\" />;\n }\n\n if (kind === 'image') {\n return (\n <div className={styles['file-preview-media-wrap']}>\n <img src={previewUrl} alt={file.name} className={styles['file-preview-image']} />\n </div>\n );\n }\n\n if (kind === 'pdf' || kind === 'iframe') {\n return (\n <iframe\n src={previewUrl}\n title={file.name}\n className={styles['file-preview-iframe']}\n />\n );\n }\n\n if (kind === 'video') {\n return (\n <div className={styles['file-preview-media-wrap']}>\n <video src={previewUrl} controls className={styles['file-preview-video']} />\n </div>\n );\n }\n\n if (kind === 'audio') {\n return (\n <div className={styles['file-preview-audio-wrap']}>\n <audio src={previewUrl} controls className={styles['file-preview-audio']} />\n </div>\n );\n }\n\n if (kind === 'unsupported') {\n return <Empty description={unsupportedMessage} />;\n }\n\n if (needsBlobPreview(kind)) {\n return (\n <div className={classNames(styles['file-preview-office'], styles['file-preview-office-wrap'])}>\n <Spin spinning={loading} wrapperClassName={styles['file-preview-office-spin']}>\n {error ? <Empty description={error} /> : <div ref={containerRef} className={styles['file-preview-office-inner']} />}\n </Spin>\n </div>\n );\n }\n\n return <Empty description={unsupportedMessage} />;\n};\n\nexport default FilePreviewContent;\n"],"names":["fetchPreviewBlob","url","res","renderExcel","container","data","jsPreviewExcel","height","_a","instance","renderWord","renderAsync","blob","renderPpt","width","init","previewer","renderText","decoder","pre","styles","FilePreviewContent","file","previewUrl","unsupportedMessage","containerRef","useRef","cleanupRef","loading","setLoading","useState","error","setError","kind","getPreviewKind","useEffect","cancelled","err","jsx","Empty","needsBlobPreview","classNames","Spin"],"mappings":"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"}
@@ -1,20 +1,21 @@
1
1
  const e = {
2
- "file-preview": "_file-preview_irbqy_1",
3
- "file-preview-header": "_file-preview-header_irbqy_139",
4
- "file-preview-info": "_file-preview-info_irbqy_148",
5
- "file-preview-icon": "_file-preview-icon_irbqy_156",
6
- "file-preview-name": "_file-preview-name_irbqy_161",
7
- "file-preview-size": "_file-preview-size_irbqy_168",
8
- "file-preview-body": "_file-preview-body_irbqy_174",
9
- "file-preview-iframe": "_file-preview-iframe_irbqy_178",
10
- "file-preview-media-wrap": "_file-preview-media-wrap_irbqy_186",
11
- "file-preview-image": "_file-preview-image_irbqy_192",
12
- "file-preview-video": "_file-preview-video_irbqy_198",
13
- "file-preview-audio-wrap": "_file-preview-audio-wrap_irbqy_204",
14
- "file-preview-audio": "_file-preview-audio_irbqy_204",
15
- "file-preview-office-wrap": "_file-preview-office-wrap_irbqy_216",
16
- "file-preview-office-inner": "_file-preview-office-inner_irbqy_221",
17
- "file-preview-text": "_file-preview-text_irbqy_228"
2
+ "file-preview": "_file-preview_m0qyk_1",
3
+ "file-preview-header": "_file-preview-header_m0qyk_139",
4
+ "file-preview-info": "_file-preview-info_m0qyk_148",
5
+ "file-preview-icon": "_file-preview-icon_m0qyk_156",
6
+ "file-preview-name": "_file-preview-name_m0qyk_161",
7
+ "file-preview-size": "_file-preview-size_m0qyk_168",
8
+ "file-preview-body": "_file-preview-body_m0qyk_174",
9
+ "file-preview-iframe": "_file-preview-iframe_m0qyk_178",
10
+ "file-preview-media-wrap": "_file-preview-media-wrap_m0qyk_186",
11
+ "file-preview-image": "_file-preview-image_m0qyk_192",
12
+ "file-preview-video": "_file-preview-video_m0qyk_198",
13
+ "file-preview-audio-wrap": "_file-preview-audio-wrap_m0qyk_204",
14
+ "file-preview-audio": "_file-preview-audio_m0qyk_204",
15
+ "file-preview-office-wrap": "_file-preview-office-wrap_m0qyk_216",
16
+ "file-preview-office-spin": "_file-preview-office-spin_m0qyk_222",
17
+ "file-preview-office-inner": "_file-preview-office-inner_m0qyk_233",
18
+ "file-preview-text": "_file-preview-text_m0qyk_240"
18
19
  };
19
20
  export {
20
21
  e as default
@@ -1 +1 @@
1
- {"version":3,"file":"style.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"style.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}
@@ -7,6 +7,8 @@ export interface FilePreviewLinkProps {
7
7
  onDownload?: (file: FileDisplayItem) => void;
8
8
  disabled?: boolean;
9
9
  showType?: boolean;
10
+ /** 文件名超长时换行展示(默认单行省略) */
11
+ nameWrap?: boolean;
10
12
  className?: string;
11
13
  }
12
14
  declare const FilePreviewLink: React.FC<FilePreviewLinkProps>;
@@ -1,61 +1,74 @@
1
- import { jsxs as n, jsx as l, Fragment as h } from "react/jsx-runtime";
2
- import { normalizeFileDisplayItem as N, getFileIcon as p, getFileTypeName as t } from "../fileDisplay.js";
3
- import y from "../FilePreviewModal/index.js";
4
- import { useState as u } from "react";
1
+ import { jsxs as a, jsx as l, Fragment as y } from "react/jsx-runtime";
2
+ import { normalizeFileDisplayItem as u, getFileIcon as o, getFileTypeName as c } from "../fileDisplay.js";
3
+ import F from "../FilePreviewModal/index.js";
4
+ import { useState as T } from "react";
5
5
  import i from "./style.module.scss.js";
6
- import f from "classnames";
7
- const D = ({
8
- file: o,
9
- url: a,
10
- downloadUrl: c,
6
+ import r from "classnames";
7
+ const P = ({
8
+ file: v,
9
+ url: s,
10
+ downloadUrl: w,
11
11
  onDownload: d,
12
- disabled: v = !1,
13
- showType: r = !0,
14
- className: m
12
+ disabled: k = !1,
13
+ showType: m = !0,
14
+ nameWrap: n = !1,
15
+ className: p
15
16
  }) => {
16
- const [k, s] = u(!1), e = N(o);
17
- return v ? /* @__PURE__ */ n(
17
+ const [N, t] = T(!1), e = u(v), f = r(
18
+ i["file-preview-link-name"],
19
+ n && i["file-preview-link-name-wrap"]
20
+ );
21
+ return k ? /* @__PURE__ */ a(
18
22
  "span",
19
23
  {
20
- className: f(i["file-preview-link-disabled"], m),
24
+ className: r(
25
+ i["file-preview-link-disabled"],
26
+ p,
27
+ n && i["file-preview-link-wrap"]
28
+ ),
21
29
  title: e.name,
22
30
  children: [
23
- /* @__PURE__ */ l("span", { className: i["file-preview-link-inner"], children: p(e.name, e.mimeType) }),
24
- /* @__PURE__ */ l("span", { className: i["file-preview-link-name"], children: e.name }),
25
- r && /* @__PURE__ */ l("span", { className: i["file-preview-link-type"], children: t(e.name, e.mimeType) })
31
+ /* @__PURE__ */ l("span", { className: i["file-preview-link-inner"], children: o(e.name, e.mimeType) }),
32
+ /* @__PURE__ */ l("span", { className: f, children: e.name }),
33
+ m && /* @__PURE__ */ l("span", { className: i["file-preview-link-type"], children: c(e.name, e.mimeType) })
26
34
  ]
27
35
  }
28
- ) : /* @__PURE__ */ n(h, { children: [
29
- /* @__PURE__ */ n(
36
+ ) : /* @__PURE__ */ a(y, { children: [
37
+ /* @__PURE__ */ a(
30
38
  "a",
31
39
  {
32
- className: f("file-preview-link", i["file-preview-link"], m),
33
- onClick: (w) => {
34
- w.preventDefault(), s(!0);
40
+ className: r(
41
+ "file-preview-link",
42
+ i["file-preview-link"],
43
+ p,
44
+ n && i["file-preview-link-wrap"]
45
+ ),
46
+ onClick: (h) => {
47
+ h.preventDefault(), t(!0);
35
48
  },
36
- href: a ?? e.url ?? "#",
49
+ href: s ?? e.url ?? "#",
37
50
  title: e.name,
38
51
  children: [
39
- /* @__PURE__ */ l("span", { className: i["file-preview-link-inner"], children: p(e.name, e.mimeType) }),
40
- /* @__PURE__ */ l("span", { className: i["file-preview-link-name"], children: e.name }),
41
- r && /* @__PURE__ */ l("span", { className: i["file-preview-link-type"], children: t(e.name, e.mimeType) })
52
+ /* @__PURE__ */ l("span", { className: i["file-preview-link-inner"], children: o(e.name, e.mimeType) }),
53
+ /* @__PURE__ */ l("span", { className: f, children: e.name }),
54
+ m && /* @__PURE__ */ l("span", { className: i["file-preview-link-type"], children: c(e.name, e.mimeType) })
42
55
  ]
43
56
  }
44
57
  ),
45
58
  /* @__PURE__ */ l(
46
- y,
59
+ F,
47
60
  {
48
- open: k,
61
+ open: N,
49
62
  file: e,
50
- url: a,
51
- downloadUrl: c,
63
+ url: s,
64
+ downloadUrl: w,
52
65
  onDownload: d,
53
- onClose: () => s(!1)
66
+ onClose: () => t(!1)
54
67
  }
55
68
  )
56
69
  ] });
57
70
  };
58
71
  export {
59
- D as default
72
+ P as default
60
73
  };
61
74
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/components/File/FilePreviewLink/index.tsx"],"sourcesContent":["import type { FileDisplayItem } from '../types';\nimport { getFileIcon, getFileTypeName, normalizeFileDisplayItem } from '../fileDisplay';\nimport FilePreviewModal from '../FilePreviewModal';\nimport React, { useState } from 'react';\nimport styles from './style.module.scss';\nimport classNames from 'classnames';\n\nexport interface FilePreviewLinkProps {\n file: FileDisplayItem;\n url?: string;\n downloadUrl?: string;\n onDownload?: (file: FileDisplayItem) => void;\n disabled?: boolean;\n showType?: boolean;\n className?: string;\n}\n\nconst FilePreviewLink: React.FC<FilePreviewLinkProps> = ({\n file,\n url,\n downloadUrl,\n onDownload,\n disabled = false,\n showType = true,\n className,\n}) => {\n const [open, setOpen] = useState(false);\n const resolvedFile = normalizeFileDisplayItem(file);\n\n if (disabled) {\n return (\n <span\n className={classNames(styles['file-preview-link-disabled'], className)}\n title={resolvedFile.name}\n >\n <span className={styles['file-preview-link-inner']}>\n {getFileIcon(resolvedFile.name, resolvedFile.mimeType)}\n </span>\n <span className={styles['file-preview-link-name']}>{resolvedFile.name}</span>\n {showType && (\n <span className={styles['file-preview-link-type']}>\n {getFileTypeName(resolvedFile.name, resolvedFile.mimeType)}\n </span>\n )}\n </span>\n );\n }\n\n return (\n <>\n <a\n className={classNames('file-preview-link', styles['file-preview-link'], className)}\n onClick={(e) => {\n e.preventDefault();\n setOpen(true);\n }}\n href={url ?? resolvedFile.url ?? '#'}\n title={resolvedFile.name}\n >\n <span className={styles['file-preview-link-inner']}>\n {getFileIcon(resolvedFile.name, resolvedFile.mimeType)}\n </span>\n <span className={styles['file-preview-link-name']}>{resolvedFile.name}</span>\n {showType && (\n <span className={styles['file-preview-link-type']}>\n {getFileTypeName(resolvedFile.name, resolvedFile.mimeType)}\n </span>\n )}\n </a>\n <FilePreviewModal\n open={open}\n file={resolvedFile}\n url={url}\n downloadUrl={downloadUrl}\n onDownload={onDownload}\n onClose={() => setOpen(false)}\n />\n </>\n );\n};\n\nexport default FilePreviewLink;\n"],"names":["FilePreviewLink","file","url","downloadUrl","onDownload","disabled","showType","className","open","setOpen","useState","resolvedFile","normalizeFileDisplayItem","jsxs","classNames","styles","jsx","getFileTypeName","Fragment","e","FilePreviewModal"],"mappings":";;;;;;AAiBA,MAAMA,IAAkD,CAAC;AAAA,EACvD,MAAAC;AAAA,EACA,KAAAC;AAAA,EACA,aAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,UAAAC,IAAW;AAAA,EACX,WAAAC;AACF,MAAM;AACJ,QAAM,CAACC,GAAMC,CAAO,IAAIC,EAAS,EAAK,GAChCC,IAAeC,EAAyBX,CAAI;AAElD,SAAII,IAEA,gBAAAQ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAWC,EAAO,4BAA4B,GAAGR,CAAS;AAAA,MACrE,OAAOI,EAAa;AAAA,MAEpB,UAAA;AAAA,QAAA,gBAAAK,EAAC,QAAA,EAAK,WAAWD,EAAO,yBAAyB,GAC9C,YAAYJ,EAAa,MAAMA,EAAa,QAAQ,EAAA,CACvD;AAAA,0BACC,QAAA,EAAK,WAAWI,EAAO,wBAAwB,GAAI,YAAa,MAAK;AAAA,QACrET,KACC,gBAAAU,EAAC,QAAA,EAAK,WAAWD,EAAO,wBAAwB,GAC7C,UAAAE,EAAgBN,EAAa,MAAMA,EAAa,QAAQ,EAAA,CAC3D;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,IAON,gBAAAE,EAAAK,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAL;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWC,EAAW,qBAAqBC,EAAO,mBAAmB,GAAGR,CAAS;AAAA,QACjF,SAAS,CAACY,MAAM;AACd,UAAAA,EAAE,eAAA,GACFV,EAAQ,EAAI;AAAA,QACd;AAAA,QACA,MAAMP,KAAOS,EAAa,OAAO;AAAA,QACjC,OAAOA,EAAa;AAAA,QAEpB,UAAA;AAAA,UAAA,gBAAAK,EAAC,QAAA,EAAK,WAAWD,EAAO,yBAAyB,GAC9C,YAAYJ,EAAa,MAAMA,EAAa,QAAQ,EAAA,CACvD;AAAA,4BACC,QAAA,EAAK,WAAWI,EAAO,wBAAwB,GAAI,YAAa,MAAK;AAAA,UACrET,KACC,gBAAAU,EAAC,QAAA,EAAK,WAAWD,EAAO,wBAAwB,GAC7C,UAAAE,EAAgBN,EAAa,MAAMA,EAAa,QAAQ,EAAA,CAC3D;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGJ,gBAAAK;AAAA,MAACI;AAAA,MAAA;AAAA,QACC,MAAAZ;AAAA,QACA,MAAMG;AAAA,QACN,KAAAT;AAAA,QACA,aAAAC;AAAA,QACA,YAAAC;AAAA,QACA,SAAS,MAAMK,EAAQ,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EAC9B,GACF;AAEJ;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/File/FilePreviewLink/index.tsx"],"sourcesContent":["import type { FileDisplayItem } from '../types';\nimport { getFileIcon, getFileTypeName, normalizeFileDisplayItem } from '../fileDisplay';\nimport FilePreviewModal from '../FilePreviewModal';\nimport React, { useState } from 'react';\nimport styles from './style.module.scss';\nimport classNames from 'classnames';\n\nexport interface FilePreviewLinkProps {\n file: FileDisplayItem;\n url?: string;\n downloadUrl?: string;\n onDownload?: (file: FileDisplayItem) => void;\n disabled?: boolean;\n showType?: boolean;\n /** 文件名超长时换行展示(默认单行省略) */\n nameWrap?: boolean;\n className?: string;\n}\n\nconst FilePreviewLink: React.FC<FilePreviewLinkProps> = ({\n file,\n url,\n downloadUrl,\n onDownload,\n disabled = false,\n showType = true,\n nameWrap = false,\n className,\n}) => {\n const [open, setOpen] = useState(false);\n const resolvedFile = normalizeFileDisplayItem(file);\n\n const nameClassName = classNames(\n styles['file-preview-link-name'],\n nameWrap && styles['file-preview-link-name-wrap'],\n );\n\n if (disabled) {\n return (\n <span\n className={classNames(\n styles['file-preview-link-disabled'],\n className,\n nameWrap && styles['file-preview-link-wrap'],\n )}\n title={resolvedFile.name}\n >\n <span className={styles['file-preview-link-inner']}>\n {getFileIcon(resolvedFile.name, resolvedFile.mimeType)}\n </span>\n <span className={nameClassName}>{resolvedFile.name}</span>\n {showType && (\n <span className={styles['file-preview-link-type']}>\n {getFileTypeName(resolvedFile.name, resolvedFile.mimeType)}\n </span>\n )}\n </span>\n );\n }\n\n return (\n <>\n <a\n className={classNames(\n 'file-preview-link',\n styles['file-preview-link'],\n className,\n nameWrap && styles['file-preview-link-wrap'],\n )}\n onClick={(e) => {\n e.preventDefault();\n setOpen(true);\n }}\n href={url ?? resolvedFile.url ?? '#'}\n title={resolvedFile.name}\n >\n <span className={styles['file-preview-link-inner']}>\n {getFileIcon(resolvedFile.name, resolvedFile.mimeType)}\n </span>\n <span className={nameClassName}>{resolvedFile.name}</span>\n {showType && (\n <span className={styles['file-preview-link-type']}>\n {getFileTypeName(resolvedFile.name, resolvedFile.mimeType)}\n </span>\n )}\n </a>\n <FilePreviewModal\n open={open}\n file={resolvedFile}\n url={url}\n downloadUrl={downloadUrl}\n onDownload={onDownload}\n onClose={() => setOpen(false)}\n />\n </>\n );\n};\n\nexport default FilePreviewLink;\n"],"names":["FilePreviewLink","file","url","downloadUrl","onDownload","disabled","showType","nameWrap","className","open","setOpen","useState","resolvedFile","normalizeFileDisplayItem","nameClassName","classNames","styles","jsxs","jsx","getFileTypeName","Fragment","e","FilePreviewModal"],"mappings":";;;;;;AAmBA,MAAMA,IAAkD,CAAC;AAAA,EACvD,MAAAC;AAAA,EACA,KAAAC;AAAA,EACA,aAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,UAAAC,IAAW;AAAA,EACX,UAAAC,IAAW;AAAA,EACX,WAAAC;AACF,MAAM;AACJ,QAAM,CAACC,GAAMC,CAAO,IAAIC,EAAS,EAAK,GAChCC,IAAeC,EAAyBZ,CAAI,GAE5Ca,IAAgBC;AAAA,IACpBC,EAAO,wBAAwB;AAAA,IAC/BT,KAAYS,EAAO,6BAA6B;AAAA,EAAA;AAGlD,SAAIX,IAEA,gBAAAY;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWF;AAAA,QACTC,EAAO,4BAA4B;AAAA,QACnCR;AAAA,QACAD,KAAYS,EAAO,wBAAwB;AAAA,MAAA;AAAA,MAE7C,OAAOJ,EAAa;AAAA,MAEpB,UAAA;AAAA,QAAA,gBAAAM,EAAC,QAAA,EAAK,WAAWF,EAAO,yBAAyB,GAC9C,YAAYJ,EAAa,MAAMA,EAAa,QAAQ,EAAA,CACvD;AAAA,QACA,gBAAAM,EAAC,QAAA,EAAK,WAAWJ,GAAgB,YAAa,MAAK;AAAA,QAClDR,KACC,gBAAAY,EAAC,QAAA,EAAK,WAAWF,EAAO,wBAAwB,GAC7C,UAAAG,EAAgBP,EAAa,MAAMA,EAAa,QAAQ,EAAA,CAC3D;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,IAON,gBAAAK,EAAAG,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAH;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWF;AAAA,UACT;AAAA,UACAC,EAAO,mBAAmB;AAAA,UAC1BR;AAAA,UACAD,KAAYS,EAAO,wBAAwB;AAAA,QAAA;AAAA,QAE7C,SAAS,CAACK,MAAM;AACd,UAAAA,EAAE,eAAA,GACFX,EAAQ,EAAI;AAAA,QACd;AAAA,QACA,MAAMR,KAAOU,EAAa,OAAO;AAAA,QACjC,OAAOA,EAAa;AAAA,QAEpB,UAAA;AAAA,UAAA,gBAAAM,EAAC,QAAA,EAAK,WAAWF,EAAO,yBAAyB,GAC9C,YAAYJ,EAAa,MAAMA,EAAa,QAAQ,EAAA,CACvD;AAAA,UACA,gBAAAM,EAAC,QAAA,EAAK,WAAWJ,GAAgB,YAAa,MAAK;AAAA,UAClDR,KACC,gBAAAY,EAAC,QAAA,EAAK,WAAWF,EAAO,wBAAwB,GAC7C,UAAAG,EAAgBP,EAAa,MAAMA,EAAa,QAAQ,EAAA,CAC3D;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGJ,gBAAAM;AAAA,MAACI;AAAA,MAAA;AAAA,QACC,MAAAb;AAAA,QACA,MAAMG;AAAA,QACN,KAAAV;AAAA,QACA,aAAAC;AAAA,QACA,YAAAC;AAAA,QACA,SAAS,MAAMM,EAAQ,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EAC9B,GACF;AAEJ;"}
@@ -1,9 +1,11 @@
1
1
  const e = {
2
- "file-preview-link": "_file-preview-link_1rk52_1",
3
- "file-preview-link-disabled": "_file-preview-link-disabled_1rk52_12",
4
- "file-preview-link-inner": "_file-preview-link-inner_1rk52_21",
5
- "file-preview-link-name": "_file-preview-link-name_1rk52_25",
6
- "file-preview-link-type": "_file-preview-link-type_1rk52_31"
2
+ "file-preview-link": "_file-preview-link_1q16r_1",
3
+ "file-preview-link-wrap": "_file-preview-link-wrap_1q16r_12",
4
+ "file-preview-link-disabled": "_file-preview-link-disabled_1q16r_17",
5
+ "file-preview-link-inner": "_file-preview-link-inner_1q16r_26",
6
+ "file-preview-link-name": "_file-preview-link-name_1q16r_30",
7
+ "file-preview-link-name-wrap": "_file-preview-link-name-wrap_1q16r_36",
8
+ "file-preview-link-type": "_file-preview-link-type_1q16r_44"
7
9
  };
8
10
  export {
9
11
  e as default
@@ -1 +1 @@
1
- {"version":3,"file":"style.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
1
+ {"version":3,"file":"style.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
@@ -0,0 +1,8 @@
1
+ import { default as React } from 'react';
2
+ export interface LlmFormattedTextProps {
3
+ text?: string;
4
+ loading?: boolean;
5
+ className?: string;
6
+ }
7
+ declare const LlmFormattedText: React.FC<LlmFormattedTextProps>;
8
+ export default LlmFormattedText;
@@ -0,0 +1,42 @@
1
+ import { jsxs as l, jsx as e } from "react/jsx-runtime";
2
+ import r from "classnames";
3
+ import { parseLlmText as o } from "../parseLlmText.js";
4
+ import t from "./style.module.scss.js";
5
+ const p = {
6
+ causes: "◆",
7
+ suggestions: "✓",
8
+ summary: "●"
9
+ }, y = ({
10
+ text: m = "",
11
+ loading: d,
12
+ className: i
13
+ }) => {
14
+ const s = o(m);
15
+ return d || s.loading ? /* @__PURE__ */ l("div", { className: r("llm-formatted-text", t["llm-formatted-text"], t["is-loading"], i), children: [
16
+ /* @__PURE__ */ e("span", { className: t["ft-spinner"], "aria-hidden": !0 }),
17
+ /* @__PURE__ */ e("span", { children: m || "正在生成..." })
18
+ ] }) : s.summary || s.sections.length > 0 ? /* @__PURE__ */ l("div", { className: r("llm-formatted-text", t["llm-formatted-text"], i), children: [
19
+ s.summary ? /* @__PURE__ */ e("p", { className: t["ft-summary"], children: s.summary }) : null,
20
+ s.sections.map((a) => /* @__PURE__ */ l(
21
+ "section",
22
+ {
23
+ className: r(t["ft-section"], t[`ft-${a.type}`]),
24
+ children: [
25
+ /* @__PURE__ */ l("h4", { className: t["ft-section-title"], children: [
26
+ /* @__PURE__ */ e("span", { className: t["ft-section-icon"], "aria-hidden": !0, children: p[a.type] || "•" }),
27
+ a.title
28
+ ] }),
29
+ a.items.length > 1 ? /* @__PURE__ */ e("ul", { className: t["ft-list"], children: a.items.map((c, n) => /* @__PURE__ */ l("li", { children: [
30
+ /* @__PURE__ */ e("span", { className: t["ft-num"], children: n + 1 }),
31
+ /* @__PURE__ */ e("span", { className: t["ft-item-text"], children: c })
32
+ ] }, n)) }) : /* @__PURE__ */ e("p", { className: t["ft-paragraph"], children: a.items[0] })
33
+ ]
34
+ },
35
+ `${a.type}-${a.title}`
36
+ ))
37
+ ] }) : /* @__PURE__ */ e("div", { className: r("llm-formatted-text", t["llm-formatted-text"], i), children: /* @__PURE__ */ e("p", { className: t["ft-paragraph"], children: m }) });
38
+ };
39
+ export {
40
+ y as default
41
+ };
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/LlmFormattedText/LlmFormattedText/index.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport React from 'react';\nimport { parseLlmText } from '../parseLlmText';\nimport styles from './style.module.scss';\n\nconst SECTION_ICONS: Record<string, string> = {\n causes: '◆',\n suggestions: '✓',\n summary: '●',\n};\n\nexport interface LlmFormattedTextProps {\n text?: string;\n loading?: boolean;\n className?: string;\n}\n\nconst LlmFormattedText: React.FC<LlmFormattedTextProps> = ({\n text = '',\n loading: loadingProp,\n className,\n}) => {\n const parsed = parseLlmText(text);\n const loading = loadingProp || parsed.loading;\n\n if (loading) {\n return (\n <div className={classNames('llm-formatted-text', styles['llm-formatted-text'], styles['is-loading'], className)}>\n <span className={styles['ft-spinner']} aria-hidden />\n <span>{text || '正在生成...'}</span>\n </div>\n );\n }\n\n const hasStructure = parsed.summary || parsed.sections.length > 0;\n if (!hasStructure) {\n return (\n <div className={classNames('llm-formatted-text', styles['llm-formatted-text'], className)}>\n <p className={styles['ft-paragraph']}>{text}</p>\n </div>\n );\n }\n\n return (\n <div className={classNames('llm-formatted-text', styles['llm-formatted-text'], className)}>\n {parsed.summary ? <p className={styles['ft-summary']}>{parsed.summary}</p> : null}\n {parsed.sections.map((sec: { type: string; title: string; items: string[] }) => (\n <section\n key={`${sec.type}-${sec.title}`}\n className={classNames(styles['ft-section'], styles[`ft-${sec.type}`])}\n >\n <h4 className={styles['ft-section-title']}>\n <span className={styles['ft-section-icon']} aria-hidden>\n {SECTION_ICONS[sec.type] || '•'}\n </span>\n {sec.title}\n </h4>\n {sec.items.length > 1 ? (\n <ul className={styles['ft-list']}>\n {sec.items.map((item: string, i: number) => (\n <li key={i}>\n <span className={styles['ft-num']}>{i + 1}</span>\n <span className={styles['ft-item-text']}>{item}</span>\n </li>\n ))}\n </ul>\n ) : (\n <p className={styles['ft-paragraph']}>{sec.items[0]}</p>\n )}\n </section>\n ))}\n </div>\n );\n};\n\nexport default LlmFormattedText;\n"],"names":["SECTION_ICONS","LlmFormattedText","text","loadingProp","className","parsed","parseLlmText","jsxs","classNames","styles","jsx","sec","item","i"],"mappings":";;;;AAKA,MAAMA,IAAwC;AAAA,EAC5C,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,SAAS;AACX,GAQMC,IAAoD,CAAC;AAAA,EACzD,MAAAC,IAAO;AAAA,EACP,SAASC;AAAA,EACT,WAAAC;AACF,MAAM;AACJ,QAAMC,IAASC,EAAaJ,CAAI;AAGhC,SAFgBC,KAAeE,EAAO,UAIlC,gBAAAE,EAAC,OAAA,EAAI,WAAWC,EAAW,sBAAsBC,EAAO,oBAAoB,GAAGA,EAAO,YAAY,GAAGL,CAAS,GAC5G,UAAA;AAAA,IAAA,gBAAAM,EAAC,UAAK,WAAWD,EAAO,YAAY,GAAG,eAAW,IAAC;AAAA,IACnD,gBAAAC,EAAC,QAAA,EAAM,UAAAR,KAAQ,UAAA,CAAU;AAAA,EAAA,GAC3B,IAIiBG,EAAO,WAAWA,EAAO,SAAS,SAAS,IAU9D,gBAAAE,EAAC,SAAI,WAAWC,EAAW,sBAAsBC,EAAO,oBAAoB,GAAGL,CAAS,GACrF,UAAA;AAAA,IAAAC,EAAO,4BAAW,KAAA,EAAE,WAAWI,EAAO,YAAY,GAAI,UAAAJ,EAAO,QAAA,CAAQ,IAAO;AAAA,IAC5EA,EAAO,SAAS,IAAI,CAACM,MACpB,gBAAAJ;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAWC,EAAWC,EAAO,YAAY,GAAGA,EAAO,MAAME,EAAI,IAAI,EAAE,CAAC;AAAA,QAEpE,UAAA;AAAA,UAAA,gBAAAJ,EAAC,MAAA,EAAG,WAAWE,EAAO,kBAAkB,GACtC,UAAA;AAAA,YAAA,gBAAAC,EAAC,QAAA,EAAK,WAAWD,EAAO,iBAAiB,GAAG,eAAW,IACpD,UAAAT,EAAcW,EAAI,IAAI,KAAK,IAAA,CAC9B;AAAA,YACCA,EAAI;AAAA,UAAA,GACP;AAAA,UACCA,EAAI,MAAM,SAAS,IAClB,gBAAAD,EAAC,QAAG,WAAWD,EAAO,SAAS,GAC5B,YAAI,MAAM,IAAI,CAACG,GAAcC,wBAC3B,MAAA,EACC,UAAA;AAAA,YAAA,gBAAAH,EAAC,UAAK,WAAWD,EAAO,QAAQ,GAAI,cAAI,GAAE;AAAA,8BACzC,QAAA,EAAK,WAAWA,EAAO,cAAc,GAAI,UAAAG,EAAA,CAAK;AAAA,UAAA,EAAA,GAFxCC,CAGT,CACD,EAAA,CACH,IAEA,gBAAAH,EAAC,KAAA,EAAE,WAAWD,EAAO,cAAc,GAAI,UAAAE,EAAI,MAAM,CAAC,EAAA,CAAE;AAAA,QAAA;AAAA,MAAA;AAAA,MAnBjD,GAAGA,EAAI,IAAI,IAAIA,EAAI,KAAK;AAAA,IAAA,CAsBhC;AAAA,EAAA,GACH,sBAlCG,OAAA,EAAI,WAAWH,EAAW,sBAAsBC,EAAO,oBAAoB,GAAGL,CAAS,GACtF,4BAAC,KAAA,EAAE,WAAWK,EAAO,cAAc,GAAI,aAAK,GAC9C;AAkCN;"}
@@ -0,0 +1,17 @@
1
+ const t = {
2
+ "llm-formatted-text": "_llm-formatted-text_1mo0r_1",
3
+ "is-loading": "_is-loading_1mo0r_7",
4
+ "ft-spinner": "_ft-spinner_1mo0r_14",
5
+ "llm-ft-spin": "_llm-ft-spin_1mo0r_1",
6
+ "ft-summary": "_ft-summary_1mo0r_28",
7
+ "ft-section": "_ft-section_1mo0r_33",
8
+ "ft-section-title": "_ft-section-title_1mo0r_37",
9
+ "ft-section-icon": "_ft-section-icon_1mo0r_46",
10
+ "ft-list": "_ft-list_1mo0r_50",
11
+ "ft-num": "_ft-num_1mo0r_62",
12
+ "ft-paragraph": "_ft-paragraph_1mo0r_69"
13
+ };
14
+ export {
15
+ t as default
16
+ };
17
+ //# sourceMappingURL=style.module.scss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
@@ -0,0 +1,4 @@
1
+ export { default as LlmFormattedText } from './LlmFormattedText';
2
+ export type { LlmFormattedTextProps } from './LlmFormattedText';
3
+ export { parseLlmText, formatLlmTextToHtml } from './parseLlmText';
4
+ export type { ParsedLlmText, LlmTextSection } from './parseLlmText';
@@ -0,0 +1,14 @@
1
+ /** 将 LLM 纯文本解析为带层级的内容块 */
2
+ export type LlmTextSection = {
3
+ type: string;
4
+ title: string;
5
+ items: string[];
6
+ };
7
+ export type ParsedLlmText = {
8
+ summary: string;
9
+ sections: LlmTextSection[];
10
+ loading?: boolean;
11
+ };
12
+ export declare function parseLlmText(text: string): ParsedLlmText;
13
+ /** 供静态 HTML 报告使用的排版 HTML */
14
+ export declare function formatLlmTextToHtml(text: string): string;
@@ -0,0 +1,77 @@
1
+ const g = [
2
+ { type: "causes", titles: ["可能原因", "原因分析", "主要原因", "异常原因"] },
3
+ { type: "suggestions", titles: ["建议", "改进建议", "处置建议", "应对措施", "整改建议"] },
4
+ { type: "summary", titles: ["异常说明", "情况说明", "分析结论", "结论"] }
5
+ ], d = new RegExp("(?:^|\\s)(?:[((]?\\d+[))]|[①②③④⑤⑥⑦⑧⑨⑩⑪⑫]|(?<!\\d)\\d+[、..])(?=\\s*[^\\d])", "g");
6
+ function h(l) {
7
+ return String(l || "").replace(/\r\n/g, `
8
+ `).replace(/[ \t]+\n/g, `
9
+ `).replace(/\n{3,}/g, `
10
+
11
+ `).trim();
12
+ }
13
+ function x(l) {
14
+ const t = l.trim();
15
+ if (!t) return [];
16
+ const i = t.split(d).map((n) => n.trim()).filter(Boolean);
17
+ if (i.length > 1) return i;
18
+ const e = t.split(/\n+/).map((n) => n.replace(/^[((]?\d+[))]\s*|^[①②③④⑤⑥⑦⑧⑨⑩]\s*|\d+[、..]\s*/, "").trim()).filter(Boolean);
19
+ return e.length > 1 ? e : [t];
20
+ }
21
+ function y(l) {
22
+ const t = h(l);
23
+ if (!t) return { summary: "", sections: [] };
24
+ if (/^(正在|思考中|分析中|加载)/.test(t) && t.length < 40)
25
+ return { summary: t, sections: [], loading: !0 };
26
+ const i = [];
27
+ let e = "";
28
+ const n = [];
29
+ for (const s of g)
30
+ for (const r of s.titles) {
31
+ const p = new RegExp(`(${r})[::\\s]*`, "g");
32
+ let c;
33
+ for (; (c = p.exec(t)) !== null; )
34
+ n.push({ type: s.type, title: r, index: c.index, len: c[0].length });
35
+ }
36
+ if (n.sort((s, r) => s.index - r.index), n.length === 0)
37
+ return { summary: t, sections: [] };
38
+ const a = n[0];
39
+ a.index > 0 && (e = t.slice(0, a.index).replace(/[::\s]+$/, "").trim());
40
+ for (let s = 0; s < n.length; s += 1) {
41
+ const r = n[s], p = r.index + r.len, c = n[s + 1], u = c ? c.index : t.length, m = t.slice(p, u).trim(), f = x(m);
42
+ i.push({
43
+ type: r.type,
44
+ title: r.title,
45
+ items: f.length ? f : [m]
46
+ });
47
+ }
48
+ if (!e && i.length) {
49
+ const s = a.index;
50
+ s > 80 && (e = t.slice(0, s).trim());
51
+ }
52
+ return !e && i.length === 0 && (e = t), { summary: e, sections: i };
53
+ }
54
+ function o(l) {
55
+ return l.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
56
+ }
57
+ function $(l) {
58
+ const t = y(l);
59
+ if (t.loading)
60
+ return `<p class="ft-loading">${o(t.summary)}</p>`;
61
+ const i = [];
62
+ t.summary && i.push(`<p class="ft-summary">${o(t.summary)}</p>`);
63
+ for (const e of t.sections) {
64
+ const n = `ft-section ft-${e.type}`, a = e.items.length > 1 ? `<ul class="ft-list">${e.items.map(
65
+ (s, r) => `<li><span class="ft-num">${r + 1}</span><span class="ft-item-text">${o(s)}</span></li>`
66
+ ).join("")}</ul>` : `<p class="ft-paragraph">${o(e.items[0] || "")}</p>`;
67
+ i.push(
68
+ `<section class="${n}"><h4 class="ft-section-title">${o(e.title)}</h4>${a}</section>`
69
+ );
70
+ }
71
+ return i.length ? `<div class="formatted-text">${i.join("")}</div>` : `<p class="ft-paragraph">${o(l || "")}</p>`;
72
+ }
73
+ export {
74
+ $ as formatLlmTextToHtml,
75
+ y as parseLlmText
76
+ };
77
+ //# sourceMappingURL=parseLlmText.js.map