@eternalheart/react-file-preview 1.4.0 → 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 +1 -0
- 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/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-CzM2mxrD.mjs → index-CKdQL1Bk.mjs} +130 -128
- package/lib/chunks/{index-CzM2mxrD.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-DuP0Tlpo.mjs → index-CRZqNMQ7.mjs} +43 -41
- package/lib/chunks/index-CRZqNMQ7.mjs.map +1 -0
- package/lib/chunks/{index-Cp68OevR.mjs → index-CTghYlSh.mjs} +1299 -1297
- package/lib/chunks/{index-Cp68OevR.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-kALp0tqz.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-10O8tfTH.mjs → index-DoGKcq9y.mjs} +194 -192
- package/lib/chunks/index-DoGKcq9y.mjs.map +1 -0
- package/lib/chunks/{index-C_BJatqr.mjs → index-DzCLf1Db.mjs} +42 -40
- 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-DaAXRBWL.mjs → index-OXjOFggq.mjs} +864 -862
- package/lib/chunks/{index-DaAXRBWL.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-DoFsoBKL.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/FilePreviewToolbar.d.ts +1 -0
- package/lib/components/preview/FilePreviewToolbar.d.ts.map +1 -1
- package/lib/components/preview/ToolbarButton.d.ts +3 -1
- package/lib/components/preview/ToolbarButton.d.ts.map +1 -1
- package/lib/hooks/index.d.ts +0 -6
- package/lib/hooks/index.d.ts.map +1 -1
- package/lib/hooks/useShikiHighlight.d.ts +3 -1
- package/lib/hooks/useShikiHighlight.d.ts.map +1 -1
- package/lib/index.cjs +32 -30
- 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 -8
- 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 +2 -0
- package/lib/renderers/toolbar.types.d.ts.map +1 -1
- package/lib/toolbar/renderItems.d.ts.map +1 -1
- package/package.json +3 -3
- package/lib/chunks/index-0v5STX5f.mjs +0 -105
- package/lib/chunks/index-0v5STX5f.mjs.map +0 -1
- package/lib/chunks/index-10O8tfTH.mjs.map +0 -1
- package/lib/chunks/index-BCyv1HM9.mjs +0 -175
- package/lib/chunks/index-BCyv1HM9.mjs.map +0 -1
- package/lib/chunks/index-Bo90aGhy.mjs +0 -114
- package/lib/chunks/index-Bo90aGhy.mjs.map +0 -1
- package/lib/chunks/index-CEeKt7L3.mjs +0 -2808
- package/lib/chunks/index-CEeKt7L3.mjs.map +0 -1
- package/lib/chunks/index-CWKbnvW6.mjs +0 -270
- package/lib/chunks/index-CWKbnvW6.mjs.map +0 -1
- package/lib/chunks/index-C_BJatqr.mjs.map +0 -1
- package/lib/chunks/index-Cbz5Z6ZK.mjs +0 -263
- package/lib/chunks/index-Cbz5Z6ZK.mjs.map +0 -1
- package/lib/chunks/index-DTYBFuAH.mjs +0 -357
- package/lib/chunks/index-DTYBFuAH.mjs.map +0 -1
- package/lib/chunks/index-DoFsoBKL.mjs.map +0 -1
- package/lib/chunks/index-DuP0Tlpo.mjs.map +0 -1
- package/lib/chunks/index-Dv3RQz86.mjs +0 -270
- package/lib/chunks/index-Dv3RQz86.mjs.map +0 -1
- package/lib/chunks/index-QfpHck8N.mjs +0 -55
- package/lib/chunks/index-QfpHck8N.mjs.map +0 -1
- package/lib/chunks/index-gjSQeou7.mjs +0 -194
- package/lib/chunks/index-gjSQeou7.mjs.map +0 -1
- package/lib/chunks/index-kALp0tqz.mjs.map +0 -1
- package/lib/chunks/index-kCeSnFs-.mjs +0 -54
- package/lib/chunks/index-kCeSnFs-.mjs.map +0 -1
- package/lib/chunks/useShikiHighlight-BA9qgdGA.mjs +0 -23
- package/lib/chunks/useShikiHighlight-BA9qgdGA.mjs.map +0 -1
- package/lib/hooks/rendererReducer.d.ts +0 -10
- package/lib/hooks/rendererReducer.d.ts.map +0 -1
- package/lib/hooks/types.d.ts +0 -152
- package/lib/hooks/types.d.ts.map +0 -1
- package/lib/hooks/useBookRenderer.d.ts +0 -14
- package/lib/hooks/useBookRenderer.d.ts.map +0 -1
- package/lib/hooks/useFilePreviewState.d.ts +0 -10
- package/lib/hooks/useFilePreviewState.d.ts.map +0 -1
- package/lib/hooks/useImageAutoFit.d.ts +0 -13
- package/lib/hooks/useImageAutoFit.d.ts.map +0 -1
- package/lib/hooks/useToolbarConfig.d.ts +0 -25
- package/lib/hooks/useToolbarConfig.d.ts.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 -16
- 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
- package/lib/toolbar/registry.d.ts +0 -51
- package/lib/toolbar/registry.d.ts.map +0 -1
package/README.zh-CN.md
CHANGED
|
@@ -4,24 +4,23 @@
|
|
|
4
4
|
|
|
5
5
|
一个现代化、功能丰富的 React 文件预览组件,支持图片、视频、音频、PDF、Office 文档(Word、Excel、PowerPoint)、Markdown 和代码文件预览。
|
|
6
6
|
|
|
7
|
-
## ✨ 特性
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
## 📦 安装
|
|
7
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/2728.svg" width="20" height="20" alt="✨" /> 特性
|
|
8
|
+
|
|
9
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f3a8.svg" width="16" height="16" alt="🎨" style="vertical-align: middle;" /> **现代化 UI** - 简洁现代的界面设计,流畅动画
|
|
10
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f4c1.svg" width="16" height="16" alt="📁" style="vertical-align: middle;" /> **多格式支持** - 支持 20+ 种文件格式
|
|
11
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1fa9f.svg" width="16" height="16" alt="🪟" style="vertical-align: middle;" /> **两种展示模式** - 全屏弹窗 **或** 嵌入式内联预览
|
|
12
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f5bc.svg" width="16" height="16" alt="🖼️" style="vertical-align: middle;" /> **强大的图片查看器** - 缩放、旋转、拖拽、滚轮缩放
|
|
13
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f3ac.svg" width="16" height="16" alt="🎬" style="vertical-align: middle;" /> **自定义视频播放器** - 基于 Video.js,支持多种视频格式
|
|
14
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f3b5.svg" width="16" height="16" alt="🎵" style="vertical-align: middle;" /> **自定义音频播放器** - 精美的音频控制界面
|
|
15
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f4c4.svg" width="16" height="16" alt="📄" style="vertical-align: middle;" /> **PDF 查看器** - 支持分页浏览
|
|
16
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f4ca.svg" width="16" height="16" alt="📊" style="vertical-align: middle;" /> **Office 文档支持** - Word、Excel、PowerPoint 文件预览
|
|
17
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f4dd.svg" width="16" height="16" alt="📝" style="vertical-align: middle;" /> **Markdown 渲染** - 支持 GitHub Flavored Markdown
|
|
18
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f4bb.svg" width="16" height="16" alt="💻" style="vertical-align: middle;" /> **代码高亮** - 支持 40+ 种编程语言
|
|
19
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f3ad.svg" width="16" height="16" alt="🎭" style="vertical-align: middle;" /> **流畅动画** - 基于 Framer Motion
|
|
20
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f4f1.svg" width="16" height="16" alt="📱" style="vertical-align: middle;" /> **响应式设计** - 适配各种屏幕尺寸
|
|
21
|
+
<img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/2328.svg" width="16" height="16" alt="⌨️" style="vertical-align: middle;" /> **键盘导航** - 支持方向键和 ESC 键
|
|
22
|
+
|
|
23
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f4e6.svg" width="20" height="20" alt="📦" /> 安装
|
|
25
24
|
|
|
26
25
|
```bash
|
|
27
26
|
# 使用 npm
|
|
@@ -136,7 +135,7 @@ export default defineConfig({
|
|
|
136
135
|
|
|
137
136
|
> 说明:`@jsquash/avif` 仅在浏览器不原生支持 AVIF 时作为兜底使用(Chrome 85+、Firefox 93+、Safari 16+ 均已原生支持)。如果你的目标浏览器都覆盖原生支持范围,也可以直接从依赖中移除 `@jsquash/avif`。
|
|
138
137
|
|
|
139
|
-
## 🚀 快速开始
|
|
138
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f680.svg" width="20" height="20" alt="🚀" /> 快速开始
|
|
140
139
|
|
|
141
140
|
📖 **第一次使用?** 查看 [快速开始指南](./QUICK_START.md) 获取 5 分钟入门教程!
|
|
142
141
|
|
|
@@ -187,14 +186,18 @@ import { FilePreviewModal, PreviewFileInput } from '@eternalheart/react-file-pre
|
|
|
187
186
|
import '@eternalheart/react-file-preview/style.css';
|
|
188
187
|
|
|
189
188
|
function App() {
|
|
189
|
+
// 假设 file1 来自 File API:<input type="file">、拖拽、
|
|
190
|
+
// 剪贴板粘贴,或 fetch().then(r => r.blob())
|
|
191
|
+
const file1 = new File(['content'], 'example.txt', { type: 'text/plain' });
|
|
192
|
+
|
|
190
193
|
const files: PreviewFileInput[] = [
|
|
191
|
-
// 1. 原生 File
|
|
194
|
+
// 1. 原生 File 对象(组件卸载时自动释放)
|
|
192
195
|
file1,
|
|
193
196
|
|
|
194
|
-
// 2. HTTP URL
|
|
197
|
+
// 2. HTTP URL 字符串(按需加载)
|
|
195
198
|
'https://example.com/image.jpg',
|
|
196
199
|
|
|
197
|
-
// 3.
|
|
200
|
+
// 3. 带元数据的文件对象(推荐用于远程资源)
|
|
198
201
|
{
|
|
199
202
|
name: 'document.pdf',
|
|
200
203
|
type: 'application/pdf',
|
|
@@ -203,6 +206,9 @@ function App() {
|
|
|
203
206
|
},
|
|
204
207
|
];
|
|
205
208
|
|
|
209
|
+
// 内存提示: 如果你通过 URL.createObjectURL() 生成 URL,
|
|
210
|
+
// 文件移除时请调用 URL.revokeObjectURL() 避免内存泄漏。
|
|
211
|
+
|
|
206
212
|
return (
|
|
207
213
|
<FilePreviewModal
|
|
208
214
|
files={files}
|
|
@@ -256,7 +262,7 @@ function InlinePreview() {
|
|
|
256
262
|
<FilePreviewEmbed files={files} width={800} height={500} />
|
|
257
263
|
```
|
|
258
264
|
|
|
259
|
-
## 💡 使用示例
|
|
265
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f4a1.svg" width="20" height="20" alt="💡" /> 使用示例
|
|
260
266
|
|
|
261
267
|
### 预览 PowerPoint 文件
|
|
262
268
|
|
|
@@ -309,7 +315,7 @@ const files = [
|
|
|
309
315
|
/>
|
|
310
316
|
```
|
|
311
317
|
|
|
312
|
-
## 📖 支持的文件格式
|
|
318
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f4d6.svg" width="20" height="20" alt="📖" /> 支持的文件格式
|
|
313
319
|
|
|
314
320
|
### 图片
|
|
315
321
|
- **格式**: JPG, PNG, GIF, WebP, SVG, BMP, ICO
|
|
@@ -358,7 +364,56 @@ const files = [
|
|
|
358
364
|
### 电子书
|
|
359
365
|
- **EPUB**: 章节导航、翻页
|
|
360
366
|
|
|
361
|
-
##
|
|
367
|
+
## ⚠️ 功能限制与性能说明
|
|
368
|
+
|
|
369
|
+
### 支持等级
|
|
370
|
+
|
|
371
|
+
**✅ 完全支持(生产可用)**
|
|
372
|
+
- 图片(JPG, PNG, GIF, WebP, SVG, BMP, ICO)
|
|
373
|
+
- 视频(MP4, WebM, OGG)
|
|
374
|
+
- 音频(MP3, WAV, OGG)
|
|
375
|
+
- PDF
|
|
376
|
+
- Markdown
|
|
377
|
+
- 代码文件(通过 Shiki 支持 40+ 种语言,按需加载)
|
|
378
|
+
- JSON, CSV, XML
|
|
379
|
+
|
|
380
|
+
**⚠️ 部分支持(仅供预览)**
|
|
381
|
+
- **Office(DOCX, XLSX, PPTX)**: 基础布局和文本渲染。复杂格式(图表、宏、嵌入对象)可能无法准确渲染。
|
|
382
|
+
- **ZIP**: 目录树浏览 + 文本/代码/图片内联预览。大型压缩包(>100MB)可能导致性能问题。
|
|
383
|
+
- **字体(TTF, OTF, WOFF)**: 元数据 + 字符预览。不支持完整字体特性测试。
|
|
384
|
+
|
|
385
|
+
**🧪 实验性支持**
|
|
386
|
+
- **MSG(Outlook 邮件)**: 邮件头和纯文本正文。复杂 HTML 正文可能无法正确渲染。
|
|
387
|
+
- **EPUB**: 基础章节导航。CSS 样式可能与原生阅读器有差异。不支持 DRM 保护文件。
|
|
388
|
+
- **字幕格式(SRT, ASS, TTML, LRC)**: 仅文本显示。不支持视频同步或高级样式。
|
|
389
|
+
|
|
390
|
+
### 性能边界
|
|
391
|
+
|
|
392
|
+
| 文件大小 | 状态 | 说明 |
|
|
393
|
+
|---------|------|------|
|
|
394
|
+
| < 50MB | ✅ 推荐 | 流畅的预览体验 |
|
|
395
|
+
| 50-100MB | ⚠️ 可能卡顿 | 加载时 UI 可能无响应 |
|
|
396
|
+
| > 100MB | ❌ 不推荐 | 可能超出浏览器内存限制 |
|
|
397
|
+
|
|
398
|
+
**特殊情况:**
|
|
399
|
+
- **ZIP 压缩包**: 性能取决于文件数量,而非仅体积
|
|
400
|
+
- **Office 文档**: 复杂文件(>200 页、大量图片)可能超时
|
|
401
|
+
- **代码高亮**: >5MB 的文件可能需要 3-5 秒高亮时间
|
|
402
|
+
|
|
403
|
+
### 浏览器兼容性
|
|
404
|
+
|
|
405
|
+
**最低要求:**
|
|
406
|
+
- Chrome 90+ / Edge 90+
|
|
407
|
+
- Firefox 88+
|
|
408
|
+
- Safari 14+
|
|
409
|
+
|
|
410
|
+
**已知限制:**
|
|
411
|
+
- **Safari iOS**: 视频自动播放需要用户交互
|
|
412
|
+
- **Firefox**: AVIF 支持需要 Firefox 93+(已包含降级解码器)
|
|
413
|
+
- **Office 格式**: 不同浏览器渲染质量有差异
|
|
414
|
+
- **EPUB**: 旧版浏览器可能不支持某些 CSS 特性
|
|
415
|
+
|
|
416
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f3ae.svg" width="20" height="20" alt="🎮" /> API 参考
|
|
362
417
|
|
|
363
418
|
### FilePreviewModal Props
|
|
364
419
|
|
|
@@ -374,6 +429,7 @@ const files = [
|
|
|
374
429
|
| `messages` | `Partial<Record<Locale, Partial<Messages>>>` | ❌ | 自定义翻译覆盖 |
|
|
375
430
|
| `headless` | `boolean` | ❌ | 无头模式,隐藏工具栏和导航箭头 |
|
|
376
431
|
| `theme` | `Theme` | ❌ | 主题模式: `'auto' \| 'dark' \| 'light'`(默认 `'dark'`) |
|
|
432
|
+
| `showDownload` | `boolean` | ❌ | 是否显示下载按钮(默认 `true`) |
|
|
377
433
|
|
|
378
434
|
### FilePreviewEmbed Props
|
|
379
435
|
|
|
@@ -391,6 +447,7 @@ const files = [
|
|
|
391
447
|
| `messages` | `Partial<Record<Locale, Partial<Messages>>>` | ❌ | - | 自定义翻译覆盖 |
|
|
392
448
|
| `headless` | `boolean` | ❌ | `false` | 无头模式,隐藏工具栏和导航箭头 |
|
|
393
449
|
| `theme` | `Theme` | ❌ | `'dark'` | 主题模式: `'auto' \| 'dark' \| 'light'` |
|
|
450
|
+
| `showDownload` | `boolean` | ❌ | `true` | 是否显示下载按钮 |
|
|
394
451
|
|
|
395
452
|
> `FilePreviewEmbed` 没有 `isOpen` / `onClose`,若要显示/隐藏,请在父组件中条件渲染。同时它不会显示工具栏上的关闭按钮。
|
|
396
453
|
|
|
@@ -510,7 +567,7 @@ const files = [
|
|
|
510
567
|
#### 电子书
|
|
511
568
|
- **EPUB**: `application/epub+zip` (.epub)
|
|
512
569
|
|
|
513
|
-
## 🌐 国际化(i18n)
|
|
570
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f310.svg" width="20" height="20" alt="🌐" /> 国际化(i18n)
|
|
514
571
|
|
|
515
572
|
内置中文(默认)和英文,零外部依赖。
|
|
516
573
|
|
|
@@ -528,7 +585,353 @@ const files = [
|
|
|
528
585
|
|
|
529
586
|
在自定义渲染器中可通过 `useTranslator()` hook 获取翻译函数。
|
|
530
587
|
|
|
531
|
-
##
|
|
588
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f9e9.svg" width="20" height="20" alt="🧩" /> 自定义渲染器
|
|
589
|
+
|
|
590
|
+
本库支持自定义渲染器以处理内置不支持的文件类型。自定义渲染器可以可选地提供工具栏配置并集成到本库的架构中。
|
|
591
|
+
|
|
592
|
+
### 事件驱动的工具栏更新
|
|
593
|
+
|
|
594
|
+
自定义渲染器可以通过事件驱动机制实现实时工具栏更新:
|
|
595
|
+
|
|
596
|
+
**优势:**
|
|
597
|
+
- **实时更新**:工具栏立即反映状态变化
|
|
598
|
+
- **更好的性能**:无轮询开销或不必要的重新渲染
|
|
599
|
+
- **类型安全**:完整的 TypeScript 接口支持
|
|
600
|
+
|
|
601
|
+
**实现方式:**
|
|
602
|
+
|
|
603
|
+
```tsx
|
|
604
|
+
import { forwardRef, useImperativeHandle, useState, useEffect, useMemo, useCallback } from 'react';
|
|
605
|
+
import { ToolbarEventEmitter } from '@eternalheart/react-file-preview';
|
|
606
|
+
import type { RendererHandle, ToolbarGroup } from '@eternalheart/react-file-preview';
|
|
607
|
+
|
|
608
|
+
interface CustomRendererProps {
|
|
609
|
+
url: string;
|
|
610
|
+
onPageChange?: (current: number, total: number) => void;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
export const CustomRenderer = forwardRef<RendererHandle, CustomRendererProps>((props, ref) => {
|
|
614
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
615
|
+
const [totalPages, setTotalPages] = useState(10);
|
|
616
|
+
const emitter = useMemo(() => new ToolbarEventEmitter(), []);
|
|
617
|
+
|
|
618
|
+
// 状态变化时通知工具栏
|
|
619
|
+
useEffect(() => {
|
|
620
|
+
emitter.notify();
|
|
621
|
+
props.onPageChange?.(currentPage, totalPages);
|
|
622
|
+
}, [currentPage, totalPages, emitter, props]);
|
|
623
|
+
|
|
624
|
+
const getToolbarGroups = useCallback((): ToolbarGroup[] => [
|
|
625
|
+
{
|
|
626
|
+
items: [
|
|
627
|
+
{
|
|
628
|
+
type: 'button',
|
|
629
|
+
icon: <ChevronLeft className="w-4 h-4" />,
|
|
630
|
+
tooltip: '上一页',
|
|
631
|
+
action: () => setCurrentPage(p => Math.max(1, p - 1)),
|
|
632
|
+
disabled: currentPage <= 1
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
type: 'text',
|
|
636
|
+
content: `${currentPage} / ${totalPages}`,
|
|
637
|
+
minWidth: '4rem'
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
type: 'button',
|
|
641
|
+
icon: <ChevronRight className="w-4 h-4" />,
|
|
642
|
+
tooltip: '下一页',
|
|
643
|
+
action: () => setCurrentPage(p => Math.min(totalPages, p + 1)),
|
|
644
|
+
disabled: currentPage >= totalPages
|
|
645
|
+
}
|
|
646
|
+
]
|
|
647
|
+
}
|
|
648
|
+
], [currentPage, totalPages]);
|
|
649
|
+
|
|
650
|
+
useImperativeHandle(ref, () => ({
|
|
651
|
+
getToolbarGroups,
|
|
652
|
+
onToolbarChange: (listener) => emitter.subscribe(listener)
|
|
653
|
+
}), [getToolbarGroups, emitter]);
|
|
654
|
+
|
|
655
|
+
return <div>你的自定义渲染器 UI</div>;
|
|
656
|
+
});
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
**主组件使用:**
|
|
660
|
+
|
|
661
|
+
```tsx
|
|
662
|
+
import { CustomRenderer } from './CustomRenderer';
|
|
663
|
+
|
|
664
|
+
<FilePreviewModal
|
|
665
|
+
files={files}
|
|
666
|
+
customRenderers={[
|
|
667
|
+
{
|
|
668
|
+
test: (file) => file.type === 'application/custom',
|
|
669
|
+
component: CustomRenderer
|
|
670
|
+
}
|
|
671
|
+
]}
|
|
672
|
+
/>
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
主组件会自动检测 `onToolbarChange` 并订阅事件。如果未实现,则回退到轮询以保持向后兼容。
|
|
676
|
+
|
|
677
|
+
### Renderer 懒加载
|
|
678
|
+
|
|
679
|
+
所有内置渲染器通过 `React.lazy` 实现代码分割,以最小化主包体积并提升初始加载性能。
|
|
680
|
+
|
|
681
|
+
**架构:**
|
|
682
|
+
|
|
683
|
+
- **注册**:渲染器在 `src/renderers/lazy.tsx` 中注册,使用 named export 并通过 `React.lazy` 包装
|
|
684
|
+
- **加载**:每个渲染器是独立的 chunk,按需加载
|
|
685
|
+
- **回退**:`<Suspense>` 配合 `<RendererLoading />` 处理加载状态
|
|
686
|
+
|
|
687
|
+
**打包体积影响:**
|
|
688
|
+
|
|
689
|
+
- 主入口:gzip ≤ 80 KB(CI 强制约束)
|
|
690
|
+
- 每个渲染器:独立异步 chunk
|
|
691
|
+
- 整个库:gzip ≤ 800 KB(所有渲染器合计)
|
|
692
|
+
|
|
693
|
+
**实现示例:**
|
|
694
|
+
|
|
695
|
+
```tsx
|
|
696
|
+
// src/renderers/lazy.tsx
|
|
697
|
+
import { lazy } from 'react';
|
|
698
|
+
import type { CustomRenderer as CustomRendererImpl } from './Custom';
|
|
699
|
+
|
|
700
|
+
export const CustomRenderer: Lazy<typeof CustomRendererImpl> = lazy(() =>
|
|
701
|
+
import('./Custom').then((m) => ({ default: m.CustomRenderer }))
|
|
702
|
+
);
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
```tsx
|
|
706
|
+
// src/FilePreviewContent.tsx
|
|
707
|
+
import { CustomRenderer } from './renderers/lazy'; // ✅ 懒加载导入
|
|
708
|
+
// 禁止: import { CustomRenderer } from './renderers/Custom'; // ❌ 直接导入会破坏代码分割
|
|
709
|
+
|
|
710
|
+
<Suspense fallback={<RendererLoading />}>
|
|
711
|
+
{fileType === 'custom' && <CustomRenderer ref={rendererRef} url={currentFile.url} />}
|
|
712
|
+
</Suspense>
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
**用于自定义渲染器:**
|
|
716
|
+
|
|
717
|
+
如果你希望自定义渲染器也享受代码分割,可以使用相同的模式:
|
|
718
|
+
|
|
719
|
+
```tsx
|
|
720
|
+
import { lazy, Suspense } from 'react';
|
|
721
|
+
|
|
722
|
+
const MyCustomRenderer = lazy(() => import('./MyCustomRenderer'));
|
|
723
|
+
|
|
724
|
+
<FilePreviewModal
|
|
725
|
+
files={files}
|
|
726
|
+
customRenderers={[
|
|
727
|
+
{
|
|
728
|
+
test: (file) => file.type === 'application/custom',
|
|
729
|
+
component: (props) => (
|
|
730
|
+
<Suspense fallback={<div>加载中...</div>}>
|
|
731
|
+
<MyCustomRenderer {...props} />
|
|
732
|
+
</Suspense>
|
|
733
|
+
)
|
|
734
|
+
}
|
|
735
|
+
]}
|
|
736
|
+
/>
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
### i18n 集成
|
|
740
|
+
|
|
741
|
+
自定义渲染器可以通过 `useTranslator()` hook 访问本库的 i18n 系统,实现一致的多语言支持。
|
|
742
|
+
|
|
743
|
+
**架构:**
|
|
744
|
+
|
|
745
|
+
- **字典源**:`file-preview-core/src/i18n/messages/`(zh-CN.ts、en-US.ts)
|
|
746
|
+
- **禁止硬编码**:所有用户可见文案必须使用翻译 key
|
|
747
|
+
- **自动切换语言**:跟随 `FilePreviewModal` 的 `locale` prop
|
|
748
|
+
|
|
749
|
+
**在自定义渲染器中使用:**
|
|
750
|
+
|
|
751
|
+
```tsx
|
|
752
|
+
import { useTranslator } from '@eternalheart/react-file-preview';
|
|
753
|
+
|
|
754
|
+
export const CustomRenderer = forwardRef<RendererHandle, Props>((props, ref) => {
|
|
755
|
+
const t = useTranslator();
|
|
756
|
+
const [error, setError] = useState<string | null>(null);
|
|
757
|
+
|
|
758
|
+
if (error) {
|
|
759
|
+
return (
|
|
760
|
+
<div className="rfp-text-fg-primary">
|
|
761
|
+
{t('custom.load_failed')}: {error}
|
|
762
|
+
</div>
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
return (
|
|
767
|
+
<div>
|
|
768
|
+
<button>{t('common.download')}</button>
|
|
769
|
+
<span>{t('custom.loading')}</span>
|
|
770
|
+
</div>
|
|
771
|
+
);
|
|
772
|
+
});
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
**新增自定义翻译键:**
|
|
776
|
+
|
|
777
|
+
对于自定义渲染器,通过 `messages` prop 扩展翻译(不要修改 `node_modules` 中的源文件):
|
|
778
|
+
|
|
779
|
+
```tsx
|
|
780
|
+
<FilePreviewModal
|
|
781
|
+
files={files}
|
|
782
|
+
locale="en-US"
|
|
783
|
+
messages={{
|
|
784
|
+
'en-US': {
|
|
785
|
+
'custom.load_failed': 'Failed to load custom file',
|
|
786
|
+
'custom.file_size': 'File size: {size} KB'
|
|
787
|
+
},
|
|
788
|
+
'zh-CN': {
|
|
789
|
+
'custom.load_failed': '自定义文件加载失败',
|
|
790
|
+
'custom.file_size': '文件大小: {size} KB'
|
|
791
|
+
}
|
|
792
|
+
}}
|
|
793
|
+
customRenderers={[...]}
|
|
794
|
+
/>
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
**指南:**
|
|
798
|
+
- 使用 `<scope>.<snake_name>` 格式(如 `custom.load_failed`、`custom.parse_error`)
|
|
799
|
+
- 为所有启用的语言(`zh-CN` 和 `en-US`)提供翻译
|
|
800
|
+
- 已有通用 key:`common.loading`、`common.download`、`common.close`、`toolbar.*`
|
|
801
|
+
|
|
802
|
+
**参数化翻译:**
|
|
803
|
+
|
|
804
|
+
```tsx
|
|
805
|
+
// 字典: 'custom.file_size': '文件大小: {size} KB'
|
|
806
|
+
t('custom.file_size', { size: 1024 }) // → "文件大小: 1024 KB"
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
**工具栏集成:**
|
|
810
|
+
|
|
811
|
+
工具栏项也应使用翻译字符串:
|
|
812
|
+
|
|
813
|
+
```tsx
|
|
814
|
+
const getToolbarGroups = useCallback((): ToolbarGroup[] => [
|
|
815
|
+
{
|
|
816
|
+
items: [
|
|
817
|
+
{
|
|
818
|
+
type: 'button',
|
|
819
|
+
icon: <Download className="rfp-w-4 rfp-h-4" />,
|
|
820
|
+
tooltip: t('common.download'), // ✅ 已翻译
|
|
821
|
+
action: handleDownload
|
|
822
|
+
}
|
|
823
|
+
]
|
|
824
|
+
}
|
|
825
|
+
], [t]);
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
### 主题适配
|
|
829
|
+
|
|
830
|
+
自定义渲染器必须使用语义化颜色 token 以支持本库的 `'auto' | 'dark' | 'light'` 主题系统。
|
|
831
|
+
|
|
832
|
+
**语义化 Token 系统:**
|
|
833
|
+
|
|
834
|
+
所有颜色定义为 CSS 变量(`--fp-*`),通过 Tailwind 类暴露,前缀为 `rfp-`:
|
|
835
|
+
|
|
836
|
+
| 用途 | 类名 | 说明 |
|
|
837
|
+
|------|------|------|
|
|
838
|
+
| **文字(fg)** | | |
|
|
839
|
+
| 主文本 | `rfp-text-fg-primary` | 最高对比度 |
|
|
840
|
+
| 正文 | `rfp-text-fg-secondary` | 默认文字 |
|
|
841
|
+
| 次要文本 | `rfp-text-fg-tertiary` | 副本、计数器 |
|
|
842
|
+
| 弱化文本 | `rfp-text-fg-muted` | 占位符 |
|
|
843
|
+
| 禁用文本 | `rfp-text-fg-disabled` | 禁用按钮 |
|
|
844
|
+
| **背景(surface)** | | |
|
|
845
|
+
| 表面层 1 | `rfp-bg-surface-1` | 卡片、最弱 |
|
|
846
|
+
| 表面层 2 | `rfp-bg-surface-2` | hover 状态 |
|
|
847
|
+
| 表面层 3 | `rfp-bg-surface-3` | 强调 |
|
|
848
|
+
| 工具栏 | `rfp-bg-surface-toolbar` | 顶部工具栏 |
|
|
849
|
+
| **边框** | | |
|
|
850
|
+
| 弱边框 | `rfp-border-line-weak` | 细线 |
|
|
851
|
+
| 标准边框 | `rfp-border-line` | 默认边框 |
|
|
852
|
+
| 强边框 | `rfp-border-line-strong` | 强调 |
|
|
853
|
+
| **代码** | | |
|
|
854
|
+
| 代码背景 | `rfp-bg-code-bg` | Dark:#1e1e1e / Light:#f6f8fa |
|
|
855
|
+
| 代码文字 | `rfp-text-code-fg` | 跟随主题 |
|
|
856
|
+
| **强调(accent)** | | |
|
|
857
|
+
| 强调背景 | `rfp-bg-accent` | 主按钮 |
|
|
858
|
+
| 强调 hover | `rfp-bg-accent-hover` | hover 状态 |
|
|
859
|
+
|
|
860
|
+
**✅ 正确用法:**
|
|
861
|
+
|
|
862
|
+
```tsx
|
|
863
|
+
export const CustomRenderer = forwardRef<RendererHandle, Props>((props, ref) => {
|
|
864
|
+
return (
|
|
865
|
+
<div className="rfp-bg-surface-1 rfp-border rfp-border-line-weak rfp-rounded">
|
|
866
|
+
<h2 className="rfp-text-fg-primary rfp-text-lg">标题</h2>
|
|
867
|
+
<p className="rfp-text-fg-secondary">正文内容</p>
|
|
868
|
+
<button className="rfp-bg-surface-2 hover:rfp-bg-surface-3 rfp-text-fg-primary">
|
|
869
|
+
点击
|
|
870
|
+
</button>
|
|
871
|
+
<pre className="rfp-bg-code-bg rfp-text-code-fg">
|
|
872
|
+
{code}
|
|
873
|
+
</pre>
|
|
874
|
+
</div>
|
|
875
|
+
);
|
|
876
|
+
});
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
**❌ 错误用法(禁止使用):**
|
|
880
|
+
|
|
881
|
+
```tsx
|
|
882
|
+
// ❌ 字面色类 — 会破坏主题切换
|
|
883
|
+
<div className="rfp-text-white/90 rfp-bg-white/10 rfp-border-white/15">
|
|
884
|
+
<div className="rfp-text-gray-700 rfp-bg-gray-100">
|
|
885
|
+
|
|
886
|
+
// ❌ 内联字面色
|
|
887
|
+
<div style={{ color: '#ffffff', background: '#1f2937' }}>
|
|
888
|
+
|
|
889
|
+
// ❌ 硬编码暗色
|
|
890
|
+
<div style={{ background: '#1e1e1e' }}> // 应改用 rfp-bg-code-bg
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
**支持主题的三方库:**
|
|
894
|
+
|
|
895
|
+
对于具有 theme prop 的库(如 `react-syntax-highlighter`),使用 `useResolvedTheme()`:
|
|
896
|
+
|
|
897
|
+
```tsx
|
|
898
|
+
import { useResolvedTheme } from '@eternalheart/react-file-preview';
|
|
899
|
+
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
|
900
|
+
import { vscDarkPlus, vs } from 'react-syntax-highlighter/dist/esm/styles/prism';
|
|
901
|
+
|
|
902
|
+
export const CodeRenderer = forwardRef<RendererHandle, Props>((props, ref) => {
|
|
903
|
+
const resolvedTheme = useResolvedTheme(); // 'dark' | 'light'
|
|
904
|
+
|
|
905
|
+
return (
|
|
906
|
+
<SyntaxHighlighter
|
|
907
|
+
language="javascript"
|
|
908
|
+
style={resolvedTheme === 'light' ? vs : vscDarkPlus}
|
|
909
|
+
>
|
|
910
|
+
{code}
|
|
911
|
+
</SyntaxHighlighter>
|
|
912
|
+
);
|
|
913
|
+
});
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
**测试:**
|
|
917
|
+
|
|
918
|
+
务必在 Light 和 Dark 两个主题下测试你的自定义渲染器:
|
|
919
|
+
|
|
920
|
+
```tsx
|
|
921
|
+
<FilePreviewModal
|
|
922
|
+
files={files}
|
|
923
|
+
theme="light" // 在 'light'、'dark'、'auto' 间切换
|
|
924
|
+
customRenderers={[...]}
|
|
925
|
+
/>
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
验证:
|
|
929
|
+
- 文字在两个主题下都可读(无白底白字或黑底黑字)
|
|
930
|
+
- 边框和分隔线清晰可见
|
|
931
|
+
- hover 状态有足够对比度
|
|
932
|
+
- 代码块跟随主题(不固定为暗色)
|
|
933
|
+
|
|
934
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f3a8.svg" width="20" height="20" alt="🎨" /> 自定义样式
|
|
532
935
|
|
|
533
936
|
组件使用 Tailwind CSS 构建,您可以通过覆盖 CSS 变量来自定义样式:
|
|
534
937
|
|
|
@@ -540,18 +943,18 @@ const files = [
|
|
|
540
943
|
}
|
|
541
944
|
```
|
|
542
945
|
|
|
543
|
-
## ⌨️ 键盘快捷键
|
|
946
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/2328.svg" width="20" height="20" alt="⌨️" /> 键盘快捷键
|
|
544
947
|
|
|
545
948
|
- `ESC` - 关闭预览
|
|
546
949
|
- `←` - 上一个文件
|
|
547
950
|
- `→` - 下一个文件
|
|
548
951
|
- `滚轮` - 缩放图片 (仅图片预览)
|
|
549
952
|
|
|
550
|
-
## 📚 文档
|
|
953
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f4da.svg" width="20" height="20" alt="📚" /> 文档
|
|
551
954
|
|
|
552
955
|
- [在线演示](https://wh131462.github.io/file-preview) - 在线 Demo
|
|
553
956
|
|
|
554
|
-
## 🤖 Context7 支持
|
|
957
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f916.svg" width="20" height="20" alt="🤖" /> Context7 支持
|
|
555
958
|
|
|
556
959
|
本项目支持 [Context7](https://context7.com) MCP Server。如果你正在使用 AI 编程助手(如 Claude Code、Cursor 等),可以配置 Context7 MCP Server 来获取 `@eternalheart/react-file-preview` 的最新文档和代码示例,从而获得更好的 AI 辅助开发体验。
|
|
557
960
|
|
|
@@ -563,33 +966,7 @@ const files = [
|
|
|
563
966
|
|
|
564
967
|
> 更多关于 Context7 的配置方式,请访问 [Context7 官方文档](https://github.com/upstash/context7)。
|
|
565
968
|
|
|
566
|
-
##
|
|
567
|
-
|
|
568
|
-
### 打包体积
|
|
569
|
-
|
|
570
|
-
- **ESM**: ~54 KB (gzipped: ~12 KB)
|
|
571
|
-
- **CJS**: ~37 KB (gzipped: ~11 KB)
|
|
572
|
-
- **CSS**: ~56 KB (gzipped: ~14 KB)
|
|
573
|
-
|
|
574
|
-
### Peer Dependencies
|
|
575
|
-
|
|
576
|
-
- `react`: ^18.0.0
|
|
577
|
-
- `react-dom`: ^18.0.0
|
|
578
|
-
|
|
579
|
-
### 导出
|
|
580
|
-
|
|
581
|
-
```json
|
|
582
|
-
{
|
|
583
|
-
".": {
|
|
584
|
-
"types": "./lib/index.d.ts",
|
|
585
|
-
"import": "./lib/index.mjs",
|
|
586
|
-
"require": "./lib/index.cjs"
|
|
587
|
-
},
|
|
588
|
-
"./style.css": "./lib/index.css"
|
|
589
|
-
}
|
|
590
|
-
```
|
|
591
|
-
|
|
592
|
-
## 🛠️ 开发
|
|
969
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f6e0.svg" width="20" height="20" alt="🛠️" /> 开发
|
|
593
970
|
|
|
594
971
|
### 库开发
|
|
595
972
|
|
|
@@ -627,15 +1004,15 @@ react-file-preview/
|
|
|
627
1004
|
└── vite.config.lib.ts # 库构建配置
|
|
628
1005
|
```
|
|
629
1006
|
|
|
630
|
-
## 📄 许可证
|
|
1007
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f4c4.svg" width="20" height="20" alt="📄" /> 许可证
|
|
631
1008
|
|
|
632
1009
|
[MIT](./LICENSE) © [EternalHeart](https://github.com/wh131462)
|
|
633
1010
|
|
|
634
|
-
## 🤝 贡献
|
|
1011
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f91d.svg" width="20" height="20" alt="🤝" /> 贡献
|
|
635
1012
|
|
|
636
1013
|
欢迎提交 Issue 和 Pull Request!
|
|
637
1014
|
|
|
638
|
-
## 🔗 相关链接
|
|
1015
|
+
## <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/1f517.svg" width="20" height="20" alt="🔗" /> 相关链接
|
|
639
1016
|
|
|
640
1017
|
- [GitHub](https://github.com/wh131462/file-preview)
|
|
641
1018
|
- [npm](https://www.npmjs.com/package/@eternalheart/react-file-preview)
|
|
@@ -20,6 +20,7 @@ export interface FilePreviewContentProps {
|
|
|
20
20
|
shouldFetchAsBlob?: ShouldFetchAsBlob;
|
|
21
21
|
onDownload?: (file: PreviewFile) => void;
|
|
22
22
|
onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
|
|
23
|
+
showDownload?: boolean;
|
|
23
24
|
}
|
|
24
25
|
export declare const FilePreviewContent: React.FC<FilePreviewContentProps>;
|
|
25
26
|
//# sourceMappingURL=FilePreviewContent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilePreviewContent.d.ts","sourceRoot":"","sources":["../src/FilePreviewContent.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"FilePreviewContent.d.ts","sourceRoot":"","sources":["../src/FilePreviewContent.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,EAAiC,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAmB,KAAK,KAAK,EAA2B,MAAM,iCAAiC,CAAC;AAGlK,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAyB,MAAM,SAAS,CAAC;AACvF,OAAO,KAAK,EAAE,0BAA0B,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAetJ,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAC5D,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC;IAC7D,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAWhE,CAAC"}
|
|
@@ -31,6 +31,8 @@ interface FilePreviewEmbedProps {
|
|
|
31
31
|
onDownload?: (file: PreviewFile) => void | Promise<void>;
|
|
32
32
|
/** 关闭回调:传入后工具栏显示关闭按钮 */
|
|
33
33
|
onClose?: () => void;
|
|
34
|
+
/** 是否显示下载按钮,默认 true */
|
|
35
|
+
showDownload?: boolean;
|
|
34
36
|
}
|
|
35
37
|
export declare const FilePreviewEmbed: React.FC<FilePreviewEmbedProps>;
|
|
36
38
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilePreviewEmbed.d.ts","sourceRoot":"","sources":["../src/FilePreviewEmbed.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAE/K,UAAU,qBAAqB;IAC7B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,oBAAoB;IACpB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAC5D,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"FilePreviewEmbed.d.ts","sourceRoot":"","sources":["../src/FilePreviewEmbed.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAE/K,UAAU,qBAAqB;IAC7B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,oBAAoB;IACpB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAC5D,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,uBAAuB;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAiE5D,CAAC"}
|
|
@@ -25,6 +25,8 @@ interface FilePreviewModalProps {
|
|
|
25
25
|
shouldFetchAsBlob?: ShouldFetchAsBlob;
|
|
26
26
|
/** 自定义下载回调;不传时库内默认通过 fetcher 拉 Blob 触发下载 */
|
|
27
27
|
onDownload?: (file: PreviewFile) => void | Promise<void>;
|
|
28
|
+
/** 是否显示下载按钮,默认 true */
|
|
29
|
+
showDownload?: boolean;
|
|
28
30
|
}
|
|
29
31
|
export declare const FilePreviewModal: React.FC<FilePreviewModalProps>;
|
|
30
32
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilePreviewModal.d.ts","sourceRoot":"","sources":["../src/FilePreviewModal.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAE/K,UAAU,qBAAqB;IAC7B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,oBAAoB;IACpB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAC5D,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"FilePreviewModal.d.ts","sourceRoot":"","sources":["../src/FilePreviewModal.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAE/K,UAAU,qBAAqB;IAC7B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,oBAAoB;IACpB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAC5D,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,uBAAuB;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAkG5D,CAAC"}
|