@eternalheart/react-file-preview 1.3.14 → 1.5.0
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/README.md +437 -60
- package/README.zh-CN.md +437 -60
- package/lib/FilePreviewContent.d.ts +4 -17
- package/lib/FilePreviewContent.d.ts.map +1 -1
- package/lib/FilePreviewEmbed.d.ts +2 -0
- package/lib/FilePreviewEmbed.d.ts.map +1 -1
- package/lib/FilePreviewModal.d.ts +2 -0
- package/lib/FilePreviewModal.d.ts.map +1 -1
- package/lib/chunks/RendererError-D5i8eSpN.mjs +15 -0
- package/lib/chunks/RendererError-D5i8eSpN.mjs.map +1 -0
- package/lib/chunks/index-2sX2d4iv.mjs +291 -0
- package/lib/chunks/index-2sX2d4iv.mjs.map +1 -0
- package/lib/chunks/index-Bdj8_B80.mjs +120 -0
- package/lib/chunks/index-Bdj8_B80.mjs.map +1 -0
- package/lib/chunks/index-CCcZzLUM.mjs +107 -0
- package/lib/chunks/index-CCcZzLUM.mjs.map +1 -0
- package/lib/chunks/{index-BfzV7KIz.mjs → index-CKdQL1Bk.mjs} +130 -128
- package/lib/chunks/{index-BfzV7KIz.mjs.map → index-CKdQL1Bk.mjs.map} +1 -1
- package/lib/chunks/index-CQYrhe7Z.mjs +275 -0
- package/lib/chunks/index-CQYrhe7Z.mjs.map +1 -0
- package/lib/chunks/{index-DEzF8C7L.mjs → index-CRZqNMQ7.mjs} +43 -41
- package/lib/chunks/index-CRZqNMQ7.mjs.map +1 -0
- package/lib/chunks/{index-D_cBflBv.mjs → index-CTghYlSh.mjs} +1299 -1297
- package/lib/chunks/{index-D_cBflBv.mjs.map → index-CTghYlSh.mjs.map} +1 -1
- package/lib/chunks/index-CuTz7dbd.mjs +313 -0
- package/lib/chunks/index-CuTz7dbd.mjs.map +1 -0
- package/lib/chunks/index-CuWzRQZw.mjs +116 -0
- package/lib/chunks/index-CuWzRQZw.mjs.map +1 -0
- package/lib/chunks/index-Cz23v-TW.mjs +2409 -0
- package/lib/chunks/index-Cz23v-TW.mjs.map +1 -0
- package/lib/chunks/{index-Br8WHz8e.mjs → index-D-Is8qvU.mjs} +22 -20
- package/lib/chunks/index-D-Is8qvU.mjs.map +1 -0
- package/lib/chunks/index-Da3FN2-3.mjs +359 -0
- package/lib/chunks/index-Da3FN2-3.mjs.map +1 -0
- package/lib/chunks/index-Dc6q1OKl.mjs +78 -0
- package/lib/chunks/index-Dc6q1OKl.mjs.map +1 -0
- package/lib/chunks/{index-d8Bt4gIX.mjs → index-DoGKcq9y.mjs} +196 -194
- package/lib/chunks/index-DoGKcq9y.mjs.map +1 -0
- package/lib/chunks/{index-DCGk-moA.mjs → index-DzCLf1Db.mjs} +47 -45
- package/lib/chunks/index-DzCLf1Db.mjs.map +1 -0
- package/lib/chunks/index-FomaQSaL.mjs +329 -0
- package/lib/chunks/index-FomaQSaL.mjs.map +1 -0
- package/lib/chunks/{index-BTLV1YqJ.mjs → index-OXjOFggq.mjs} +864 -862
- package/lib/chunks/{index-BTLV1YqJ.mjs.map → index-OXjOFggq.mjs.map} +1 -1
- package/lib/chunks/index-WLepq2g2.mjs +200 -0
- package/lib/chunks/index-WLepq2g2.mjs.map +1 -0
- package/lib/chunks/{index-BG3Idu38.mjs → index-_B5marES.mjs} +27 -25
- package/lib/chunks/index-_B5marES.mjs.map +1 -0
- package/lib/chunks/useShikiHighlight-Bbs8Fbqs.mjs +36 -0
- package/lib/chunks/useShikiHighlight-Bbs8Fbqs.mjs.map +1 -0
- package/lib/components/preview/FilePreviewRenderer.d.ts +18 -0
- package/lib/components/preview/FilePreviewRenderer.d.ts.map +1 -0
- package/lib/components/preview/FilePreviewToolbar.d.ts +20 -0
- package/lib/components/preview/FilePreviewToolbar.d.ts.map +1 -0
- package/lib/components/preview/NavArrows.d.ts +18 -0
- package/lib/components/preview/NavArrows.d.ts.map +1 -0
- package/lib/components/preview/RendererError.d.ts +15 -0
- package/lib/components/preview/RendererError.d.ts.map +1 -0
- package/lib/components/preview/RendererErrorBoundary.d.ts +23 -0
- package/lib/components/preview/RendererErrorBoundary.d.ts.map +1 -0
- package/lib/components/preview/ToolbarButton.d.ts +16 -0
- package/lib/components/preview/ToolbarButton.d.ts.map +1 -0
- package/lib/components/preview/index.d.ts +7 -0
- package/lib/components/preview/index.d.ts.map +1 -0
- package/lib/hooks/index.d.ts +3 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/useKeyboardNavigation.d.ts +15 -0
- package/lib/hooks/useKeyboardNavigation.d.ts.map +1 -0
- package/lib/hooks/useShikiHighlight.d.ts +3 -1
- package/lib/hooks/useShikiHighlight.d.ts.map +1 -1
- package/lib/hooks/useThemeMode.d.ts +7 -0
- package/lib/hooks/useThemeMode.d.ts.map +1 -0
- package/lib/index.cjs +27 -25
- package/lib/index.cjs.map +1 -1
- package/lib/index.css +1 -1
- package/lib/index.mjs +1 -1
- package/lib/renderers/Audio/index.d.ts +2 -1
- package/lib/renderers/Audio/index.d.ts.map +1 -1
- package/lib/renderers/Csv/index.d.ts +2 -1
- package/lib/renderers/Csv/index.d.ts.map +1 -1
- package/lib/renderers/Docx/index.d.ts +2 -1
- package/lib/renderers/Docx/index.d.ts.map +1 -1
- package/lib/renderers/Epub/index.d.ts +2 -3
- package/lib/renderers/Epub/index.d.ts.map +1 -1
- package/lib/renderers/Font/index.d.ts +2 -1
- package/lib/renderers/Font/index.d.ts.map +1 -1
- package/lib/renderers/Image/index.d.ts +6 -7
- package/lib/renderers/Image/index.d.ts.map +1 -1
- package/lib/renderers/Json/index.d.ts +2 -1
- package/lib/renderers/Json/index.d.ts.map +1 -1
- package/lib/renderers/Markdown/index.d.ts +2 -2
- package/lib/renderers/Markdown/index.d.ts.map +1 -1
- package/lib/renderers/Mobi/index.d.ts +2 -3
- package/lib/renderers/Mobi/index.d.ts.map +1 -1
- package/lib/renderers/Msg/index.d.ts +2 -1
- package/lib/renderers/Msg/index.d.ts.map +1 -1
- package/lib/renderers/Pdf/index.d.ts +4 -6
- package/lib/renderers/Pdf/index.d.ts.map +1 -1
- package/lib/renderers/Pptx/index.d.ts +2 -1
- package/lib/renderers/Pptx/index.d.ts.map +1 -1
- package/lib/renderers/Subtitle/index.d.ts +2 -1
- package/lib/renderers/Subtitle/index.d.ts.map +1 -1
- package/lib/renderers/Text/index.d.ts +2 -3
- package/lib/renderers/Text/index.d.ts.map +1 -1
- package/lib/renderers/Video/index.d.ts +2 -1
- package/lib/renderers/Video/index.d.ts.map +1 -1
- package/lib/renderers/Xlsx/index.d.ts +2 -1
- package/lib/renderers/Xlsx/index.d.ts.map +1 -1
- package/lib/renderers/Xml/index.d.ts +2 -1
- package/lib/renderers/Xml/index.d.ts.map +1 -1
- package/lib/renderers/Zip/index.d.ts +7 -2
- package/lib/renderers/Zip/index.d.ts.map +1 -1
- package/lib/renderers/base.types.d.ts +38 -0
- package/lib/renderers/base.types.d.ts.map +1 -0
- package/lib/renderers/registry.d.ts +36 -0
- package/lib/renderers/registry.d.ts.map +1 -0
- package/lib/renderers/toolbar.types.d.ts +3 -0
- package/lib/renderers/toolbar.types.d.ts.map +1 -1
- package/lib/toolbar/renderItems.d.ts +8 -0
- package/lib/toolbar/renderItems.d.ts.map +1 -0
- package/package.json +3 -3
- package/lib/chunks/RendererError-BH6fzLrN.mjs +0 -15
- package/lib/chunks/RendererError-BH6fzLrN.mjs.map +0 -1
- package/lib/chunks/index--lXiT1Y_.mjs +0 -2325
- package/lib/chunks/index--lXiT1Y_.mjs.map +0 -1
- package/lib/chunks/index-B05UpMZC.mjs +0 -270
- package/lib/chunks/index-B05UpMZC.mjs.map +0 -1
- package/lib/chunks/index-BG3Idu38.mjs.map +0 -1
- package/lib/chunks/index-B_7NPlPG.mjs +0 -105
- package/lib/chunks/index-B_7NPlPG.mjs.map +0 -1
- package/lib/chunks/index-BaU-yih3.mjs +0 -194
- package/lib/chunks/index-BaU-yih3.mjs.map +0 -1
- package/lib/chunks/index-Br8WHz8e.mjs.map +0 -1
- package/lib/chunks/index-CaobN7Im.mjs +0 -175
- package/lib/chunks/index-CaobN7Im.mjs.map +0 -1
- package/lib/chunks/index-Ch7DqyC4.mjs +0 -55
- package/lib/chunks/index-Ch7DqyC4.mjs.map +0 -1
- package/lib/chunks/index-DCGk-moA.mjs.map +0 -1
- package/lib/chunks/index-DEzF8C7L.mjs.map +0 -1
- package/lib/chunks/index-DKwN-YU-.mjs +0 -54
- package/lib/chunks/index-DKwN-YU-.mjs.map +0 -1
- package/lib/chunks/index-DMmb2rBE.mjs +0 -357
- package/lib/chunks/index-DMmb2rBE.mjs.map +0 -1
- package/lib/chunks/index-Dq-90KbM.mjs +0 -240
- package/lib/chunks/index-Dq-90KbM.mjs.map +0 -1
- package/lib/chunks/index-Go2oJfny.mjs +0 -114
- package/lib/chunks/index-Go2oJfny.mjs.map +0 -1
- package/lib/chunks/index-d8Bt4gIX.mjs.map +0 -1
- package/lib/chunks/index-jHf5E4be.mjs +0 -161
- package/lib/chunks/index-jHf5E4be.mjs.map +0 -1
- package/lib/chunks/useShikiHighlight-DoY3TBPT.mjs +0 -23
- package/lib/chunks/useShikiHighlight-DoY3TBPT.mjs.map +0 -1
- package/lib/renderers/Epub/toolbar.d.ts +0 -13
- package/lib/renderers/Epub/toolbar.d.ts.map +0 -1
- package/lib/renderers/Image/toolbar.d.ts +0 -15
- package/lib/renderers/Image/toolbar.d.ts.map +0 -1
- package/lib/renderers/Markdown/toolbar.d.ts +0 -9
- package/lib/renderers/Markdown/toolbar.d.ts.map +0 -1
- package/lib/renderers/Mobi/toolbar.d.ts +0 -13
- package/lib/renderers/Mobi/toolbar.d.ts.map +0 -1
- package/lib/renderers/Pdf/toolbar.d.ts +0 -11
- package/lib/renderers/Pdf/toolbar.d.ts.map +0 -1
- package/lib/renderers/Text/toolbar.d.ts +0 -12
- package/lib/renderers/Text/toolbar.d.ts.map +0 -1
- package/lib/renderers/Zip/toolbar.d.ts +0 -13
- package/lib/renderers/Zip/toolbar.d.ts.map +0 -1
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { jsxs as A, jsx as y } from "react/jsx-runtime";
|
|
2
|
-
import { useState as S, useRef as w, useCallback as u, useEffect as d } from "react";
|
|
3
|
-
import { u as F } from "./index--lXiT1Y_.mjs";
|
|
4
|
-
import { R as O } from "./RendererError-BH6fzLrN.mjs";
|
|
5
|
-
import * as _ from "pdfjs-dist/build/pdf.mjs";
|
|
6
|
-
const Q = ({
|
|
7
|
-
url: m,
|
|
8
|
-
zoom: T,
|
|
9
|
-
currentPage: k,
|
|
10
|
-
onPageChange: g,
|
|
11
|
-
onTotalPagesChange: M,
|
|
12
|
-
onPageWidthChange: E
|
|
13
|
-
}) => {
|
|
14
|
-
const N = F(), [l, j] = S(0), [h, D] = S(null), [H, R] = S(!0), i = w(null), c = w(null), s = w(/* @__PURE__ */ new Map()), f = w(null), I = u(async (r, t) => {
|
|
15
|
-
if (!c.current) return;
|
|
16
|
-
const e = s.current.get(r);
|
|
17
|
-
if (!(!e || e.rendering)) {
|
|
18
|
-
e.rendering = !0;
|
|
19
|
-
try {
|
|
20
|
-
const n = await c.current.getPage(r), a = n.getViewport({ scale: t }), o = document.createElement("canvas");
|
|
21
|
-
o.width = a.width, o.height = a.height, o.style.maxWidth = "100%", o.style.height = "auto", o.style.borderRadius = "0", o.style.display = "block";
|
|
22
|
-
const v = o.getContext("2d");
|
|
23
|
-
if (!v) return;
|
|
24
|
-
const b = n.render({ canvasContext: v, viewport: a });
|
|
25
|
-
if (e.renderTask = b, await b.promise, r === 1 && E) {
|
|
26
|
-
const L = n.getViewport({ scale: 1 });
|
|
27
|
-
E(L.width);
|
|
28
|
-
}
|
|
29
|
-
e.element.innerHTML = "", e.element.appendChild(o);
|
|
30
|
-
const p = document.createElement("div");
|
|
31
|
-
p.textContent = String(r), p.className = "rfp-absolute rfp-top-2 rfp-right-2 rfp-bg-surface-nav-hover rfp-backdrop-blur-sm rfp-text-fg-primary rfp-text-xs rfp-px-3 rfp-py-1 rfp-rounded-full", e.element.appendChild(p), e.rendered = !0;
|
|
32
|
-
} catch (n) {
|
|
33
|
-
(n == null ? void 0 : n.name) !== "RenderingCancelledException" && console.error(`渲染页面 ${r} 失败:`, n);
|
|
34
|
-
} finally {
|
|
35
|
-
e.rendering = !1, e.renderTask = null;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}, [E]), x = u((r) => {
|
|
39
|
-
const t = s.current.get(r);
|
|
40
|
-
if (!t) return;
|
|
41
|
-
t.renderTask && (t.renderTask.cancel(), t.renderTask = null);
|
|
42
|
-
const e = t.element.querySelector("canvas");
|
|
43
|
-
if (e) {
|
|
44
|
-
const n = e.getContext("2d");
|
|
45
|
-
n && n.clearRect(0, 0, e.width, e.height), e.remove();
|
|
46
|
-
}
|
|
47
|
-
t.element.innerHTML = "", t.rendered = !1, t.rendering = !1;
|
|
48
|
-
}, []), P = u(() => {
|
|
49
|
-
if (!c.current || !i.current) return;
|
|
50
|
-
const r = i.current.querySelector(".pdf-pages");
|
|
51
|
-
if (r) {
|
|
52
|
-
r.innerHTML = "", s.current.clear();
|
|
53
|
-
for (let t = 1; t <= l; t++) {
|
|
54
|
-
const e = document.createElement("div");
|
|
55
|
-
e.className = "rfp-relative rfp-flex rfp-justify-center rfp-min-h-[800px]", e.setAttribute("data-page-number", String(t)), r.appendChild(e), s.current.set(t, {
|
|
56
|
-
element: e,
|
|
57
|
-
rendered: !1,
|
|
58
|
-
rendering: !1,
|
|
59
|
-
renderTask: null
|
|
60
|
-
}), f.current && f.current.observe(e);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}, [l]), V = u(async () => {
|
|
64
|
-
if (D(null), R(!0), j(0), c.current) {
|
|
65
|
-
try {
|
|
66
|
-
c.current.destroy();
|
|
67
|
-
} catch {
|
|
68
|
-
}
|
|
69
|
-
c.current = null;
|
|
70
|
-
}
|
|
71
|
-
try {
|
|
72
|
-
const r = _.getDocument({ url: m });
|
|
73
|
-
c.current = await r.promise;
|
|
74
|
-
const t = c.current.numPages;
|
|
75
|
-
j(t), M(t), g(1), R(!1);
|
|
76
|
-
} catch (r) {
|
|
77
|
-
console.error("PDF 加载错误:", r), D(N("pdf.load_failed")), R(!1);
|
|
78
|
-
}
|
|
79
|
-
}, [m, M, g, N]), C = u(() => {
|
|
80
|
-
if (!i.current || s.current.size === 0) return;
|
|
81
|
-
const r = i.current, t = r.scrollTop, e = r.clientHeight, n = t + e / 2;
|
|
82
|
-
let a = 1, o = 1 / 0;
|
|
83
|
-
s.current.forEach((v, b) => {
|
|
84
|
-
const p = v.element.getBoundingClientRect(), L = r.getBoundingClientRect(), B = p.top - L.top + p.height / 2 + t, q = Math.abs(B - n);
|
|
85
|
-
q < o && (o = q, a = b);
|
|
86
|
-
}), a !== k && g(a);
|
|
87
|
-
}, [k, g]);
|
|
88
|
-
return d(() => (f.current = new IntersectionObserver(
|
|
89
|
-
(r) => {
|
|
90
|
-
r.forEach((t) => {
|
|
91
|
-
const e = Number(t.target.getAttribute("data-page-number"));
|
|
92
|
-
if (e)
|
|
93
|
-
if (t.isIntersecting)
|
|
94
|
-
I(e, T);
|
|
95
|
-
else {
|
|
96
|
-
const n = s.current.get(e);
|
|
97
|
-
n && n.rendered && x(e);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
root: i.current,
|
|
103
|
-
rootMargin: "500px 0px",
|
|
104
|
-
threshold: 0
|
|
105
|
-
}
|
|
106
|
-
), () => {
|
|
107
|
-
f.current && (f.current.disconnect(), f.current = null);
|
|
108
|
-
}), [T, I, x]), d(() => {
|
|
109
|
-
m && V();
|
|
110
|
-
}, [m, V]), d(() => {
|
|
111
|
-
l > 0 && setTimeout(() => {
|
|
112
|
-
P();
|
|
113
|
-
}, 0);
|
|
114
|
-
}, [l, P]), d(() => {
|
|
115
|
-
const r = setTimeout(() => {
|
|
116
|
-
s.current.forEach((t, e) => {
|
|
117
|
-
t.rendered && x(e);
|
|
118
|
-
}), f.current && i.current && s.current.forEach((t) => {
|
|
119
|
-
var e, n;
|
|
120
|
-
(e = f.current) == null || e.unobserve(t.element), (n = f.current) == null || n.observe(t.element);
|
|
121
|
-
});
|
|
122
|
-
}, 150);
|
|
123
|
-
return () => clearTimeout(r);
|
|
124
|
-
}, [T, x]), d(() => {
|
|
125
|
-
const r = i.current;
|
|
126
|
-
if (r)
|
|
127
|
-
return r.addEventListener("scroll", C), () => r.removeEventListener("scroll", C);
|
|
128
|
-
}, [C]), d(() => () => {
|
|
129
|
-
if (s.current.forEach((r) => {
|
|
130
|
-
r.renderTask && r.renderTask.cancel();
|
|
131
|
-
}), s.current.clear(), c.current) {
|
|
132
|
-
try {
|
|
133
|
-
c.current.destroy();
|
|
134
|
-
} catch {
|
|
135
|
-
}
|
|
136
|
-
c.current = null;
|
|
137
|
-
}
|
|
138
|
-
}, []), /* @__PURE__ */ A(
|
|
139
|
-
"div",
|
|
140
|
-
{
|
|
141
|
-
ref: i,
|
|
142
|
-
className: "rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full rfp-overflow-auto rfp-py-4 md:rfp-py-8 rfp-px-2 md:rfp-px-4",
|
|
143
|
-
children: [
|
|
144
|
-
h && /* @__PURE__ */ y(O, { message: h }),
|
|
145
|
-
!h && H && /* @__PURE__ */ y("div", { className: "rfp-flex rfp-items-center rfp-justify-center rfp-min-h-screen", children: /* @__PURE__ */ y("div", { className: "rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin" }) }),
|
|
146
|
-
!h && !H && /* @__PURE__ */ y("div", { className: "pdf-pages rfp-flex rfp-flex-col rfp-gap-4" }),
|
|
147
|
-
l > 0 && /* @__PURE__ */ A("div", { className: "rfp-sticky rfp-bottom-2 md:rfp-bottom-4 rfp-mt-4 md:rfp-mt-8 rfp-bg-surface-nav-hover rfp-backdrop-blur-xl rfp-text-fg-primary rfp-px-4 rfp-py-2 md:rfp-px-6 md:rfp-py-3 rfp-rounded-full rfp-text-xs md:rfp-text-sm rfp-font-medium rfp-shadow-2xl rfp-border rfp-border-line-weak", children: [
|
|
148
|
-
"第 ",
|
|
149
|
-
k,
|
|
150
|
-
" 页 / 共 ",
|
|
151
|
-
l,
|
|
152
|
-
" 页"
|
|
153
|
-
] })
|
|
154
|
-
]
|
|
155
|
-
}
|
|
156
|
-
);
|
|
157
|
-
};
|
|
158
|
-
export {
|
|
159
|
-
Q as PdfRenderer
|
|
160
|
-
};
|
|
161
|
-
//# sourceMappingURL=index-jHf5E4be.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-jHf5E4be.mjs","sources":["../../src/renderers/Pdf/index.tsx"],"sourcesContent":["import { useState, useEffect, useRef, useCallback } from 'react';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { RendererError } from '../RendererError';\n// @ts-ignore - pdfjs-dist 类型路径\nimport * as pdfjsLib from 'pdfjs-dist/build/pdf.mjs';\n\ninterface PdfPageProxy {\n getViewport(opts: { scale: number }): { width: number; height: number };\n render(opts: { canvasContext: CanvasRenderingContext2D; viewport: { width: number; height: number } }): {\n promise: Promise<void>;\n cancel(): void;\n };\n}\n\ninterface PdfDocumentProxy {\n numPages: number;\n getPage(pageNumber: number): Promise<PdfPageProxy>;\n destroy(): void;\n}\n\ninterface PageState {\n element: HTMLDivElement;\n rendered: boolean;\n rendering: boolean;\n renderTask: { cancel(): void } | null;\n}\n\ninterface PdfRendererProps {\n url: string;\n zoom: number;\n currentPage: number;\n onPageChange: (page: number) => void;\n onTotalPagesChange: (total: number) => void;\n onPageWidthChange?: (width: number) => void;\n}\n\nexport const PdfRenderer: React.FC<PdfRendererProps> = ({\n url,\n zoom,\n currentPage,\n onPageChange,\n onTotalPagesChange,\n onPageWidthChange,\n}) => {\n const t = useTranslator();\n const [numPages, setNumPages] = useState<number>(0);\n const [error, setError] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const containerRef = useRef<HTMLDivElement>(null);\n const pdfDocRef = useRef<PdfDocumentProxy | null>(null);\n const pageStatesRef = useRef<Map<number, PageState>>(new Map());\n const observerRef = useRef<IntersectionObserver | null>(null);\n\n // 渲染单个页面\n const renderPage = useCallback(async (pageNumber: number, scale: number) => {\n if (!pdfDocRef.current) return;\n const state = pageStatesRef.current.get(pageNumber);\n if (!state || state.rendering) return;\n\n state.rendering = true;\n\n try {\n const page = await pdfDocRef.current.getPage(pageNumber);\n const viewport = page.getViewport({ scale });\n\n const canvas = document.createElement('canvas');\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n canvas.style.maxWidth = '100%';\n canvas.style.height = 'auto';\n canvas.style.borderRadius = '0';\n canvas.style.display = 'block';\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const renderTask = page.render({ canvasContext: ctx, viewport });\n state.renderTask = renderTask;\n await renderTask.promise;\n\n // 上报第一页原始宽度\n if (pageNumber === 1 && onPageWidthChange) {\n const baseViewport = page.getViewport({ scale: 1 });\n onPageWidthChange(baseViewport.width);\n }\n\n state.element.innerHTML = '';\n state.element.appendChild(canvas);\n\n // 页码标签\n const label = document.createElement('div');\n label.textContent = String(pageNumber);\n label.className = 'rfp-absolute rfp-top-2 rfp-right-2 rfp-bg-surface-nav-hover rfp-backdrop-blur-sm rfp-text-fg-primary rfp-text-xs rfp-px-3 rfp-py-1 rfp-rounded-full';\n state.element.appendChild(label);\n\n state.rendered = true;\n } catch (err: any) {\n if (err?.name !== 'RenderingCancelledException') {\n console.error(`渲染页面 ${pageNumber} 失败:`, err);\n }\n } finally {\n state.rendering = false;\n state.renderTask = null;\n }\n }, [onPageWidthChange]);\n\n // 清理页面 canvas\n const clearPageCanvas = useCallback((pageNumber: number) => {\n const state = pageStatesRef.current.get(pageNumber);\n if (!state) return;\n\n // 取消正在进行的渲染\n if (state.renderTask) {\n state.renderTask.cancel();\n state.renderTask = null;\n }\n\n // 清理 canvas\n const canvas = state.element.querySelector('canvas');\n if (canvas) {\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n canvas.remove();\n }\n\n state.element.innerHTML = '';\n state.rendered = false;\n state.rendering = false;\n }, []);\n\n // 初始化页面占位符\n const initPagePlaceholders = useCallback(() => {\n if (!pdfDocRef.current || !containerRef.current) return;\n\n const wrapper = containerRef.current.querySelector('.pdf-pages') as HTMLDivElement | null;\n if (!wrapper) return;\n\n wrapper.innerHTML = '';\n pageStatesRef.current.clear();\n\n for (let i = 1; i <= numPages; i++) {\n const pageDiv = document.createElement('div');\n pageDiv.className = 'rfp-relative rfp-flex rfp-justify-center rfp-min-h-[800px]';\n pageDiv.setAttribute('data-page-number', String(i));\n wrapper.appendChild(pageDiv);\n\n pageStatesRef.current.set(i, {\n element: pageDiv,\n rendered: false,\n rendering: false,\n renderTask: null,\n });\n\n // 观察页面元素\n if (observerRef.current) {\n observerRef.current.observe(pageDiv);\n }\n }\n }, [numPages]);\n\n // 加载 PDF 文档\n const loadPdf = useCallback(async () => {\n setError(null);\n setIsLoading(true);\n setNumPages(0);\n\n if (pdfDocRef.current) {\n try {\n pdfDocRef.current.destroy();\n } catch {\n // ignore\n }\n pdfDocRef.current = null;\n }\n\n try {\n const loadingTask = pdfjsLib.getDocument({ url });\n pdfDocRef.current = (await loadingTask.promise) as PdfDocumentProxy;\n const total = pdfDocRef.current.numPages;\n\n setNumPages(total);\n onTotalPagesChange(total);\n onPageChange(1);\n setIsLoading(false);\n } catch (err) {\n console.error('PDF 加载错误:', err);\n setError(t('pdf.load_failed'));\n setIsLoading(false);\n }\n }, [url, onTotalPagesChange, onPageChange, t]);\n\n // 滚动处理\n const handleScroll = useCallback(() => {\n if (!containerRef.current || pageStatesRef.current.size === 0) return;\n\n const container = containerRef.current;\n const scrollTop = container.scrollTop;\n const containerHeight = container.clientHeight;\n const scrollCenter = scrollTop + containerHeight / 2;\n\n let currentVisiblePage = 1;\n let minDistance = Infinity;\n\n pageStatesRef.current.forEach((state, pageNumber) => {\n const rect = state.element.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const pageCenter = rect.top - containerRect.top + rect.height / 2 + scrollTop;\n const distance = Math.abs(pageCenter - scrollCenter);\n\n if (distance < minDistance) {\n minDistance = distance;\n currentVisiblePage = pageNumber;\n }\n });\n\n if (currentVisiblePage !== currentPage) {\n onPageChange(currentVisiblePage);\n }\n }, [currentPage, onPageChange]);\n\n // 初始化 IntersectionObserver\n useEffect(() => {\n observerRef.current = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n const pageNumber = Number(entry.target.getAttribute('data-page-number'));\n if (!pageNumber) return;\n\n if (entry.isIntersecting) {\n // 页面进入视口,渲染\n renderPage(pageNumber, zoom);\n } else {\n // 页面离开视口,清理\n const state = pageStatesRef.current.get(pageNumber);\n if (state && state.rendered) {\n clearPageCanvas(pageNumber);\n }\n }\n });\n },\n {\n root: containerRef.current,\n rootMargin: '500px 0px',\n threshold: 0,\n }\n );\n\n return () => {\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n };\n }, [zoom, renderPage, clearPageCanvas]);\n\n // 监听 URL 变化\n useEffect(() => {\n // 只有 URL 有效时才加载(避免空字符串或已 revoke 的 blob URL)\n if (url) {\n loadPdf();\n }\n }, [url, loadPdf]);\n\n // 监听 numPages 变化,初始化占位符\n useEffect(() => {\n if (numPages > 0) {\n // 等待 DOM 更新后初始化占位符\n setTimeout(() => {\n initPagePlaceholders();\n }, 0);\n }\n }, [numPages, initPagePlaceholders]);\n\n // 监听 zoom 变化(防抖)\n useEffect(() => {\n const timer = setTimeout(() => {\n // 清理所有已渲染页面\n pageStatesRef.current.forEach((state, pageNumber) => {\n if (state.rendered) {\n clearPageCanvas(pageNumber);\n }\n });\n\n // 触发重新渲染\n if (observerRef.current && containerRef.current) {\n pageStatesRef.current.forEach((state) => {\n observerRef.current?.unobserve(state.element);\n observerRef.current?.observe(state.element);\n });\n }\n }, 150);\n\n return () => clearTimeout(timer);\n }, [zoom, clearPageCanvas]);\n\n // 监听滚动事件\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, [handleScroll]);\n\n // 清理\n useEffect(() => {\n return () => {\n // 清理所有渲染任务\n pageStatesRef.current.forEach((state) => {\n if (state.renderTask) {\n state.renderTask.cancel();\n }\n });\n pageStatesRef.current.clear();\n\n if (pdfDocRef.current) {\n try {\n pdfDocRef.current.destroy();\n } catch {\n // ignore\n }\n pdfDocRef.current = null;\n }\n };\n }, []);\n\n return (\n <div\n ref={containerRef}\n className=\"rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full rfp-overflow-auto rfp-py-4 md:rfp-py-8 rfp-px-2 md:rfp-px-4\"\n >\n {error && (\n <RendererError message={error} />\n )}\n\n {!error && isLoading && (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-min-h-screen\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {!error && !isLoading && (\n <div className=\"pdf-pages rfp-flex rfp-flex-col rfp-gap-4\" />\n )}\n\n {/* 底部页码指示器 */}\n {numPages > 0 && (\n <div className=\"rfp-sticky rfp-bottom-2 md:rfp-bottom-4 rfp-mt-4 md:rfp-mt-8 rfp-bg-surface-nav-hover rfp-backdrop-blur-xl rfp-text-fg-primary rfp-px-4 rfp-py-2 md:rfp-px-6 md:rfp-py-3 rfp-rounded-full rfp-text-xs md:rfp-text-sm rfp-font-medium rfp-shadow-2xl rfp-border rfp-border-line-weak\">\n 第 {currentPage} 页 / 共 {numPages} 页\n </div>\n )}\n </div>\n );\n};\n"],"names":["PdfRenderer","url","zoom","currentPage","onPageChange","onTotalPagesChange","onPageWidthChange","t","useTranslator","numPages","setNumPages","useState","error","setError","isLoading","setIsLoading","containerRef","useRef","pdfDocRef","pageStatesRef","observerRef","renderPage","useCallback","pageNumber","scale","state","page","viewport","canvas","ctx","renderTask","baseViewport","label","err","clearPageCanvas","initPagePlaceholders","wrapper","i","pageDiv","loadPdf","loadingTask","pdfjsLib","total","handleScroll","container","scrollTop","containerHeight","scrollCenter","currentVisiblePage","minDistance","rect","containerRect","pageCenter","distance","useEffect","entries","entry","timer","_a","_b","jsxs","jsx","RendererError"],"mappings":"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"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { useState as l, useEffect as f } from "react";
|
|
2
|
-
import { codeToHtml as a } from "shiki";
|
|
3
|
-
import { b as n } from "./index--lXiT1Y_.mjs";
|
|
4
|
-
function p(s, o) {
|
|
5
|
-
const r = n(), [u, i] = l(""), [h, e] = l(!0);
|
|
6
|
-
return f(() => {
|
|
7
|
-
let t = !1;
|
|
8
|
-
return e(!0), a(s, {
|
|
9
|
-
lang: o,
|
|
10
|
-
theme: r === "light" ? "github-light" : "dark-plus"
|
|
11
|
-
}).then((m) => {
|
|
12
|
-
t || (i(m), e(!1));
|
|
13
|
-
}).catch(() => {
|
|
14
|
-
t || (i(""), e(!1));
|
|
15
|
-
}), () => {
|
|
16
|
-
t = !0;
|
|
17
|
-
};
|
|
18
|
-
}, [s, o, r]), { html: u, loading: h };
|
|
19
|
-
}
|
|
20
|
-
export {
|
|
21
|
-
p as u
|
|
22
|
-
};
|
|
23
|
-
//# sourceMappingURL=useShikiHighlight-DoY3TBPT.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useShikiHighlight-DoY3TBPT.mjs","sources":["../../src/hooks/useShikiHighlight.ts"],"sourcesContent":["import { useState, useEffect } from 'react';\nimport { codeToHtml } from 'shiki';\nimport { useResolvedTheme } from '../ThemeContext';\n\n/**\n * 用 shiki 把代码高亮成 HTML(与 vue-file-preview 同引擎、同主题,保证两端视觉一致)。\n *\n * - dark 主题用 `dark-plus`(VSCode Dark Plus)\n * - light 主题用 `github-light`(GitHub Light)\n *\n * shiki 输出的 <pre> 自带 inline 背景/前景色,主题切换时必须重新高亮,\n * 因此 resolvedTheme 进入依赖数组。\n *\n * @returns\n * - `html`: 高亮后的 HTML 字符串(失败或加载中为 '')\n * - `loading`: 是否正在高亮\n */\nexport function useShikiHighlight(code: string, lang: string): { html: string; loading: boolean } {\n const resolvedTheme = useResolvedTheme();\n const [html, setHtml] = useState('');\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n codeToHtml(code, {\n lang,\n theme: resolvedTheme === 'light' ? 'github-light' : 'dark-plus',\n })\n .then((out) => {\n if (!cancelled) {\n setHtml(out);\n setLoading(false);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setHtml('');\n setLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [code, lang, resolvedTheme]);\n\n return { html, loading };\n}\n"],"names":["useShikiHighlight","code","lang","resolvedTheme","useResolvedTheme","html","setHtml","useState","loading","setLoading","useEffect","cancelled","codeToHtml","out"],"mappings":";;;AAiBO,SAASA,EAAkBC,GAAcC,GAAkD;AAChG,QAAMC,IAAgBC,EAAA,GAChB,CAACC,GAAMC,CAAO,IAAIC,EAAS,EAAE,GAC7B,CAACC,GAASC,CAAU,IAAIF,EAAS,EAAI;AAE3C,SAAAG,EAAU,MAAM;AACd,QAAIC,IAAY;AAChB,WAAAF,EAAW,EAAI,GACfG,EAAWX,GAAM;AAAA,MACf,MAAAC;AAAA,MACA,OAAOC,MAAkB,UAAU,iBAAiB;AAAA,IAAA,CACrD,EACE,KAAK,CAACU,MAAQ;AACb,MAAKF,MACHL,EAAQO,CAAG,GACXJ,EAAW,EAAK;AAAA,IAEpB,CAAC,EACA,MAAM,MAAM;AACX,MAAKE,MACHL,EAAQ,EAAE,GACVG,EAAW,EAAK;AAAA,IAEpB,CAAC,GACI,MAAM;AACX,MAAAE,IAAY;AAAA,IACd;AAAA,EACF,GAAG,CAACV,GAAMC,GAAMC,CAAa,CAAC,GAEvB,EAAE,MAAAE,GAAM,SAAAG,EAAA;AACjB;"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { ToolbarGroup } from '../toolbar.types';
|
|
3
|
-
import type { EpubRendererHandle } from './index';
|
|
4
|
-
import type { Translator } from '@eternalheart/file-preview-core';
|
|
5
|
-
export interface EpubToolbarContext {
|
|
6
|
-
epubRef: React.RefObject<EpubRendererHandle | null>;
|
|
7
|
-
current: number;
|
|
8
|
-
total: number;
|
|
9
|
-
fullWidth: boolean;
|
|
10
|
-
t: Translator;
|
|
11
|
-
}
|
|
12
|
-
export declare function getEpubToolbarGroups(ctx: EpubToolbarContext): ToolbarGroup[];
|
|
13
|
-
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/renderers/Epub/toolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,CAAC,EAAE,UAAU,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,kBAAkB,GAAG,YAAY,EAAE,CAyB5E"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { ToolbarGroup } from '../toolbar.types';
|
|
2
|
-
import type { Translator } from '@eternalheart/file-preview-core';
|
|
3
|
-
export interface ImageToolbarContext {
|
|
4
|
-
zoom: number;
|
|
5
|
-
onZoomIn: () => void;
|
|
6
|
-
onZoomOut: () => void;
|
|
7
|
-
onFitToWidth: () => void;
|
|
8
|
-
onOriginalSize: () => void;
|
|
9
|
-
onRotateLeft: () => void;
|
|
10
|
-
onRotateRight: () => void;
|
|
11
|
-
onReset: () => void;
|
|
12
|
-
t: Translator;
|
|
13
|
-
}
|
|
14
|
-
export declare function getImageToolbarGroups(ctx: ImageToolbarContext): ToolbarGroup[];
|
|
15
|
-
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/renderers/Image/toolbar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAmBlE,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,CAAC,EAAE,UAAU,CAAC;CACf;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,mBAAmB,GAAG,YAAY,EAAE,CA2B9E"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { ToolbarGroup } from '../toolbar.types';
|
|
2
|
-
import type { Translator } from '@eternalheart/file-preview-core';
|
|
3
|
-
export interface MarkdownToolbarContext {
|
|
4
|
-
viewMode: 'preview' | 'source';
|
|
5
|
-
onToggleViewMode: () => void;
|
|
6
|
-
t: Translator;
|
|
7
|
-
}
|
|
8
|
-
export declare function getMarkdownToolbarGroups(ctx: MarkdownToolbarContext): ToolbarGroup[];
|
|
9
|
-
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/renderers/Markdown/toolbar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC/B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,CAAC,EAAE,UAAU,CAAC;CACf;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,sBAAsB,GAAG,YAAY,EAAE,CAepF"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { ToolbarGroup } from '../toolbar.types';
|
|
3
|
-
import type { MobiRendererHandle } from './index';
|
|
4
|
-
import type { Translator } from '@eternalheart/file-preview-core';
|
|
5
|
-
export interface MobiToolbarContext {
|
|
6
|
-
mobiRef: React.RefObject<MobiRendererHandle | null>;
|
|
7
|
-
current: number;
|
|
8
|
-
total: number;
|
|
9
|
-
fullWidth: boolean;
|
|
10
|
-
t: Translator;
|
|
11
|
-
}
|
|
12
|
-
export declare function getMobiToolbarGroups(ctx: MobiToolbarContext): ToolbarGroup[];
|
|
13
|
-
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/renderers/Mobi/toolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,CAAC,EAAE,UAAU,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,kBAAkB,GAAG,YAAY,EAAE,CA8C5E"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { ToolbarGroup } from '../toolbar.types';
|
|
2
|
-
import type { Translator } from '@eternalheart/file-preview-core';
|
|
3
|
-
export interface PdfToolbarContext {
|
|
4
|
-
zoom: number;
|
|
5
|
-
onZoomIn: () => void;
|
|
6
|
-
onZoomOut: () => void;
|
|
7
|
-
onReset: () => void;
|
|
8
|
-
t: Translator;
|
|
9
|
-
}
|
|
10
|
-
export declare function getPdfToolbarGroups(ctx: PdfToolbarContext): ToolbarGroup[];
|
|
11
|
-
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/renderers/Pdf/toolbar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,CAAC,EAAE,UAAU,CAAC;CACf;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,iBAAiB,GAAG,YAAY,EAAE,CAe1E"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ToolbarGroup } from '../toolbar.types';
|
|
2
|
-
import type { Translator } from '@eternalheart/file-preview-core';
|
|
3
|
-
export interface TextToolbarContext {
|
|
4
|
-
wordWrap: boolean;
|
|
5
|
-
onToggleWrap: () => void;
|
|
6
|
-
isHtml: boolean;
|
|
7
|
-
htmlPreview: boolean;
|
|
8
|
-
onToggleHtmlPreview: () => void;
|
|
9
|
-
t: Translator;
|
|
10
|
-
}
|
|
11
|
-
export declare function getTextToolbarGroups(ctx: TextToolbarContext): ToolbarGroup[];
|
|
12
|
-
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/renderers/Text/toolbar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,CAAC,EAAE,UAAU,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,kBAAkB,GAAG,YAAY,EAAE,CA8B5E"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { ToolbarGroup } from '../toolbar.types';
|
|
2
|
-
import type { Translator } from '@eternalheart/file-preview-core';
|
|
3
|
-
export interface ZipToolbarStats {
|
|
4
|
-
files: number;
|
|
5
|
-
dirs: number;
|
|
6
|
-
size: number;
|
|
7
|
-
}
|
|
8
|
-
export interface ZipToolbarContext {
|
|
9
|
-
stats: ZipToolbarStats | null;
|
|
10
|
-
t: Translator;
|
|
11
|
-
}
|
|
12
|
-
export declare function getZipToolbarGroups({ stats }: ZipToolbarContext): ToolbarGroup[];
|
|
13
|
-
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/renderers/Zip/toolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IAC9B,CAAC,EAAE,UAAU,CAAC;CACf;AAED,wBAAgB,mBAAmB,CAAC,EAAE,KAAK,EAAE,EAAE,iBAAiB,GAAG,YAAY,EAAE,CAahF"}
|