viewdoc 0.1.1 → 0.2.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.
Files changed (44) hide show
  1. package/README.md +6 -3
  2. package/dist/DocxViewer-VQN3BESX.js +8 -0
  3. package/dist/DocxViewer-VQN3BESX.js.map +1 -0
  4. package/dist/PdfViewer-NVAQBI2Y.js +8 -0
  5. package/dist/PdfViewer-NVAQBI2Y.js.map +1 -0
  6. package/dist/XlsxViewer-SQMAF5UA.js +8 -0
  7. package/dist/XlsxViewer-SQMAF5UA.js.map +1 -0
  8. package/dist/chunk-4VVVAGYE.js +110 -0
  9. package/dist/chunk-4VVVAGYE.js.map +1 -0
  10. package/dist/chunk-KRN2POC4.js +174 -0
  11. package/dist/chunk-KRN2POC4.js.map +1 -0
  12. package/dist/chunk-LE4YTMPN.js +135 -0
  13. package/dist/chunk-LE4YTMPN.js.map +1 -0
  14. package/dist/chunk-OA35SYM6.js +432 -0
  15. package/dist/chunk-OA35SYM6.js.map +1 -0
  16. package/dist/docx.cjs +566 -0
  17. package/dist/docx.cjs.map +1 -0
  18. package/dist/docx.d.cts +43 -0
  19. package/dist/docx.d.ts +43 -0
  20. package/dist/docx.js +8 -0
  21. package/dist/docx.js.map +1 -0
  22. package/dist/index.cjs +235 -116
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +9 -150
  25. package/dist/index.d.ts +9 -150
  26. package/dist/index.js +21 -828
  27. package/dist/index.js.map +1 -1
  28. package/dist/pdf.cjs +631 -0
  29. package/dist/pdf.cjs.map +1 -0
  30. package/dist/pdf.d.cts +45 -0
  31. package/dist/pdf.d.ts +45 -0
  32. package/dist/pdf.js +8 -0
  33. package/dist/pdf.js.map +1 -0
  34. package/dist/useDraggable-QvFR-4DD.d.cts +33 -0
  35. package/dist/useDraggable-QvFR-4DD.d.ts +33 -0
  36. package/dist/xlsx.cjs +591 -0
  37. package/dist/xlsx.cjs.map +1 -0
  38. package/dist/xlsx.d.cts +43 -0
  39. package/dist/xlsx.d.ts +43 -0
  40. package/dist/xlsx.js +8 -0
  41. package/dist/xlsx.js.map +1 -0
  42. package/package.json +16 -1
  43. package/dist/styles.d.cts +0 -2
  44. package/dist/styles.d.ts +0 -2
