@cherrystudio/file-preview 0.0.0-stage → 0.1.1
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/LICENSE +661 -0
- package/README.md +247 -2
- package/dist/Combination-BLg27FvF.js +1044 -0
- package/dist/EchartsChartRenderer-e2b5JysX.js +39859 -0
- package/dist/FilePreviewTooLarge-DkHa6toZ.js +27 -0
- package/dist/ImageFilePreview-Be0jdBJ-.js +2170 -0
- package/dist/PdfFilePreview-D3Ie0_mm.js +29747 -0
- package/dist/PowerPointFilePreview-BLfF0zcm.js +58032 -0
- package/dist/SpreadsheetFilePreview-DJdoyeis.js +3217 -0
- package/dist/WordFilePreview-DSqt7Uq2.js +4137 -0
- package/dist/assets/cmaps/78-EUC-H.bcmap +0 -0
- package/dist/assets/cmaps/78-EUC-V.bcmap +0 -0
- package/dist/assets/cmaps/78-H.bcmap +0 -0
- package/dist/assets/cmaps/78-RKSJ-H.bcmap +0 -0
- package/dist/assets/cmaps/78-RKSJ-V.bcmap +0 -0
- package/dist/assets/cmaps/78-V.bcmap +0 -0
- package/dist/assets/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/dist/assets/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/dist/assets/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/dist/assets/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/dist/assets/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/dist/assets/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/dist/assets/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/dist/assets/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/dist/assets/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/dist/assets/cmaps/Add-H.bcmap +0 -0
- package/dist/assets/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/dist/assets/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/dist/assets/cmaps/Add-V.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/dist/assets/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/dist/assets/cmaps/B5-H.bcmap +0 -0
- package/dist/assets/cmaps/B5-V.bcmap +0 -0
- package/dist/assets/cmaps/B5pc-H.bcmap +0 -0
- package/dist/assets/cmaps/B5pc-V.bcmap +0 -0
- package/dist/assets/cmaps/CNS-EUC-H.bcmap +0 -0
- package/dist/assets/cmaps/CNS-EUC-V.bcmap +0 -0
- package/dist/assets/cmaps/CNS1-H.bcmap +0 -0
- package/dist/assets/cmaps/CNS1-V.bcmap +0 -0
- package/dist/assets/cmaps/CNS2-H.bcmap +0 -0
- package/dist/assets/cmaps/CNS2-V.bcmap +3 -0
- package/dist/assets/cmaps/ETHK-B5-H.bcmap +0 -0
- package/dist/assets/cmaps/ETHK-B5-V.bcmap +0 -0
- package/dist/assets/cmaps/ETen-B5-H.bcmap +0 -0
- package/dist/assets/cmaps/ETen-B5-V.bcmap +0 -0
- package/dist/assets/cmaps/ETenms-B5-H.bcmap +3 -0
- package/dist/assets/cmaps/ETenms-B5-V.bcmap +0 -0
- package/dist/assets/cmaps/EUC-H.bcmap +0 -0
- package/dist/assets/cmaps/EUC-V.bcmap +0 -0
- package/dist/assets/cmaps/Ext-H.bcmap +0 -0
- package/dist/assets/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/dist/assets/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/dist/assets/cmaps/Ext-V.bcmap +0 -0
- package/dist/assets/cmaps/GB-EUC-H.bcmap +0 -0
- package/dist/assets/cmaps/GB-EUC-V.bcmap +0 -0
- package/dist/assets/cmaps/GB-H.bcmap +4 -0
- package/dist/assets/cmaps/GB-V.bcmap +0 -0
- package/dist/assets/cmaps/GBK-EUC-H.bcmap +0 -0
- package/dist/assets/cmaps/GBK-EUC-V.bcmap +0 -0
- package/dist/assets/cmaps/GBK2K-H.bcmap +0 -0
- package/dist/assets/cmaps/GBK2K-V.bcmap +0 -0
- package/dist/assets/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/dist/assets/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/dist/assets/cmaps/GBT-EUC-H.bcmap +0 -0
- package/dist/assets/cmaps/GBT-EUC-V.bcmap +0 -0
- package/dist/assets/cmaps/GBT-H.bcmap +0 -0
- package/dist/assets/cmaps/GBT-V.bcmap +0 -0
- package/dist/assets/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/dist/assets/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/dist/assets/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/dist/assets/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/dist/assets/cmaps/H.bcmap +0 -0
- package/dist/assets/cmaps/HKdla-B5-H.bcmap +0 -0
- package/dist/assets/cmaps/HKdla-B5-V.bcmap +0 -0
- package/dist/assets/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/dist/assets/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/dist/assets/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/dist/assets/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/dist/assets/cmaps/HKm314-B5-H.bcmap +0 -0
- package/dist/assets/cmaps/HKm314-B5-V.bcmap +0 -0
- package/dist/assets/cmaps/HKm471-B5-H.bcmap +0 -0
- package/dist/assets/cmaps/HKm471-B5-V.bcmap +0 -0
- package/dist/assets/cmaps/HKscs-B5-H.bcmap +0 -0
- package/dist/assets/cmaps/HKscs-B5-V.bcmap +0 -0
- package/dist/assets/cmaps/Hankaku.bcmap +0 -0
- package/dist/assets/cmaps/Hiragana.bcmap +0 -0
- package/dist/assets/cmaps/KSC-EUC-H.bcmap +0 -0
- package/dist/assets/cmaps/KSC-EUC-V.bcmap +0 -0
- package/dist/assets/cmaps/KSC-H.bcmap +0 -0
- package/dist/assets/cmaps/KSC-Johab-H.bcmap +0 -0
- package/dist/assets/cmaps/KSC-Johab-V.bcmap +0 -0
- package/dist/assets/cmaps/KSC-V.bcmap +0 -0
- package/dist/assets/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/dist/assets/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/dist/assets/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/dist/assets/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/dist/assets/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/dist/assets/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/dist/assets/cmaps/Katakana.bcmap +0 -0
- package/dist/assets/cmaps/LICENSE +36 -0
- package/dist/assets/cmaps/NWP-H.bcmap +0 -0
- package/dist/assets/cmaps/NWP-V.bcmap +0 -0
- package/dist/assets/cmaps/RKSJ-H.bcmap +0 -0
- package/dist/assets/cmaps/RKSJ-V.bcmap +0 -0
- package/dist/assets/cmaps/Roman.bcmap +0 -0
- package/dist/assets/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/dist/assets/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/dist/assets/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/dist/assets/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/dist/assets/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/dist/assets/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/dist/assets/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/dist/assets/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/dist/assets/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/dist/assets/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/dist/assets/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/dist/assets/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/dist/assets/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/dist/assets/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/dist/assets/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/dist/assets/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/dist/assets/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/dist/assets/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/dist/assets/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/dist/assets/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/dist/assets/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/dist/assets/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/dist/assets/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/dist/assets/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/dist/assets/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/dist/assets/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/dist/assets/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/dist/assets/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/dist/assets/cmaps/V.bcmap +0 -0
- package/dist/assets/cmaps/WP-Symbol.bcmap +0 -0
- package/dist/assets/pdf.worker.js +77187 -0
- package/dist/assets/standard_fonts/FoxitDingbats.pfb +0 -0
- package/dist/assets/standard_fonts/FoxitFixed.pfb +0 -0
- package/dist/assets/standard_fonts/FoxitFixedBold.pfb +0 -0
- package/dist/assets/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- package/dist/assets/standard_fonts/FoxitFixedItalic.pfb +0 -0
- package/dist/assets/standard_fonts/FoxitSerif.pfb +0 -0
- package/dist/assets/standard_fonts/FoxitSerifBold.pfb +0 -0
- package/dist/assets/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- package/dist/assets/standard_fonts/FoxitSerifItalic.pfb +0 -0
- package/dist/assets/standard_fonts/FoxitSymbol.pfb +0 -0
- package/dist/assets/standard_fonts/LICENSE_FOXIT +27 -0
- package/dist/assets/standard_fonts/LICENSE_LIBERATION +102 -0
- package/dist/assets/standard_fonts/LiberationSans-Bold.ttf +0 -0
- package/dist/assets/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/dist/assets/standard_fonts/LiberationSans-Italic.ttf +0 -0
- package/dist/assets/standard_fonts/LiberationSans-Regular.ttf +0 -0
- package/dist/assets/xlsx.worker.js +61444 -0
- package/dist/core.d.ts +2 -0
- package/dist/core.js +3 -0
- package/dist/documentAnchor-J7GGLU15.js +69 -0
- package/dist/imageFilePreviewPlugin-CYLM2bwR.js +29 -0
- package/dist/jszip.min-uwqlc4KL.js +3108 -0
- package/dist/react.d.ts +105 -0
- package/dist/react.js +3114 -0
- package/dist/rolldown-runtime-B-lAHAz2.js +37 -0
- package/dist/rotate-ccw-YWx7RzY9.js +36 -0
- package/dist/selection-CQPD5a6C.js +47 -0
- package/dist/source-DjjzeN4t.d.ts +58 -0
- package/dist/source-Rx3etU3y.js +28 -0
- package/dist/styles.css +8778 -0
- package/dist/styles.js +0 -0
- package/dist/touchPinch-C4fl-9fg.js +34 -0
- package/dist/useTranslation-DMhY277o.js +7056 -0
- package/dist/zoom-out-DLOQGt1e.js +66 -0
- package/package.json +69 -3
package/README.md
CHANGED
|
@@ -1,3 +1,248 @@
|
|
|
1
|
-
#
|
|
1
|
+
# File preview
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Portable React DOM previews for PDF, DOCX, PPTX, XLSX and images (including SVG).
|
|
4
|
+
The package owns rendering, controls, structural selections, workers and translations.
|
|
5
|
+
Hosts own file access, permissions, navigation, external opening and logging.
|
|
6
|
+
HTML, Markdown and source-code previews remain in the desktop application.
|
|
7
|
+
|
|
8
|
+
Install a published version alongside React 19 and React DOM 19:
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
pnpm add @cherrystudio/file-preview react@^19 react-dom@^19
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The package can be installed independently of the Cherry Studio workspace. It bundles
|
|
15
|
+
its rendering engines and UI components; consumers do not need workspace packages or
|
|
16
|
+
dependency patches.
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import type { PreviewSource } from '@cherrystudio/file-preview/core'
|
|
20
|
+
import { Preview } from '@cherrystudio/file-preview/react'
|
|
21
|
+
import '@cherrystudio/file-preview/styles.css'
|
|
22
|
+
|
|
23
|
+
function FilePanel({ source }: { source: PreviewSource }) {
|
|
24
|
+
return <Preview source={source} locale="zh-cn" />
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Give the parent a defined height. Each source opens an independent `PreviewDocument`.
|
|
29
|
+
The preview closes it after failure, replacement, refresh or unmount, including a late
|
|
30
|
+
open that completes after cancellation. A document's size and revision stay fixed;
|
|
31
|
+
its reader must reject version changes, short reads and reads after close. Close must
|
|
32
|
+
be idempotent. Range offsets and lengths are safe integers within the document size.
|
|
33
|
+
DOCX, PPTX, XLSX and images request the whole document as one `[0, size)` range, so
|
|
34
|
+
a host can serve it with a single read; PDF requests partial ranges.
|
|
35
|
+
Readers should honor abort signals where their transport supports cancellation. The
|
|
36
|
+
package discards a read result after cancellation; it cannot stop host I/O that has
|
|
37
|
+
already started or interrupt synchronous engine parsing. Returned byte views remain
|
|
38
|
+
host-owned: the package does not mutate or detach them. XLSX copies the requested
|
|
39
|
+
bytes before transferring its own buffer to the parsing worker.
|
|
40
|
+
|
|
41
|
+
`refreshKey` is an optional number. Changing it closes the current document and opens
|
|
42
|
+
a fresh session, including after a failure. `header` accepts host-owned navigation
|
|
43
|
+
and file-identity content for the fixed top row; the format toolbar shares that row.
|
|
44
|
+
Without a header, format controls render above the document. Give `source` and
|
|
45
|
+
`resources` stable references so layout, locale and theme updates retain the session.
|
|
46
|
+
|
|
47
|
+
`onSelection` reports `{ sourceId, revision, anchor, excerpt }`, or `null` when a
|
|
48
|
+
pick is cleared. Anchors use worksheet A1 ranges, body paragraph ordinals, PDF pages
|
|
49
|
+
and PPTX slides. The host owns held selections across refreshes and file switches.
|
|
50
|
+
`revision` is opaque to the package and only distinguishes document versions. Hosts
|
|
51
|
+
map selections back to their own file identity; the package never parses it.
|
|
52
|
+
Excerpts use NFC normalization, collapse the shared JavaScript/Python whitespace set
|
|
53
|
+
to single spaces, and trim both ends. They are limited to 2000 UTF-16 code units,
|
|
54
|
+
without splitting a surrogate pair; an empty normalized excerpt produces `null`.
|
|
55
|
+
Callback references are stabilized inside `Preview`, so inline callbacks do not
|
|
56
|
+
reopen documents or repeat a selection notification merely because the host rendered.
|
|
57
|
+
|
|
58
|
+
Recognized `source.mediaType` values take precedence over the filename extension;
|
|
59
|
+
missing or unrecognized media types fall back to the extension. `supportsPreview`
|
|
60
|
+
and `canSelectPreview` accept the same optional media type as their second argument.
|
|
61
|
+
|
|
62
|
+
`onDiagnostic` is the logging channel for engine warnings and errors. A terminal
|
|
63
|
+
failure emits one diagnostic and calls `onError` once for that session; `onError`
|
|
64
|
+
notifies host state and should not log the same error again. Expected `too_large`
|
|
65
|
+
failures are warnings. Non-terminal problems, such as a failed PPTX slide or PDF
|
|
66
|
+
outline navigation, emit diagnostics while the rest of the document remains usable.
|
|
67
|
+
|
|
68
|
+
`onError` receives a `PreviewError` with a stable `code` and an optional underlying
|
|
69
|
+
`cause`. Error messages are diagnostic details, not localized UI copy.
|
|
70
|
+
|
|
71
|
+
| Code | Meaning |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| `invalid_range` | Invalid document size, offset or read length |
|
|
74
|
+
| `short_read` | The reader returned fewer or more bytes than requested |
|
|
75
|
+
| `source_changed` | The host detected a revision change during reading |
|
|
76
|
+
| `closed` | A read was attempted after the host document closed |
|
|
77
|
+
| `too_large` | A preview source or PDF range exceeded its safety limit |
|
|
78
|
+
| `load_error` | Opening, parsing or rendering failed for another reason |
|
|
79
|
+
|
|
80
|
+
`onRequestOpen` delegates external opening to the host only after the user activates
|
|
81
|
+
an open button. Its reason is `unsupported` for unrecognized formats or `too_large`
|
|
82
|
+
for size-limit fallbacks; rendering or refreshing an unsupported source never opens
|
|
83
|
+
another application automatically. DOCX/PPTX above 25 MiB, XLSX above 20 MiB and
|
|
84
|
+
images above 64 MiB show their limits. PDF has a 16 MiB assembled-range cap, without
|
|
85
|
+
a whole-document size limit. These states offer an external-open button when the
|
|
86
|
+
host supplies the callback.
|
|
87
|
+
`resources.baseUrl` optionally overrides the bundled worker/font/CMap directory;
|
|
88
|
+
include a trailing slash. Relative URLs resolve against the host page.
|
|
89
|
+
`readPdfResource` takes precedence over resource URLs for PDF fonts and CMaps,
|
|
90
|
+
including font substitution. Electron provides it for file-scheme pages.
|
|
91
|
+
PDF workers belong to individual previews and never change pdf.js global options.
|
|
92
|
+
Cleanup awaits the pdf.js loading task's destruction before terminating its worker,
|
|
93
|
+
allowing document fonts to be released. There is no forced teardown timeout: an
|
|
94
|
+
already-unresponsive worker can leave that destruction promise pending.
|
|
95
|
+
Translations use an independent i18next instance with resources for all 13 desktop
|
|
96
|
+
languages; other locales fall back to English.
|
|
97
|
+
|
|
98
|
+
`FilePreviewLayout.Shell` owns the shared header and toolbar placement.
|
|
99
|
+
`FilePreviewLayout`, `FilePreviewToolbar` and its portal provider/host are also used
|
|
100
|
+
by desktop-only formats; `FilePreviewToolbarButton` is available for icon commands.
|
|
101
|
+
The registry is static; formats cannot be registered at runtime.
|
|
102
|
+
|
|
103
|
+
For a bundled web application, copy the package's `dist/assets/` directory to a
|
|
104
|
+
public directory (for example, Vite's `public/preview-assets/`) and point the preview
|
|
105
|
+
at its deployed URL:
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
const resources = { baseUrl: '/preview-assets/' }
|
|
109
|
+
|
|
110
|
+
<Preview source={source} resources={resources} locale="zh-cn" />
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Keep the workers, `cmaps/` and `standard_fonts/` together. Worker entry URLs must be
|
|
114
|
+
same-origin with the application; CORS permission alone does not allow a cross-origin
|
|
115
|
+
`new Worker()` entry. A cross-origin asset host needs a same-origin worker entry or
|
|
116
|
+
a host-provided `createWorker`. Font and CMap requests separately require the server's
|
|
117
|
+
cross-origin permissions when loaded from another origin.
|
|
118
|
+
When no base URL is provided, the bundler handles the native worker URLs; hosts
|
|
119
|
+
must still deploy the PDF resource directories or provide `readPdfResource`.
|
|
120
|
+
|
|
121
|
+
## WebView and inline hosts
|
|
122
|
+
|
|
123
|
+
A page whose bundle has no URL, such as inline HTML loaded into a mobile WebView, cannot
|
|
124
|
+
resolve the bundled workers or PDF resources. Supply both through `resources`:
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import pdfWorker from '@cherrystudio/file-preview/assets/pdf.worker.js?raw'
|
|
128
|
+
import xlsxWorker from '@cherrystudio/file-preview/assets/xlsx.worker.js?raw'
|
|
129
|
+
|
|
130
|
+
const workerSources = { pdf: pdfWorker, xlsx: xlsxWorker }
|
|
131
|
+
const workerUrls: Partial<Record<'pdf' | 'xlsx', string>> = {}
|
|
132
|
+
const resources = {
|
|
133
|
+
createWorker: (kind: 'pdf' | 'xlsx') => {
|
|
134
|
+
workerUrls[kind] ??= URL.createObjectURL(new Blob([workerSources[kind]], { type: 'text/javascript' }))
|
|
135
|
+
return new Worker(workerUrls[kind], { type: 'module' })
|
|
136
|
+
},
|
|
137
|
+
readPdfResource: (kind: 'cmap' | 'standard_font', name: string) => bridge.readPdfResource(kind, name)
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Cache one object URL per worker kind for the host resource lifetime. After all previews
|
|
142
|
+
using these resources have unmounted and the host disposes this resource set, release
|
|
143
|
+
the URLs with `for (const url of Object.values(workerUrls)) URL.revokeObjectURL(url)`.
|
|
144
|
+
Terminating an individual worker does not revoke its object URL.
|
|
145
|
+
|
|
146
|
+
`createWorker` takes precedence over `baseUrl` for both workers. Each worker file is
|
|
147
|
+
self-contained. Give inline HTML a base URL, such as react-native-webview's
|
|
148
|
+
`source={{ html, baseUrl: 'https://file-preview.local/' }}`: in an opaque `about:blank`
|
|
149
|
+
origin, browsers refuse module workers created from blob URLs. `readPdfResource` serves names from `assets/cmaps/` (without `.bcmap`)
|
|
150
|
+
and `assets/standard_fonts/`.
|
|
151
|
+
|
|
152
|
+
PDF and DOCX zoom with a two-finger pinch, and images pinch-zoom in their viewport.
|
|
153
|
+
PPTX and XLSX zoom through the toolbar. A spreadsheet touch selects a cell on tap, and
|
|
154
|
+
swiping scrolls without selecting. Disable page zoom in the host page
|
|
155
|
+
(`<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">`)
|
|
156
|
+
so a pinch outside these surfaces does not scale the whole preview.
|
|
157
|
+
|
|
158
|
+
### Opt-in host layout and font compatibility
|
|
159
|
+
|
|
160
|
+
All `options` are opt-in. Omitting them preserves desktop rendering: a PDF sidebar,
|
|
161
|
+
DOCX at 100% with its existing font handling, translucent spreadsheet headers, and
|
|
162
|
+
the existing viewport inset. The package does not detect the host platform.
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
<Preview
|
|
166
|
+
source={source}
|
|
167
|
+
resources={resources}
|
|
168
|
+
options={{
|
|
169
|
+
bottomInset: 'content',
|
|
170
|
+
pdf: { outlineLayout: useOverlayOutline ? 'overlay' : 'panel' },
|
|
171
|
+
docx: { initialZoom: 'fit-width', normalizeSymbolBullets: true },
|
|
172
|
+
xlsx: { opaqueHeaders: true }
|
|
173
|
+
}}
|
|
174
|
+
/>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The host chooses `useOverlayOutline` from its actual available width, including
|
|
178
|
+
landscape orientation. Overlay mode covers the preview without shrinking its pages;
|
|
179
|
+
Escape, the close button, the backdrop, and selecting an internal destination dismiss
|
|
180
|
+
it. Explicitly selecting either PDF layout also keeps page-width zoom in sync with
|
|
181
|
+
container resizing; manual zoom is preserved.
|
|
182
|
+
|
|
183
|
+
DOCX `fit-width` includes the document wrapper and widest page, permits scales below
|
|
184
|
+
50%, and never enlarges beyond 100%. It follows container resizing until the user
|
|
185
|
+
zooms using the toolbar or a pinch; Reset resumes fitting. No orientation message is
|
|
186
|
+
needed for DOCX. `normalizeSymbolBullets` is read when opening the document: it maps
|
|
187
|
+
known single-character Symbol/Wingdings bullet markers to Unicode and removes their
|
|
188
|
+
legacy font override. Other fonts, unknown symbols and numbered lists are preserved.
|
|
189
|
+
|
|
190
|
+
`bottomInset: 'content'` adds trailing space inside PDF, DOCX and PPTX document scroll
|
|
191
|
+
containers, in unscaled host CSS pixels. Both PDF outline layouts receive trailing
|
|
192
|
+
scroll space too. XLSX is the fixed-control exception: its sheet tabs, status and zoom
|
|
193
|
+
controls reserve the inset below the whole footer so host overlays cannot cover them.
|
|
194
|
+
The grid does not add a second inset. Other formats retain their existing inset behavior.
|
|
195
|
+
`opaqueHeaders` composites the muted XLSX header color over an opaque version of
|
|
196
|
+
`--background`, including the frozen corner, so cells cannot show through alpha colors.
|
|
197
|
+
|
|
198
|
+
Keep `source` and `resources` references stable during layout, locale and theme updates.
|
|
199
|
+
Changing `options` does not reopen the source. Font compatibility takes effect on the
|
|
200
|
+
next document open or explicit refresh; it does not reparse an open document.
|
|
201
|
+
|
|
202
|
+
## Styling
|
|
203
|
+
|
|
204
|
+
`className` and `style` apply to the preview's single theme root. Internal frames inherit
|
|
205
|
+
its tokens. Add `dark` for the dark theme, and set these custom properties to retheme it.
|
|
206
|
+
Root overrides win over the packaged values, and PDF observes this same root for theme changes.
|
|
207
|
+
|
|
208
|
+
| Property | Used for |
|
|
209
|
+
| --- | --- |
|
|
210
|
+
| `--background`, `--foreground` | Surfaces and text |
|
|
211
|
+
| `--primary` | Picks, focus and active controls |
|
|
212
|
+
| `--muted`, `--muted-foreground` | Secondary surfaces, icons and labels |
|
|
213
|
+
| `--border`, `--border-subtle`, `--ring` | Dividers, outlines and focus rings |
|
|
214
|
+
| `--file-preview-toolbar-button-size` | Toolbar button size, default `1.75rem` |
|
|
215
|
+
| `--file-preview-bottom-inset` | Bottom space; content mode adds document scroll space or protects the fixed XLSX footer |
|
|
216
|
+
|
|
217
|
+
## Building
|
|
218
|
+
|
|
219
|
+
```sh
|
|
220
|
+
pnpm --dir packages/file-preview pack --pack-destination /path/to/artifacts
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
`pack` runs the production build first, so the tarball never carries a stale `dist`.
|
|
224
|
+
|
|
225
|
+
The library build uses Vite to process native worker URLs and Tailwind CSS, plus
|
|
226
|
+
`rolldown-plugin-dts` for declaration bundles. Every third-party library except `zod`
|
|
227
|
+
is bundled, including UI components and the patched docx-preview and pptx-renderer, so they are dev
|
|
228
|
+
dependencies; consumers install only `zod` and the React peers. CSS excludes Tailwind preflight
|
|
229
|
+
and scopes selectors to `.file-preview-root`.
|
|
230
|
+
|
|
231
|
+
## Publishing
|
|
232
|
+
|
|
233
|
+
Versioning and npm publishing use the repository's [Changesets workflow](../../.changeset/README.md).
|
|
234
|
+
The initial changeset promotes `0.1.0-alpha.0` to `0.1.0` in the automated version PR.
|
|
235
|
+
Merging that version PR publishes the package under the `latest` tag. Subsequent
|
|
236
|
+
publishable changes must include a changeset for `@cherrystudio/file-preview`.
|
|
237
|
+
|
|
238
|
+
Both release and snapshot workflows build this package through `pnpm packages:build`.
|
|
239
|
+
The manual snapshot workflow publishes under the `snapshot` tag for integration testing:
|
|
240
|
+
|
|
241
|
+
```sh
|
|
242
|
+
pnpm add @cherrystudio/file-preview@snapshot
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The `prepack` hook rebuilds the package before packing or publishing. The artifact
|
|
246
|
+
contains the JavaScript and declaration entry points, scoped stylesheet, worker scripts,
|
|
247
|
+
PDF CMaps and standard fonts, README and license. Verify the packed artifact in an
|
|
248
|
+
independent consumer before the first release, including worker and PDF resource loading.
|