@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.
Files changed (215) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +247 -2
  3. package/dist/Combination-BLg27FvF.js +1044 -0
  4. package/dist/EchartsChartRenderer-e2b5JysX.js +39859 -0
  5. package/dist/FilePreviewTooLarge-DkHa6toZ.js +27 -0
  6. package/dist/ImageFilePreview-Be0jdBJ-.js +2170 -0
  7. package/dist/PdfFilePreview-D3Ie0_mm.js +29747 -0
  8. package/dist/PowerPointFilePreview-BLfF0zcm.js +58032 -0
  9. package/dist/SpreadsheetFilePreview-DJdoyeis.js +3217 -0
  10. package/dist/WordFilePreview-DSqt7Uq2.js +4137 -0
  11. package/dist/assets/cmaps/78-EUC-H.bcmap +0 -0
  12. package/dist/assets/cmaps/78-EUC-V.bcmap +0 -0
  13. package/dist/assets/cmaps/78-H.bcmap +0 -0
  14. package/dist/assets/cmaps/78-RKSJ-H.bcmap +0 -0
  15. package/dist/assets/cmaps/78-RKSJ-V.bcmap +0 -0
  16. package/dist/assets/cmaps/78-V.bcmap +0 -0
  17. package/dist/assets/cmaps/78ms-RKSJ-H.bcmap +0 -0
  18. package/dist/assets/cmaps/78ms-RKSJ-V.bcmap +0 -0
  19. package/dist/assets/cmaps/83pv-RKSJ-H.bcmap +0 -0
  20. package/dist/assets/cmaps/90ms-RKSJ-H.bcmap +0 -0
  21. package/dist/assets/cmaps/90ms-RKSJ-V.bcmap +0 -0
  22. package/dist/assets/cmaps/90msp-RKSJ-H.bcmap +0 -0
  23. package/dist/assets/cmaps/90msp-RKSJ-V.bcmap +0 -0
  24. package/dist/assets/cmaps/90pv-RKSJ-H.bcmap +0 -0
  25. package/dist/assets/cmaps/90pv-RKSJ-V.bcmap +0 -0
  26. package/dist/assets/cmaps/Add-H.bcmap +0 -0
  27. package/dist/assets/cmaps/Add-RKSJ-H.bcmap +0 -0
  28. package/dist/assets/cmaps/Add-RKSJ-V.bcmap +0 -0
  29. package/dist/assets/cmaps/Add-V.bcmap +0 -0
  30. package/dist/assets/cmaps/Adobe-CNS1-0.bcmap +0 -0
  31. package/dist/assets/cmaps/Adobe-CNS1-1.bcmap +0 -0
  32. package/dist/assets/cmaps/Adobe-CNS1-2.bcmap +0 -0
  33. package/dist/assets/cmaps/Adobe-CNS1-3.bcmap +0 -0
  34. package/dist/assets/cmaps/Adobe-CNS1-4.bcmap +0 -0
  35. package/dist/assets/cmaps/Adobe-CNS1-5.bcmap +0 -0
  36. package/dist/assets/cmaps/Adobe-CNS1-6.bcmap +0 -0
  37. package/dist/assets/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  38. package/dist/assets/cmaps/Adobe-GB1-0.bcmap +0 -0
  39. package/dist/assets/cmaps/Adobe-GB1-1.bcmap +0 -0
  40. package/dist/assets/cmaps/Adobe-GB1-2.bcmap +0 -0
  41. package/dist/assets/cmaps/Adobe-GB1-3.bcmap +0 -0
  42. package/dist/assets/cmaps/Adobe-GB1-4.bcmap +0 -0
  43. package/dist/assets/cmaps/Adobe-GB1-5.bcmap +0 -0
  44. package/dist/assets/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  45. package/dist/assets/cmaps/Adobe-Japan1-0.bcmap +0 -0
  46. package/dist/assets/cmaps/Adobe-Japan1-1.bcmap +0 -0
  47. package/dist/assets/cmaps/Adobe-Japan1-2.bcmap +0 -0
  48. package/dist/assets/cmaps/Adobe-Japan1-3.bcmap +0 -0
  49. package/dist/assets/cmaps/Adobe-Japan1-4.bcmap +0 -0
  50. package/dist/assets/cmaps/Adobe-Japan1-5.bcmap +0 -0
  51. package/dist/assets/cmaps/Adobe-Japan1-6.bcmap +0 -0
  52. package/dist/assets/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  53. package/dist/assets/cmaps/Adobe-Korea1-0.bcmap +0 -0
  54. package/dist/assets/cmaps/Adobe-Korea1-1.bcmap +0 -0
  55. package/dist/assets/cmaps/Adobe-Korea1-2.bcmap +0 -0
  56. package/dist/assets/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  57. package/dist/assets/cmaps/B5-H.bcmap +0 -0
  58. package/dist/assets/cmaps/B5-V.bcmap +0 -0
  59. package/dist/assets/cmaps/B5pc-H.bcmap +0 -0
  60. package/dist/assets/cmaps/B5pc-V.bcmap +0 -0
  61. package/dist/assets/cmaps/CNS-EUC-H.bcmap +0 -0
  62. package/dist/assets/cmaps/CNS-EUC-V.bcmap +0 -0
  63. package/dist/assets/cmaps/CNS1-H.bcmap +0 -0
  64. package/dist/assets/cmaps/CNS1-V.bcmap +0 -0
  65. package/dist/assets/cmaps/CNS2-H.bcmap +0 -0
  66. package/dist/assets/cmaps/CNS2-V.bcmap +3 -0
  67. package/dist/assets/cmaps/ETHK-B5-H.bcmap +0 -0
  68. package/dist/assets/cmaps/ETHK-B5-V.bcmap +0 -0
  69. package/dist/assets/cmaps/ETen-B5-H.bcmap +0 -0
  70. package/dist/assets/cmaps/ETen-B5-V.bcmap +0 -0
  71. package/dist/assets/cmaps/ETenms-B5-H.bcmap +3 -0
  72. package/dist/assets/cmaps/ETenms-B5-V.bcmap +0 -0
  73. package/dist/assets/cmaps/EUC-H.bcmap +0 -0
  74. package/dist/assets/cmaps/EUC-V.bcmap +0 -0
  75. package/dist/assets/cmaps/Ext-H.bcmap +0 -0
  76. package/dist/assets/cmaps/Ext-RKSJ-H.bcmap +0 -0
  77. package/dist/assets/cmaps/Ext-RKSJ-V.bcmap +0 -0
  78. package/dist/assets/cmaps/Ext-V.bcmap +0 -0
  79. package/dist/assets/cmaps/GB-EUC-H.bcmap +0 -0
  80. package/dist/assets/cmaps/GB-EUC-V.bcmap +0 -0
  81. package/dist/assets/cmaps/GB-H.bcmap +4 -0
  82. package/dist/assets/cmaps/GB-V.bcmap +0 -0
  83. package/dist/assets/cmaps/GBK-EUC-H.bcmap +0 -0
  84. package/dist/assets/cmaps/GBK-EUC-V.bcmap +0 -0
  85. package/dist/assets/cmaps/GBK2K-H.bcmap +0 -0
  86. package/dist/assets/cmaps/GBK2K-V.bcmap +0 -0
  87. package/dist/assets/cmaps/GBKp-EUC-H.bcmap +0 -0
  88. package/dist/assets/cmaps/GBKp-EUC-V.bcmap +0 -0
  89. package/dist/assets/cmaps/GBT-EUC-H.bcmap +0 -0
  90. package/dist/assets/cmaps/GBT-EUC-V.bcmap +0 -0
  91. package/dist/assets/cmaps/GBT-H.bcmap +0 -0
  92. package/dist/assets/cmaps/GBT-V.bcmap +0 -0
  93. package/dist/assets/cmaps/GBTpc-EUC-H.bcmap +0 -0
  94. package/dist/assets/cmaps/GBTpc-EUC-V.bcmap +0 -0
  95. package/dist/assets/cmaps/GBpc-EUC-H.bcmap +0 -0
  96. package/dist/assets/cmaps/GBpc-EUC-V.bcmap +0 -0
  97. package/dist/assets/cmaps/H.bcmap +0 -0
  98. package/dist/assets/cmaps/HKdla-B5-H.bcmap +0 -0
  99. package/dist/assets/cmaps/HKdla-B5-V.bcmap +0 -0
  100. package/dist/assets/cmaps/HKdlb-B5-H.bcmap +0 -0
  101. package/dist/assets/cmaps/HKdlb-B5-V.bcmap +0 -0
  102. package/dist/assets/cmaps/HKgccs-B5-H.bcmap +0 -0
  103. package/dist/assets/cmaps/HKgccs-B5-V.bcmap +0 -0
  104. package/dist/assets/cmaps/HKm314-B5-H.bcmap +0 -0
  105. package/dist/assets/cmaps/HKm314-B5-V.bcmap +0 -0
  106. package/dist/assets/cmaps/HKm471-B5-H.bcmap +0 -0
  107. package/dist/assets/cmaps/HKm471-B5-V.bcmap +0 -0
  108. package/dist/assets/cmaps/HKscs-B5-H.bcmap +0 -0
  109. package/dist/assets/cmaps/HKscs-B5-V.bcmap +0 -0
  110. package/dist/assets/cmaps/Hankaku.bcmap +0 -0
  111. package/dist/assets/cmaps/Hiragana.bcmap +0 -0
  112. package/dist/assets/cmaps/KSC-EUC-H.bcmap +0 -0
  113. package/dist/assets/cmaps/KSC-EUC-V.bcmap +0 -0
  114. package/dist/assets/cmaps/KSC-H.bcmap +0 -0
  115. package/dist/assets/cmaps/KSC-Johab-H.bcmap +0 -0
  116. package/dist/assets/cmaps/KSC-Johab-V.bcmap +0 -0
  117. package/dist/assets/cmaps/KSC-V.bcmap +0 -0
  118. package/dist/assets/cmaps/KSCms-UHC-H.bcmap +0 -0
  119. package/dist/assets/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  120. package/dist/assets/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  121. package/dist/assets/cmaps/KSCms-UHC-V.bcmap +0 -0
  122. package/dist/assets/cmaps/KSCpc-EUC-H.bcmap +0 -0
  123. package/dist/assets/cmaps/KSCpc-EUC-V.bcmap +0 -0
  124. package/dist/assets/cmaps/Katakana.bcmap +0 -0
  125. package/dist/assets/cmaps/LICENSE +36 -0
  126. package/dist/assets/cmaps/NWP-H.bcmap +0 -0
  127. package/dist/assets/cmaps/NWP-V.bcmap +0 -0
  128. package/dist/assets/cmaps/RKSJ-H.bcmap +0 -0
  129. package/dist/assets/cmaps/RKSJ-V.bcmap +0 -0
  130. package/dist/assets/cmaps/Roman.bcmap +0 -0
  131. package/dist/assets/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  132. package/dist/assets/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  133. package/dist/assets/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  134. package/dist/assets/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  135. package/dist/assets/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  136. package/dist/assets/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  137. package/dist/assets/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  138. package/dist/assets/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  139. package/dist/assets/cmaps/UniGB-UCS2-H.bcmap +0 -0
  140. package/dist/assets/cmaps/UniGB-UCS2-V.bcmap +0 -0
  141. package/dist/assets/cmaps/UniGB-UTF16-H.bcmap +0 -0
  142. package/dist/assets/cmaps/UniGB-UTF16-V.bcmap +0 -0
  143. package/dist/assets/cmaps/UniGB-UTF32-H.bcmap +0 -0
  144. package/dist/assets/cmaps/UniGB-UTF32-V.bcmap +0 -0
  145. package/dist/assets/cmaps/UniGB-UTF8-H.bcmap +0 -0
  146. package/dist/assets/cmaps/UniGB-UTF8-V.bcmap +0 -0
  147. package/dist/assets/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  148. package/dist/assets/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  149. package/dist/assets/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  150. package/dist/assets/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  151. package/dist/assets/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  152. package/dist/assets/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  153. package/dist/assets/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  154. package/dist/assets/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  155. package/dist/assets/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  156. package/dist/assets/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  157. package/dist/assets/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  158. package/dist/assets/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  159. package/dist/assets/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  160. package/dist/assets/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  161. package/dist/assets/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  162. package/dist/assets/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  163. package/dist/assets/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  164. package/dist/assets/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  165. package/dist/assets/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  166. package/dist/assets/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  167. package/dist/assets/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  168. package/dist/assets/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  169. package/dist/assets/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  170. package/dist/assets/cmaps/UniKS-UCS2-H.bcmap +0 -0
  171. package/dist/assets/cmaps/UniKS-UCS2-V.bcmap +0 -0
  172. package/dist/assets/cmaps/UniKS-UTF16-H.bcmap +0 -0
  173. package/dist/assets/cmaps/UniKS-UTF16-V.bcmap +0 -0
  174. package/dist/assets/cmaps/UniKS-UTF32-H.bcmap +0 -0
  175. package/dist/assets/cmaps/UniKS-UTF32-V.bcmap +0 -0
  176. package/dist/assets/cmaps/UniKS-UTF8-H.bcmap +0 -0
  177. package/dist/assets/cmaps/UniKS-UTF8-V.bcmap +0 -0
  178. package/dist/assets/cmaps/V.bcmap +0 -0
  179. package/dist/assets/cmaps/WP-Symbol.bcmap +0 -0
  180. package/dist/assets/pdf.worker.js +77187 -0
  181. package/dist/assets/standard_fonts/FoxitDingbats.pfb +0 -0
  182. package/dist/assets/standard_fonts/FoxitFixed.pfb +0 -0
  183. package/dist/assets/standard_fonts/FoxitFixedBold.pfb +0 -0
  184. package/dist/assets/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  185. package/dist/assets/standard_fonts/FoxitFixedItalic.pfb +0 -0
  186. package/dist/assets/standard_fonts/FoxitSerif.pfb +0 -0
  187. package/dist/assets/standard_fonts/FoxitSerifBold.pfb +0 -0
  188. package/dist/assets/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  189. package/dist/assets/standard_fonts/FoxitSerifItalic.pfb +0 -0
  190. package/dist/assets/standard_fonts/FoxitSymbol.pfb +0 -0
  191. package/dist/assets/standard_fonts/LICENSE_FOXIT +27 -0
  192. package/dist/assets/standard_fonts/LICENSE_LIBERATION +102 -0
  193. package/dist/assets/standard_fonts/LiberationSans-Bold.ttf +0 -0
  194. package/dist/assets/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  195. package/dist/assets/standard_fonts/LiberationSans-Italic.ttf +0 -0
  196. package/dist/assets/standard_fonts/LiberationSans-Regular.ttf +0 -0
  197. package/dist/assets/xlsx.worker.js +61444 -0
  198. package/dist/core.d.ts +2 -0
  199. package/dist/core.js +3 -0
  200. package/dist/documentAnchor-J7GGLU15.js +69 -0
  201. package/dist/imageFilePreviewPlugin-CYLM2bwR.js +29 -0
  202. package/dist/jszip.min-uwqlc4KL.js +3108 -0
  203. package/dist/react.d.ts +105 -0
  204. package/dist/react.js +3114 -0
  205. package/dist/rolldown-runtime-B-lAHAz2.js +37 -0
  206. package/dist/rotate-ccw-YWx7RzY9.js +36 -0
  207. package/dist/selection-CQPD5a6C.js +47 -0
  208. package/dist/source-DjjzeN4t.d.ts +58 -0
  209. package/dist/source-Rx3etU3y.js +28 -0
  210. package/dist/styles.css +8778 -0
  211. package/dist/styles.js +0 -0
  212. package/dist/touchPinch-C4fl-9fg.js +34 -0
  213. package/dist/useTranslation-DMhY277o.js +7056 -0
  214. package/dist/zoom-out-DLOQGt1e.js +66 -0
  215. package/package.json +69 -3
package/README.md CHANGED
@@ -1,3 +1,248 @@
1
- # Temporary Holding Version
1
+ # File preview
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
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.