package/dist/docx.cjs ADDED
@@ -0,0 +1,566 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/entry-docx.ts
31
+ var entry_docx_exports = {};
32
+ __export(entry_docx_exports, {
33
+ DocxViewer: () => DocxViewer
34
+ });
35
+ module.exports = __toCommonJS(entry_docx_exports);
36
+
37
+ // src/core/ViewerShell.tsx
38
+ var import_react2 = require("react");
39
+
40
+ // src/core/useDraggable.ts
41
+ var import_react = require("react");
42
+ function useDraggable(options = {}) {
43
+ const { defaultPosition = { x: 80, y: 80 }, draggable = true } = options;
44
+ const [position, setPosition] = (0, import_react.useState)(defaultPosition);
45
+ const onDragHandlePointerDown = (0, import_react.useCallback)(
46
+ (e) => {
47
+ if (!draggable) return;
48
+ e.preventDefault();
49
+ const startX = e.clientX;
50
+ const startY = e.clientY;
51
+ setPosition((current) => {
52
+ const originX = current.x;
53
+ const originY = current.y;
54
+ const onMove = (ev) => {
55
+ setPosition({ x: originX + (ev.clientX - startX), y: originY + (ev.clientY - startY) });
56
+ };
57
+ const onUp = () => {
58
+ window.removeEventListener("pointermove", onMove);
59
+ window.removeEventListener("pointerup", onUp);
60
+ };
61
+ window.addEventListener("pointermove", onMove);
62
+ window.addEventListener("pointerup", onUp);
63
+ return current;
64
+ });
65
+ },
66
+ [draggable]
67
+ );
68
+ return { position, onDragHandlePointerDown };
69
+ }
70
+
71
+ // src/core/icons.tsx
72
+ var import_jsx_runtime = require("react/jsx-runtime");
73
+ function Svg(props) {
74
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
75
+ "svg",
76
+ {
77
+ width: "16",
78
+ height: "16",
79
+ viewBox: "0 0 24 24",
80
+ fill: "none",
81
+ stroke: "currentColor",
82
+ strokeWidth: "2",
83
+ strokeLinecap: "round",
84
+ strokeLinejoin: "round",
85
+ "aria-hidden": "true",
86
+ focusable: "false",
87
+ ...props
88
+ }
89
+ );
90
+ }
91
+ function ZoomOutIcon() {
92
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { children: [
93
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "11", cy: "11", r: "7" }),
94
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" }),
95
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "8", y1: "11", x2: "14", y2: "11" })
96
+ ] });
97
+ }
98
+ function ZoomInIcon() {
99
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { children: [
100
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "11", cy: "11", r: "7" }),
101
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" }),
102
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "11", y1: "8", x2: "11", y2: "14" }),
103
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "8", y1: "11", x2: "14", y2: "11" })
104
+ ] });
105
+ }
106
+ function DownloadIcon() {
107
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { children: [
108
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 3v12" }),
109
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M7 10l5 5 5-5" }),
110
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 21h14" })
111
+ ] });
112
+ }
113
+ function FullscreenEnterIcon() {
114
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { children: [
115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "15 3 21 3 21 9" }),
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "9 21 3 21 3 15" }),
117
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
118
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
119
+ ] });
120
+ }
121
+ function ResetIcon() {
122
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { children: [
123
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 12a9 9 0 1 0 3-6.7" }),
124
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "3 3 3 8 8 8" })
125
+ ] });
126
+ }
127
+ function GripIcon() {
128
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { children: [
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "5 9 2 12 5 15" }),
130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "9 5 12 2 15 5" }),
131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "15 19 12 22 9 19" }),
132
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "19 9 22 12 19 15" }),
133
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
134
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "2", x2: "12", y2: "22" })
135
+ ] });
136
+ }
137
+ function FullscreenExitIcon() {
138
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { children: [
139
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "9 3 9 9 3 9" }),
140
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "15 21 15 15 21 15" }),
141
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "9", y1: "9", x2: "3", y2: "3" }),
142
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "15", y1: "15", x2: "21", y2: "21" })
143
+ ] });
144
+ }
145
+
146
+ // src/core/Toolbar.tsx
147
+ var import_jsx_runtime2 = require("react/jsx-runtime");
148
+ function Toolbar({
149
+ scale,
150
+ onZoomIn,
151
+ onZoomOut,
152
+ onReset,
153
+ onFullscreen,
154
+ onDownload,
155
+ isFullscreen = false,
156
+ showZoomControls = true,
157
+ dragHandle,
158
+ onDragHandlePointerDown,
159
+ extra
160
+ }) {
161
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vd-toolbar", role: "toolbar", "aria-label": "Document viewer controls", children: [
162
+ dragHandle && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
163
+ "span",
164
+ {
165
+ className: "vd-toolbar-drag-handle",
166
+ onPointerDown: onDragHandlePointerDown,
167
+ title: "Drag to move",
168
+ "aria-label": "Drag to move",
169
+ children: dragHandle
170
+ }
171
+ ),
172
+ showZoomControls && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
173
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
174
+ "button",
175
+ {
176
+ type: "button",
177
+ className: "vd-toolbar-btn",
178
+ onClick: onZoomOut,
179
+ "aria-label": "Zoom out",
180
+ title: "Zoom out",
181
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ZoomOutIcon, {})
182
+ }
183
+ ),
184
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "vd-toolbar-scale", "aria-live": "polite", children: [
185
+ Math.round(scale * 100),
186
+ "%"
187
+ ] }),
188
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "vd-toolbar-btn", onClick: onZoomIn, "aria-label": "Zoom in", title: "Zoom in", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ZoomInIcon, {}) }),
189
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
190
+ "button",
191
+ {
192
+ type: "button",
193
+ className: "vd-toolbar-btn",
194
+ onClick: onReset,
195
+ "aria-label": "Reset zoom to 100%",
196
+ title: "Reset zoom to 100%",
197
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ResetIcon, {})
198
+ }
199
+ )
200
+ ] }),
201
+ extra,
202
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vd-toolbar-spacer" }),
203
+ onDownload && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
204
+ "button",
205
+ {
206
+ type: "button",
207
+ className: "vd-toolbar-btn",
208
+ onClick: onDownload,
209
+ "aria-label": "Download file",
210
+ title: "Download file",
211
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DownloadIcon, {})
212
+ }
213
+ ),
214
+ onFullscreen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
215
+ "button",
216
+ {
217
+ type: "button",
218
+ className: "vd-toolbar-btn",
219
+ onClick: onFullscreen,
220
+ "aria-label": isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
221
+ title: isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
222
+ children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FullscreenExitIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FullscreenEnterIcon, {})
223
+ }
224
+ )
225
+ ] });
226
+ }
227
+
228
+ // src/core/theme.ts
229
+ var THEME_VAR_MAP = {
230
+ background: "--vd-bg",
231
+ toolbarBackground: "--vd-toolbar-bg",
232
+ toolbarBorderColor: "--vd-toolbar-border-color",
233
+ toolbarButtonHoverBackground: "--vd-toolbar-btn-hover-bg",
234
+ textColor: "--vd-text-color",
235
+ borderRadius: "--vd-border-radius",
236
+ toolbarButtonRadius: "--vd-toolbar-btn-radius"
237
+ };
238
+ function themeToStyle(theme) {
239
+ if (!theme) return void 0;
240
+ const style = {};
241
+ for (const key of Object.keys(theme)) {
242
+ const value = theme[key];
243
+ if (value) style[THEME_VAR_MAP[key]] = value;
244
+ }
245
+ return style;
246
+ }
247
+
248
+ // src/core/ViewerShell.tsx
249
+ var import_jsx_runtime3 = require("react/jsx-runtime");
250
+ function ViewerShell({
251
+ zoomPan,
252
+ onDownload,
253
+ toolbarExtra,
254
+ children,
255
+ enableZoomControls = true,
256
+ enableFullscreen = true,
257
+ enablePan = true,
258
+ theme,
259
+ width,
260
+ height,
261
+ floating = true,
262
+ draggable = true,
263
+ defaultPosition,
264
+ transformOrigin
265
+ }) {
266
+ const rootRef = (0, import_react2.useRef)(null);
267
+ const [isFullscreen, setIsFullscreen] = (0, import_react2.useState)(false);
268
+ const effectiveWidth = typeof width === "number" ? width : 1200;
269
+ const effectiveHeight = typeof height === "number" ? height : 700;
270
+ const resolvedDefaultPosition = defaultPosition ?? (typeof window !== "undefined" ? {
271
+ x: Math.max(0, (window.innerWidth - effectiveWidth) / 2),
272
+ y: Math.max(0, (window.innerHeight - effectiveHeight) / 2)
273
+ } : { x: 80, y: 80 });
274
+ const { position, onDragHandlePointerDown } = useDraggable({
275
+ defaultPosition: resolvedDefaultPosition,
276
+ draggable
277
+ });
278
+ (0, import_react2.useEffect)(() => {
279
+ const onChange = () => setIsFullscreen(document.fullscreenElement === rootRef.current);
280
+ document.addEventListener("fullscreenchange", onChange);
281
+ return () => document.removeEventListener("fullscreenchange", onChange);
282
+ }, []);
283
+ const onFullscreen = (0, import_react2.useCallback)(() => {
284
+ const el = rootRef.current;
285
+ if (!el) return;
286
+ if (document.fullscreenElement) {
287
+ document.exitFullscreen();
288
+ } else {
289
+ el.requestFullscreen();
290
+ }
291
+ }, []);
292
+ const sizeStyle = {
293
+ width: width ?? 1200,
294
+ height: height ?? 700
295
+ };
296
+ const floatingStyle = floating ? { position: "fixed", left: position.x, top: position.y } : void 0;
297
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
298
+ "div",
299
+ {
300
+ className: `vd-shell${floating ? " vd-shell--floating" : ""}`,
301
+ ref: rootRef,
302
+ style: { ...themeToStyle(theme), ...sizeStyle, ...floatingStyle },
303
+ children: [
304
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
305
+ Toolbar,
306
+ {
307
+ scale: zoomPan.scale,
308
+ onZoomIn: zoomPan.zoomIn,
309
+ onZoomOut: zoomPan.zoomOut,
310
+ onReset: zoomPan.resetZoom,
311
+ onFullscreen: enableFullscreen ? onFullscreen : void 0,
312
+ onDownload,
313
+ isFullscreen,
314
+ showZoomControls: enableZoomControls,
315
+ dragHandle: floating && draggable ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GripIcon, {}) : void 0,
316
+ onDragHandlePointerDown: floating && draggable ? onDragHandlePointerDown : void 0,
317
+ extra: toolbarExtra
318
+ }
319
+ ),
320
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
321
+ "div",
322
+ {
323
+ className: `vd-canvas${enablePan ? "" : " vd-canvas--no-pan"}`,
324
+ ref: zoomPan.containerRef,
325
+ onWheel: zoomPan.handlers.onWheel,
326
+ onPointerDown: zoomPan.handlers.onPointerDown,
327
+ onPointerMove: zoomPan.handlers.onPointerMove,
328
+ onPointerUp: zoomPan.handlers.onPointerUp,
329
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
330
+ "div",
331
+ {
332
+ className: "vd-canvas-content",
333
+ style: {
334
+ transform: `translate(${zoomPan.translateX}px, ${zoomPan.translateY}px) scale(${zoomPan.scale})`,
335
+ transformOrigin
336
+ },
337
+ children
338
+ }
339
+ )
340
+ }
341
+ )
342
+ ]
343
+ }
344
+ );
345
+ }
346
+
347
+ // src/core/useZoomPan.ts
348
+ var import_react3 = require("react");
349
+ var DEFAULT_MIN = 0.1;
350
+ var DEFAULT_MAX = 8;
351
+ var DEFAULT_STEP = 0.25;
352
+ function useZoomPan(options = {}) {
353
+ const {
354
+ minScale = DEFAULT_MIN,
355
+ maxScale = DEFAULT_MAX,
356
+ zoomStep = DEFAULT_STEP,
357
+ enablePan = true,
358
+ enableWheelZoom = true,
359
+ enableDragScroll = false
360
+ } = options;
361
+ const [state, setState] = (0, import_react3.useState)({ scale: 1, translateX: 0, translateY: 0 });
362
+ const containerRef = (0, import_react3.useRef)(null);
363
+ const dragState = (0, import_react3.useRef)({
364
+ dragging: false,
365
+ startX: 0,
366
+ startY: 0,
367
+ originX: 0,
368
+ originY: 0
369
+ });
370
+ const scrollDragState = (0, import_react3.useRef)(
371
+ { dragging: false, startX: 0, startY: 0, originLeft: 0, originTop: 0 }
372
+ );
373
+ const clamp = (0, import_react3.useCallback)(
374
+ (value) => Math.min(maxScale, Math.max(minScale, value)),
375
+ [minScale, maxScale]
376
+ );
377
+ const setScale = (0, import_react3.useCallback)(
378
+ (scale) => setState((prev) => ({ ...prev, scale: clamp(scale) })),
379
+ [clamp]
380
+ );
381
+ const zoomIn = (0, import_react3.useCallback)(() => setScale(state.scale + zoomStep), [setScale, state.scale, zoomStep]);
382
+ const zoomOut = (0, import_react3.useCallback)(() => setScale(state.scale - zoomStep), [setScale, state.scale, zoomStep]);
383
+ const resetZoom = (0, import_react3.useCallback)(() => setState({ scale: 1, translateX: 0, translateY: 0 }), []);
384
+ const onWheel = (0, import_react3.useCallback)(
385
+ (e) => {
386
+ if (!enableWheelZoom) return;
387
+ if (!e.ctrlKey && !e.metaKey) return;
388
+ e.preventDefault();
389
+ const delta = e.deltaY > 0 ? -zoomStep : zoomStep;
390
+ setScale(state.scale + delta);
391
+ },
392
+ [enableWheelZoom, setScale, state.scale, zoomStep]
393
+ );
394
+ const onPointerDown = (0, import_react3.useCallback)(
395
+ (e) => {
396
+ if (enablePan) {
397
+ dragState.current = {
398
+ dragging: true,
399
+ startX: e.clientX,
400
+ startY: e.clientY,
401
+ originX: state.translateX,
402
+ originY: state.translateY
403
+ };
404
+ e.target.setPointerCapture(e.pointerId);
405
+ } else if (enableDragScroll && containerRef.current) {
406
+ scrollDragState.current = {
407
+ dragging: true,
408
+ startX: e.clientX,
409
+ startY: e.clientY,
410
+ originLeft: containerRef.current.scrollLeft,
411
+ originTop: containerRef.current.scrollTop
412
+ };
413
+ e.target.setPointerCapture(e.pointerId);
414
+ }
415
+ },
416
+ [enablePan, enableDragScroll, state.translateX, state.translateY]
417
+ );
418
+ const onPointerMove = (0, import_react3.useCallback)(
419
+ (e) => {
420
+ if (enablePan) {
421
+ if (!dragState.current.dragging) return;
422
+ const dx = e.clientX - dragState.current.startX;
423
+ const dy = e.clientY - dragState.current.startY;
424
+ setState((prev) => ({
425
+ ...prev,
426
+ translateX: dragState.current.originX + dx,
427
+ translateY: dragState.current.originY + dy
428
+ }));
429
+ } else if (enableDragScroll) {
430
+ if (!scrollDragState.current.dragging || !containerRef.current) return;
431
+ const dx = e.clientX - scrollDragState.current.startX;
432
+ const dy = e.clientY - scrollDragState.current.startY;
433
+ containerRef.current.scrollLeft = scrollDragState.current.originLeft - dx;
434
+ containerRef.current.scrollTop = scrollDragState.current.originTop - dy;
435
+ }
436
+ },
437
+ [enablePan, enableDragScroll]
438
+ );
439
+ const onPointerUp = (0, import_react3.useCallback)(
440
+ (e) => {
441
+ if (enablePan) {
442
+ dragState.current.dragging = false;
443
+ e.target.releasePointerCapture(e.pointerId);
444
+ } else if (enableDragScroll) {
445
+ scrollDragState.current.dragging = false;
446
+ e.target.releasePointerCapture(e.pointerId);
447
+ }
448
+ },
449
+ [enablePan, enableDragScroll]
450
+ );
451
+ return {
452
+ ...state,
453
+ containerRef,
454
+ zoomIn,
455
+ zoomOut,
456
+ resetZoom,
457
+ setScale,
458
+ handlers: { onWheel, onPointerDown, onPointerMove, onPointerUp }
459
+ };
460
+ }
461
+
462
+ // src/viewers/useDocxHtml.ts
463
+ var import_react4 = require("react");
464
+ var import_mammoth = __toESM(require("mammoth"), 1);
465
+ function useDocxHtml(uri) {
466
+ const [html, setHtml] = (0, import_react4.useState)(null);
467
+ const [error, setError] = (0, import_react4.useState)(null);
468
+ const [loading, setLoading] = (0, import_react4.useState)(true);
469
+ (0, import_react4.useEffect)(() => {
470
+ let cancelled = false;
471
+ setLoading(true);
472
+ setError(null);
473
+ setHtml(null);
474
+ fetch(uri).then((res) => {
475
+ if (!res.ok) throw new Error(`Failed to fetch document: ${res.status} ${res.statusText}`);
476
+ return res.arrayBuffer();
477
+ }).then((arrayBuffer) => import_mammoth.default.convertToHtml({ arrayBuffer })).then((result) => {
478
+ if (cancelled) return;
479
+ setHtml(result.value);
480
+ setLoading(false);
481
+ }).catch((err) => {
482
+ if (!cancelled) {
483
+ setError(err);
484
+ setLoading(false);
485
+ }
486
+ });
487
+ return () => {
488
+ cancelled = true;
489
+ };
490
+ }, [uri]);
491
+ return { html, error, loading };
492
+ }
493
+
494
+ // src/viewers/DocxViewer.tsx
495
+ var import_jsx_runtime4 = require("react/jsx-runtime");
496
+ function defaultDownload(uri, fileName) {
497
+ const link = document.createElement("a");
498
+ link.href = uri;
499
+ link.download = fileName ?? "";
500
+ link.rel = "noopener";
501
+ document.body.appendChild(link);
502
+ link.click();
503
+ document.body.removeChild(link);
504
+ }
505
+ function DocxViewer({
506
+ uri,
507
+ fileName,
508
+ className,
509
+ style,
510
+ width,
511
+ height,
512
+ minScale = 0.5,
513
+ maxScale = 3,
514
+ zoomStep,
515
+ enableZoomControls = true,
516
+ enableWheelZoom = true,
517
+ enableFullscreen = true,
518
+ enableDownload = true,
519
+ onDownload,
520
+ theme,
521
+ floating = true,
522
+ windowDraggable = true,
523
+ defaultPosition
524
+ }) {
525
+ const zoomPan = useZoomPan({
526
+ minScale,
527
+ maxScale,
528
+ zoomStep,
529
+ enablePan: false,
530
+ enableDragScroll: true,
531
+ enableWheelZoom
532
+ });
533
+ const { html, error, loading } = useDocxHtml(uri);
534
+ const handleDownload = enableDownload ? onDownload ?? (() => defaultDownload(uri, fileName)) : void 0;
535
+ const wrapperStyle = floating ? { ...style } : { display: "flex", alignItems: "center", justifyContent: "center", width: "100%", height: "100%", ...style };
536
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className, style: wrapperStyle, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
537
+ ViewerShell,
538
+ {
539
+ zoomPan,
540
+ onDownload: handleDownload,
541
+ enableZoomControls,
542
+ enableFullscreen,
543
+ enablePan: false,
544
+ theme,
545
+ width,
546
+ height,
547
+ floating,
548
+ draggable: windowDraggable,
549
+ defaultPosition,
550
+ transformOrigin: "top center",
551
+ children: [
552
+ loading && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vd-doc-status", children: "Loading document\u2026" }),
553
+ error && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vd-doc-status", children: [
554
+ "Failed to load document: ",
555
+ error.message
556
+ ] }),
557
+ html && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vd-docx-page", dangerouslySetInnerHTML: { __html: html } })
558
+ ]
559
+ }
560
+ ) });
561
+ }
562
+ // Annotate the CommonJS export names for ESM import in node:
563
+ 0 && (module.exports = {
564
+ DocxViewer
565
+ });
566
+ //# sourceMappingURL=docx.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/entry-docx.ts","../src/core/ViewerShell.tsx","../src/core/useDraggable.ts","../src/core/icons.tsx","../src/core/Toolbar.tsx","../src/core/theme.ts","../src/core/useZoomPan.ts","../src/viewers/useDocxHtml.ts","../src/viewers/DocxViewer.tsx"],"sourcesContent":["export { DocxViewer } from './viewers/DocxViewer'\nexport type { DocxViewerProps } from './viewers/DocxViewer'\n","import { useCallback, useEffect, useRef, useState, type CSSProperties, type ReactNode } from 'react'\nimport { useDraggable, type Position } from './useDraggable'\nimport { GripIcon } from './icons'\nimport { Toolbar } from './Toolbar'\nimport { themeToStyle, type ViewerTheme } from './theme'\nimport type { ZoomPanControls } from './useZoomPan'\n\nexport interface ViewerShellProps {\n zoomPan: ZoomPanControls\n onDownload?: () => void\n toolbarExtra?: ReactNode\n children: ReactNode\n /** Show the zoom in/out/reset-to-100% controls. Default: true. */\n enableZoomControls?: boolean\n /** Show the fullscreen toggle button. Default: true. */\n enableFullscreen?: boolean\n /** Allow click-drag-release panning of the content. Default: true. */\n enablePan?: boolean\n /** Colors/radii to override the default look. Any field left out keeps the default. */\n theme?: ViewerTheme\n /** Width of the viewer. Accepts any CSS size (e.g. 1200, '1200px', '100%'). Default: 1200. */\n width?: number | string\n /** Height of the viewer. Accepts any CSS size (e.g. 700, '700px', '100vh'). Default: 700. */\n height?: number | string\n\n /** Render as a floating window (position: fixed) that can be dragged, instead of filling the parent container. Default: true. */\n floating?: boolean\n /** When floating, allow dragging the window by its toolbar. Default: true. */\n draggable?: boolean\n /** Initial position when floating. Default: centered in the viewport. */\n defaultPosition?: Position\n /** CSS transform-origin for the zoomed content. Default: 'center center'. */\n transformOrigin?: string\n}\n\nexport function ViewerShell({\n zoomPan,\n onDownload,\n toolbarExtra,\n children,\n enableZoomControls = true,\n enableFullscreen = true,\n enablePan = true,\n theme,\n width,\n height,\n floating = true,\n draggable = true,\n defaultPosition,\n transformOrigin,\n}: ViewerShellProps) {\n const rootRef = useRef<HTMLDivElement>(null)\n const [isFullscreen, setIsFullscreen] = useState(false)\n\n const effectiveWidth = typeof width === 'number' ? width : 1200\n const effectiveHeight = typeof height === 'number' ? height : 700\n const resolvedDefaultPosition =\n defaultPosition ??\n (typeof window !== 'undefined'\n ? {\n x: Math.max(0, (window.innerWidth - effectiveWidth) / 2),\n y: Math.max(0, (window.innerHeight - effectiveHeight) / 2),\n }\n : { x: 80, y: 80 })\n\n const { position, onDragHandlePointerDown } = useDraggable({\n defaultPosition: resolvedDefaultPosition,\n draggable,\n })\n\n useEffect(() => {\n const onChange = () => setIsFullscreen(document.fullscreenElement === rootRef.current)\n document.addEventListener('fullscreenchange', onChange)\n return () => document.removeEventListener('fullscreenchange', onChange)\n }, [])\n\n const onFullscreen = useCallback(() => {\n const el = rootRef.current\n if (!el) return\n if (document.fullscreenElement) {\n document.exitFullscreen()\n } else {\n el.requestFullscreen()\n }\n }, [])\n\n const sizeStyle: CSSProperties = {\n width: width ?? 1200,\n height: height ?? 700,\n }\n const floatingStyle: CSSProperties | undefined = floating\n ? { position: 'fixed', left: position.x, top: position.y }\n : undefined\n\n return (\n <div\n className={`vd-shell${floating ? ' vd-shell--floating' : ''}`}\n ref={rootRef}\n style={{ ...themeToStyle(theme), ...sizeStyle, ...floatingStyle }}\n >\n <Toolbar\n scale={zoomPan.scale}\n onZoomIn={zoomPan.zoomIn}\n onZoomOut={zoomPan.zoomOut}\n onReset={zoomPan.resetZoom}\n onFullscreen={enableFullscreen ? onFullscreen : undefined}\n onDownload={onDownload}\n isFullscreen={isFullscreen}\n showZoomControls={enableZoomControls}\n dragHandle={floating && draggable ? <GripIcon /> : undefined}\n onDragHandlePointerDown={floating && draggable ? onDragHandlePointerDown : undefined}\n extra={toolbarExtra}\n />\n <div\n className={`vd-canvas${enablePan ? '' : ' vd-canvas--no-pan'}`}\n ref={zoomPan.containerRef}\n onWheel={zoomPan.handlers.onWheel}\n onPointerDown={zoomPan.handlers.onPointerDown}\n onPointerMove={zoomPan.handlers.onPointerMove}\n onPointerUp={zoomPan.handlers.onPointerUp}\n >\n <div\n className=\"vd-canvas-content\"\n style={{\n transform: `translate(${zoomPan.translateX}px, ${zoomPan.translateY}px) scale(${zoomPan.scale})`,\n transformOrigin,\n }}\n >\n {children}\n </div>\n </div>\n </div>\n )\n}\n","import { useCallback, useState } from 'react'\n\nexport interface Position {\n x: number\n y: number\n}\n\nexport interface UseDraggableOptions {\n defaultPosition?: Position\n /** Allow dragging via the returned handle props. Default: true. */\n draggable?: boolean\n}\n\nexport interface DraggableControls {\n position: Position\n onDragHandlePointerDown: (e: React.PointerEvent) => void\n}\n\nexport function useDraggable(options: UseDraggableOptions = {}): DraggableControls {\n const { defaultPosition = { x: 80, y: 80 }, draggable = true } = options\n const [position, setPosition] = useState<Position>(defaultPosition)\n\n const onDragHandlePointerDown = useCallback(\n (e: React.PointerEvent) => {\n if (!draggable) return\n e.preventDefault()\n const startX = e.clientX\n const startY = e.clientY\n\n setPosition((current) => {\n const originX = current.x\n const originY = current.y\n\n const onMove = (ev: PointerEvent) => {\n setPosition({ x: originX + (ev.clientX - startX), y: originY + (ev.clientY - startY) })\n }\n const onUp = () => {\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerup', onUp)\n }\n window.addEventListener('pointermove', onMove)\n window.addEventListener('pointerup', onUp)\n\n return current\n })\n },\n [draggable]\n )\n\n return { position, onDragHandlePointerDown }\n}\n","import type { SVGProps } from 'react'\n\nfunction Svg(props: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n {...props}\n />\n )\n}\n\nexport function ZoomOutIcon() {\n return (\n <Svg>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n <line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\" />\n </Svg>\n )\n}\n\nexport function ZoomInIcon() {\n return (\n <Svg>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n <line x1=\"11\" y1=\"8\" x2=\"11\" y2=\"14\" />\n <line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\" />\n </Svg>\n )\n}\n\nexport function DownloadIcon() {\n return (\n <Svg>\n <path d=\"M12 3v12\" />\n <path d=\"M7 10l5 5 5-5\" />\n <path d=\"M5 21h14\" />\n </Svg>\n )\n}\n\nexport function FullscreenEnterIcon() {\n return (\n <Svg>\n <polyline points=\"15 3 21 3 21 9\" />\n <polyline points=\"9 21 3 21 3 15\" />\n <line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" />\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n </Svg>\n )\n}\n\nexport function ResetIcon() {\n return (\n <Svg>\n <path d=\"M3 12a9 9 0 1 0 3-6.7\" />\n <polyline points=\"3 3 3 8 8 8\" />\n </Svg>\n )\n}\n\nexport function GripIcon() {\n return (\n <Svg>\n <polyline points=\"5 9 2 12 5 15\" />\n <polyline points=\"9 5 12 2 15 5\" />\n <polyline points=\"15 19 12 22 9 19\" />\n <polyline points=\"19 9 22 12 19 15\" />\n <line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\" />\n <line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"22\" />\n </Svg>\n )\n}\n\nexport function FullscreenExitIcon() {\n return (\n <Svg>\n <polyline points=\"9 3 9 9 3 9\" />\n <polyline points=\"15 21 15 15 21 15\" />\n <line x1=\"9\" y1=\"9\" x2=\"3\" y2=\"3\" />\n <line x1=\"15\" y1=\"15\" x2=\"21\" y2=\"21\" />\n </Svg>\n )\n}\n","import type { ReactNode } from 'react'\nimport { DownloadIcon, FullscreenEnterIcon, FullscreenExitIcon, ResetIcon, ZoomInIcon, ZoomOutIcon } from './icons'\n\nexport interface ToolbarProps {\n scale: number\n onZoomIn: () => void\n onZoomOut: () => void\n onReset: () => void\n onFullscreen?: () => void\n onDownload?: () => void\n /** Whether the viewer is currently in fullscreen mode (controls which icon is shown). */\n isFullscreen?: boolean\n /** Show zoom in/out/reset controls. Default: true. */\n showZoomControls?: boolean\n /** Icon shown at the start of the toolbar; pointer-down on it starts dragging. */\n dragHandle?: ReactNode\n /** Pointer-down handler attached to the drag handle icon. */\n onDragHandlePointerDown?: (e: React.PointerEvent) => void\n extra?: ReactNode\n}\n\nexport function Toolbar({\n scale,\n onZoomIn,\n onZoomOut,\n onReset,\n onFullscreen,\n onDownload,\n isFullscreen = false,\n showZoomControls = true,\n dragHandle,\n onDragHandlePointerDown,\n extra,\n}: ToolbarProps) {\n return (\n <div className=\"vd-toolbar\" role=\"toolbar\" aria-label=\"Document viewer controls\">\n {dragHandle && (\n <span\n className=\"vd-toolbar-drag-handle\"\n onPointerDown={onDragHandlePointerDown}\n title=\"Drag to move\"\n aria-label=\"Drag to move\"\n >\n {dragHandle}\n </span>\n )}\n {showZoomControls && (\n <>\n <button\n type=\"button\"\n className=\"vd-toolbar-btn\"\n onClick={onZoomOut}\n aria-label=\"Zoom out\"\n title=\"Zoom out\"\n >\n <ZoomOutIcon />\n </button>\n <span className=\"vd-toolbar-scale\" aria-live=\"polite\">\n {Math.round(scale * 100)}%\n </span>\n <button type=\"button\" className=\"vd-toolbar-btn\" onClick={onZoomIn} aria-label=\"Zoom in\" title=\"Zoom in\">\n <ZoomInIcon />\n </button>\n <button\n type=\"button\"\n className=\"vd-toolbar-btn\"\n onClick={onReset}\n aria-label=\"Reset zoom to 100%\"\n title=\"Reset zoom to 100%\"\n >\n <ResetIcon />\n </button>\n </>\n )}\n {extra}\n <span className=\"vd-toolbar-spacer\" />\n {onDownload && (\n <button\n type=\"button\"\n className=\"vd-toolbar-btn\"\n onClick={onDownload}\n aria-label=\"Download file\"\n title=\"Download file\"\n >\n <DownloadIcon />\n </button>\n )}\n {onFullscreen && (\n <button\n type=\"button\"\n className=\"vd-toolbar-btn\"\n onClick={onFullscreen}\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n title={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n >\n {isFullscreen ? <FullscreenExitIcon /> : <FullscreenEnterIcon />}\n </button>\n )}\n </div>\n )\n}\n","import type { CSSProperties } from 'react'\n\nexport interface ViewerTheme {\n /** Background color of the viewer canvas area. */\n background?: string\n /** Background color of the toolbar strip. */\n toolbarBackground?: string\n /** Border color under the toolbar. */\n toolbarBorderColor?: string\n /** Hover background for toolbar buttons. */\n toolbarButtonHoverBackground?: string\n /** Text/icon color used across the toolbar. */\n textColor?: string\n /** Corner radius of the outer viewer container. */\n borderRadius?: string\n /** Corner radius of individual toolbar buttons. */\n toolbarButtonRadius?: string\n}\n\nconst THEME_VAR_MAP: Record<keyof ViewerTheme, string> = {\n background: '--vd-bg',\n toolbarBackground: '--vd-toolbar-bg',\n toolbarBorderColor: '--vd-toolbar-border-color',\n toolbarButtonHoverBackground: '--vd-toolbar-btn-hover-bg',\n textColor: '--vd-text-color',\n borderRadius: '--vd-border-radius',\n toolbarButtonRadius: '--vd-toolbar-btn-radius',\n}\n\n/** Converts a ViewerTheme into inline CSS custom properties overriding the defaults in styles.css. */\nexport function themeToStyle(theme?: ViewerTheme): CSSProperties | undefined {\n if (!theme) return undefined\n const style: Record<string, string> = {}\n for (const key of Object.keys(theme) as (keyof ViewerTheme)[]) {\n const value = theme[key]\n if (value) style[THEME_VAR_MAP[key]] = value\n }\n return style as CSSProperties\n}\n","import { useCallback, useRef, useState } from 'react'\n\nexport interface ZoomPanState {\n scale: number\n translateX: number\n translateY: number\n}\n\nexport interface ZoomPanOptions {\n minScale?: number\n maxScale?: number\n zoomStep?: number\n /** Allow click-drag-release panning by transforming the content. Default: true. */\n enablePan?: boolean\n /** Allow Ctrl/Cmd + scroll wheel zoom. Default: true. */\n enableWheelZoom?: boolean\n /** Allow click-drag-release scrolling of a natively-scrollable container (used instead of enablePan for scrollable content like PDF pages). Default: false. */\n enableDragScroll?: boolean\n}\n\nexport interface ZoomPanControls extends ZoomPanState {\n containerRef: React.RefObject<HTMLDivElement>\n zoomIn: () => void\n zoomOut: () => void\n resetZoom: () => void\n setScale: (scale: number) => void\n handlers: {\n onWheel: (e: React.WheelEvent) => void\n onPointerDown: (e: React.PointerEvent) => void\n onPointerMove: (e: React.PointerEvent) => void\n onPointerUp: (e: React.PointerEvent) => void\n }\n}\n\nconst DEFAULT_MIN = 0.1\nconst DEFAULT_MAX = 8\nconst DEFAULT_STEP = 0.25\n\nexport function useZoomPan(options: ZoomPanOptions = {}): ZoomPanControls {\n const {\n minScale = DEFAULT_MIN,\n maxScale = DEFAULT_MAX,\n zoomStep = DEFAULT_STEP,\n enablePan = true,\n enableWheelZoom = true,\n enableDragScroll = false,\n } = options\n\n const [state, setState] = useState<ZoomPanState>({ scale: 1, translateX: 0, translateY: 0 })\n const containerRef = useRef<HTMLDivElement>(null)\n const dragState = useRef<{ dragging: boolean; startX: number; startY: number; originX: number; originY: number }>({\n dragging: false,\n startX: 0,\n startY: 0,\n originX: 0,\n originY: 0,\n })\n const scrollDragState = useRef<{ dragging: boolean; startX: number; startY: number; originLeft: number; originTop: number }>(\n { dragging: false, startX: 0, startY: 0, originLeft: 0, originTop: 0 }\n )\n\n const clamp = useCallback(\n (value: number) => Math.min(maxScale, Math.max(minScale, value)),\n [minScale, maxScale]\n )\n\n const setScale = useCallback(\n (scale: number) => setState((prev) => ({ ...prev, scale: clamp(scale) })),\n [clamp]\n )\n\n const zoomIn = useCallback(() => setScale(state.scale + zoomStep), [setScale, state.scale, zoomStep])\n const zoomOut = useCallback(() => setScale(state.scale - zoomStep), [setScale, state.scale, zoomStep])\n const resetZoom = useCallback(() => setState({ scale: 1, translateX: 0, translateY: 0 }), [])\n\n const onWheel = useCallback(\n (e: React.WheelEvent) => {\n if (!enableWheelZoom) return\n if (!e.ctrlKey && !e.metaKey) return\n e.preventDefault()\n const delta = e.deltaY > 0 ? -zoomStep : zoomStep\n setScale(state.scale + delta)\n },\n [enableWheelZoom, setScale, state.scale, zoomStep]\n )\n\n const onPointerDown = useCallback(\n (e: React.PointerEvent) => {\n if (enablePan) {\n dragState.current = {\n dragging: true,\n startX: e.clientX,\n startY: e.clientY,\n originX: state.translateX,\n originY: state.translateY,\n }\n ;(e.target as HTMLElement).setPointerCapture(e.pointerId)\n } else if (enableDragScroll && containerRef.current) {\n scrollDragState.current = {\n dragging: true,\n startX: e.clientX,\n startY: e.clientY,\n originLeft: containerRef.current.scrollLeft,\n originTop: containerRef.current.scrollTop,\n }\n ;(e.target as HTMLElement).setPointerCapture(e.pointerId)\n }\n },\n [enablePan, enableDragScroll, state.translateX, state.translateY]\n )\n\n const onPointerMove = useCallback(\n (e: React.PointerEvent) => {\n if (enablePan) {\n if (!dragState.current.dragging) return\n const dx = e.clientX - dragState.current.startX\n const dy = e.clientY - dragState.current.startY\n setState((prev) => ({\n ...prev,\n translateX: dragState.current.originX + dx,\n translateY: dragState.current.originY + dy,\n }))\n } else if (enableDragScroll) {\n if (!scrollDragState.current.dragging || !containerRef.current) return\n const dx = e.clientX - scrollDragState.current.startX\n const dy = e.clientY - scrollDragState.current.startY\n containerRef.current.scrollLeft = scrollDragState.current.originLeft - dx\n containerRef.current.scrollTop = scrollDragState.current.originTop - dy\n }\n },\n [enablePan, enableDragScroll]\n )\n\n const onPointerUp = useCallback(\n (e: React.PointerEvent) => {\n if (enablePan) {\n dragState.current.dragging = false\n ;(e.target as HTMLElement).releasePointerCapture(e.pointerId)\n } else if (enableDragScroll) {\n scrollDragState.current.dragging = false\n ;(e.target as HTMLElement).releasePointerCapture(e.pointerId)\n }\n },\n [enablePan, enableDragScroll]\n )\n\n return {\n ...state,\n containerRef,\n zoomIn,\n zoomOut,\n resetZoom,\n setScale,\n handlers: { onWheel, onPointerDown, onPointerMove, onPointerUp },\n }\n}\n","import { useEffect, useState } from 'react'\nimport mammoth from 'mammoth'\n\nexport interface UseDocxHtmlResult {\n html: string | null\n error: Error | null\n loading: boolean\n}\n\nexport function useDocxHtml(uri: string): UseDocxHtmlResult {\n const [html, setHtml] = useState<string | null>(null)\n const [error, setError] = useState<Error | null>(null)\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n let cancelled = false\n setLoading(true)\n setError(null)\n setHtml(null)\n\n fetch(uri)\n .then((res) => {\n if (!res.ok) throw new Error(`Failed to fetch document: ${res.status} ${res.statusText}`)\n return res.arrayBuffer()\n })\n .then((arrayBuffer) => mammoth.convertToHtml({ arrayBuffer }))\n .then((result) => {\n if (cancelled) return\n setHtml(result.value)\n setLoading(false)\n })\n .catch((err: Error) => {\n if (!cancelled) {\n setError(err)\n setLoading(false)\n }\n })\n\n return () => {\n cancelled = true\n }\n }, [uri])\n\n return { html, error, loading }\n}\n","import type { CSSProperties } from 'react'\nimport { ViewerShell } from '../core/ViewerShell'\nimport type { ViewerTheme } from '../core/theme'\nimport type { Position } from '../core/useDraggable'\nimport { useZoomPan } from '../core/useZoomPan'\nimport { useDocxHtml } from './useDocxHtml'\n\nexport interface DocxViewerProps {\n /** URL of the .docx file to display. */\n uri: string\n /** Used as the suggested filename on download. */\n fileName?: string\n className?: string\n style?: CSSProperties\n\n /** Width of the viewer. Accepts any CSS size (e.g. 1200, '1200px', '100%'). Default: 1200. */\n width?: number | string\n /** Height of the viewer. Accepts any CSS size (e.g. 700, '700px', '100vh'). Default: 700. */\n height?: number | string\n\n /** Minimum zoom scale. Default: 0.5 */\n minScale?: number\n /** Maximum zoom scale. Default: 3 */\n maxScale?: number\n /** Zoom increment per step (buttons / Ctrl+scroll). Default: 0.25 */\n zoomStep?: number\n\n /** Show zoom in/out and reset-to-100% controls. Default: true. */\n enableZoomControls?: boolean\n /** Allow Ctrl/Cmd + scroll wheel to zoom. Default: true. */\n enableWheelZoom?: boolean\n /** Show the fullscreen toggle button. Default: true. */\n enableFullscreen?: boolean\n /** Show the download button. Default: true. */\n enableDownload?: boolean\n /** Called when the download button is clicked. If omitted, downloads `uri` directly. */\n onDownload?: () => void\n /** Colors/radii to override the default look (toolbar background, text color, etc). */\n theme?: ViewerTheme\n\n /** Render as a floating window (position: fixed) that can be dragged, instead of filling the parent. Default: true. */\n floating?: boolean\n /** When floating, allow dragging the window by its toolbar. Default: true. */\n windowDraggable?: boolean\n /** Initial position when floating. Default: centered in the viewport. */\n defaultPosition?: Position\n}\n\nfunction defaultDownload(uri: string, fileName?: string) {\n const link = document.createElement('a')\n link.href = uri\n link.download = fileName ?? ''\n link.rel = 'noopener'\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n}\n\nexport function DocxViewer({\n uri,\n fileName,\n className,\n style,\n width,\n height,\n minScale = 0.5,\n maxScale = 3,\n zoomStep,\n enableZoomControls = true,\n enableWheelZoom = true,\n enableFullscreen = true,\n enableDownload = true,\n onDownload,\n theme,\n floating = true,\n windowDraggable = true,\n defaultPosition,\n}: DocxViewerProps) {\n const zoomPan = useZoomPan({\n minScale,\n maxScale,\n zoomStep,\n enablePan: false,\n enableDragScroll: true,\n enableWheelZoom,\n })\n const { html, error, loading } = useDocxHtml(uri)\n\n const handleDownload = enableDownload ? onDownload ?? (() => defaultDownload(uri, fileName)) : undefined\n\n const wrapperStyle: CSSProperties = floating\n ? { ...style }\n : { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '100%', height: '100%', ...style }\n\n return (\n <div className={className} style={wrapperStyle}>\n <ViewerShell\n zoomPan={zoomPan}\n onDownload={handleDownload}\n enableZoomControls={enableZoomControls}\n enableFullscreen={enableFullscreen}\n enablePan={false}\n theme={theme}\n width={width}\n height={height}\n floating={floating}\n draggable={windowDraggable}\n defaultPosition={defaultPosition}\n transformOrigin=\"top center\"\n >\n {loading && <span className=\"vd-doc-status\">Loading document…</span>}\n {error && <span className=\"vd-doc-status\">Failed to load document: {error.message}</span>}\n {html && <div className=\"vd-docx-page\" dangerouslySetInnerHTML={{ __html: html }} />}\n </ViewerShell>\n </div>\n )\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_react","mammoth","import_jsx_runtime"]}