@extend-ai/react-docx 0.6.0 → 0.6.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/README.md +234 -0
- package/dist/index.cjs +137 -166
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +6385 -304
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-TIKIYV26.js +0 -6131
- package/dist/chunk-TIKIYV26.js.map +0 -1
- package/dist/docx-import-worker.cjs +0 -5927
- package/dist/docx-import-worker.cjs.map +0 -1
- package/dist/docx-import-worker.js +0 -33
- package/dist/docx-import-worker.js.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# @extend-ai/react-docx
|
|
2
|
+
|
|
3
|
+
React-first DOCX viewing and editing components for rendering `.docx` files in a browser.
|
|
4
|
+
|
|
5
|
+
`@extend-ai/react-docx` gives you:
|
|
6
|
+
|
|
7
|
+
- A simple read-only viewer for rendering `.docx` files or prebuilt document models
|
|
8
|
+
- A richer editor/controller API for building custom DOCX editing UIs
|
|
9
|
+
- Pagination, page layout, theme, tracked-change, form-field, and thumbnail hooks
|
|
10
|
+
- Configurable page surface and inter-page background colors
|
|
11
|
+
- A dark read-only night-reader mode that inverts document content while preserving image hues
|
|
12
|
+
- Lower-level OOXML, model, layout, and serialization exports for custom pipelines
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @extend-ai/react-docx react react-dom
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`react` and `react-dom` are peer dependencies.
|
|
21
|
+
|
|
22
|
+
## Main Entry Points
|
|
23
|
+
|
|
24
|
+
The package exports two useful levels of API:
|
|
25
|
+
|
|
26
|
+
1. `ReactDocxViewer`
|
|
27
|
+
A lightweight read-only viewer when you just want to render a document.
|
|
28
|
+
|
|
29
|
+
2. `useDocxEditor` + `DocxEditorViewer`
|
|
30
|
+
The full controller/view split for editable or highly customized experiences.
|
|
31
|
+
|
|
32
|
+
It also re-exports lower-level document/model/layout/serializer APIs, so you can work below the UI layer when needed.
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### Read-only viewer
|
|
37
|
+
|
|
38
|
+
Use `ReactDocxViewer` when you want the smallest integration surface.
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import * as React from "react";
|
|
42
|
+
import { ReactDocxViewer } from "@extend-ai/react-docx";
|
|
43
|
+
|
|
44
|
+
export function ReadOnlyDocxExample() {
|
|
45
|
+
const [file, setFile] = React.useState<ArrayBuffer | undefined>();
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div style={{ display: "grid", gap: 12 }}>
|
|
49
|
+
<input
|
|
50
|
+
type="file"
|
|
51
|
+
accept=".docx"
|
|
52
|
+
onChange={async (event) => {
|
|
53
|
+
const nextFile = event.target.files?.[0];
|
|
54
|
+
setFile(nextFile ? await nextFile.arrayBuffer() : undefined);
|
|
55
|
+
}}
|
|
56
|
+
/>
|
|
57
|
+
|
|
58
|
+
<ReactDocxViewer
|
|
59
|
+
file={file}
|
|
60
|
+
emptyState="Choose a DOCX file to preview."
|
|
61
|
+
/>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
You can also pass a `model` instead of a raw `.docx` file if you already have a normalized document model.
|
|
68
|
+
|
|
69
|
+
### Full editor/viewer
|
|
70
|
+
|
|
71
|
+
Use `useDocxEditor` when you want import/export controls, document theme state, selection-aware editing commands, pagination state, and a customizable document canvas.
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import * as React from "react";
|
|
75
|
+
import {
|
|
76
|
+
DocxEditorViewer,
|
|
77
|
+
useDocxDocumentTheme,
|
|
78
|
+
useDocxEditor,
|
|
79
|
+
useDocxPagination,
|
|
80
|
+
} from "@extend-ai/react-docx";
|
|
81
|
+
|
|
82
|
+
export function EditorExample() {
|
|
83
|
+
const editor = useDocxEditor({
|
|
84
|
+
initialDocumentTheme: "light",
|
|
85
|
+
initialStatus: "Ready",
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const { documentTheme, toggleDocumentTheme } = useDocxDocumentTheme(editor);
|
|
89
|
+
const { pagination } = useDocxPagination(editor);
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<div style={{ display: "grid", gap: 12 }}>
|
|
93
|
+
<div style={{ display: "flex", gap: 8, alignItems: "center" }}>
|
|
94
|
+
<input
|
|
95
|
+
type="file"
|
|
96
|
+
accept=".docx"
|
|
97
|
+
onChange={(event) => {
|
|
98
|
+
const file = event.target.files?.[0];
|
|
99
|
+
if (file) {
|
|
100
|
+
void editor.importDocxFile(file);
|
|
101
|
+
}
|
|
102
|
+
}}
|
|
103
|
+
/>
|
|
104
|
+
|
|
105
|
+
<button type="button" onClick={() => editor.exportDocx()}>
|
|
106
|
+
Export DOCX
|
|
107
|
+
</button>
|
|
108
|
+
|
|
109
|
+
<button type="button" onClick={() => toggleDocumentTheme()}>
|
|
110
|
+
Theme: {documentTheme}
|
|
111
|
+
</button>
|
|
112
|
+
|
|
113
|
+
<span>
|
|
114
|
+
Page {pagination.currentPage} / {pagination.totalPages}
|
|
115
|
+
</span>
|
|
116
|
+
|
|
117
|
+
<span>{editor.status}</span>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
<DocxEditorViewer
|
|
121
|
+
editor={editor}
|
|
122
|
+
mode="edit"
|
|
123
|
+
pageBackgroundColor="#ffffff"
|
|
124
|
+
pageGapBackgroundColor="transparent"
|
|
125
|
+
/>
|
|
126
|
+
</div>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Thumbnail Hook
|
|
132
|
+
|
|
133
|
+
The library can expose page thumbnails from mounted viewer surfaces so you can build your own page strip, mini-map, or navigation UI.
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import * as React from "react";
|
|
137
|
+
import {
|
|
138
|
+
DocxEditorViewer,
|
|
139
|
+
useDocxEditor,
|
|
140
|
+
useDocxPageThumbnails,
|
|
141
|
+
} from "@extend-ai/react-docx";
|
|
142
|
+
|
|
143
|
+
export function ThumbnailExample() {
|
|
144
|
+
const editor = useDocxEditor();
|
|
145
|
+
const { thumbnails } = useDocxPageThumbnails(editor, {
|
|
146
|
+
maxWidthPx: 160,
|
|
147
|
+
maxHeightPx: 220,
|
|
148
|
+
pixelRatio: 2,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
return (
|
|
152
|
+
<div style={{ display: "grid", gridTemplateColumns: "180px 1fr", gap: 16 }}>
|
|
153
|
+
<div style={{ display: "grid", gap: 12, alignContent: "start" }}>
|
|
154
|
+
{thumbnails.map((thumbnail) => (
|
|
155
|
+
<canvas
|
|
156
|
+
key={thumbnail.pageIndex}
|
|
157
|
+
ref={thumbnail.canvasRef}
|
|
158
|
+
width={thumbnail.pixelWidthPx}
|
|
159
|
+
height={thumbnail.pixelHeightPx}
|
|
160
|
+
style={{
|
|
161
|
+
width: thumbnail.widthPx,
|
|
162
|
+
height: thumbnail.heightPx,
|
|
163
|
+
border: "1px solid #ddd",
|
|
164
|
+
}}
|
|
165
|
+
/>
|
|
166
|
+
))}
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
<DocxEditorViewer
|
|
170
|
+
editor={editor}
|
|
171
|
+
pageVirtualization={{ enabled: false }}
|
|
172
|
+
/>
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Notes:
|
|
179
|
+
|
|
180
|
+
- Thumbnails are produced from mounted page DOM.
|
|
181
|
+
- Thumbnail sizing is bounded by `maxWidthPx` and `maxHeightPx`, so downstream UIs can bias toward portrait thumbnail rails.
|
|
182
|
+
- If page virtualization is enabled, offscreen pages can report `status: "unavailable"`.
|
|
183
|
+
- For a full thumbnail rail, disable virtualization or manage the visible page range yourself.
|
|
184
|
+
|
|
185
|
+
## Useful Hooks
|
|
186
|
+
|
|
187
|
+
`@extend-ai/react-docx` exports several hooks for wiring custom UI around the viewer:
|
|
188
|
+
|
|
189
|
+
- `useDocxDocumentTheme(editor)` for light/dark document mode
|
|
190
|
+
- `useDocxPagination(editor)` for current page and total page count
|
|
191
|
+
- `useDocxPageLayout(editor)` for page size, margins, columns, and viewport defaults
|
|
192
|
+
- `useDocxPageThumbnails(editor, options)` for rendering page previews into your own canvases
|
|
193
|
+
- `useDocxParagraphStyles(editor)` for available paragraph styles and style selection
|
|
194
|
+
- `useDocxLineSpacing(editor)` for selected line spacing state
|
|
195
|
+
- `useDocxBorders(editor)` for paragraph/table border presets
|
|
196
|
+
- `useDocxFormFields(editor)` for DOCX form-field state and updates
|
|
197
|
+
- `useDocxTrackChanges(editor)` for tracked-change UI state
|
|
198
|
+
- `useDocxImageWrapMenu(editor)` for image wrapping controls
|
|
199
|
+
|
|
200
|
+
## Lower-level APIs
|
|
201
|
+
|
|
202
|
+
The package also re-exports the lower-level internals used by the viewer:
|
|
203
|
+
|
|
204
|
+
- OOXML parsing from `@extend-ai/react-docx-ooxml-core`
|
|
205
|
+
- Document model helpers from `@extend-ai/react-docx-doc-model`
|
|
206
|
+
- Editing operations from `@extend-ai/react-docx-editor-ops`
|
|
207
|
+
- Layout primitives from `@extend-ai/react-docx-layout-engine`
|
|
208
|
+
- Layout/core snapshot helpers from `@extend-ai/react-docx-layout-core`
|
|
209
|
+
- DOCX serialization from `@extend-ai/react-docx-serializer`
|
|
210
|
+
|
|
211
|
+
This means you can build your own pipeline, for example:
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
import {
|
|
215
|
+
buildDocModel,
|
|
216
|
+
parseDocx,
|
|
217
|
+
serializeDocx,
|
|
218
|
+
} from "@extend-ai/react-docx";
|
|
219
|
+
|
|
220
|
+
const pkg = await parseDocx(arrayBuffer);
|
|
221
|
+
const model = buildDocModel(pkg);
|
|
222
|
+
const output = serializeDocx(model, pkg);
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Viewer Notes
|
|
226
|
+
|
|
227
|
+
- `DocxEditorViewer` supports `mode="edit"` and `mode="read-only"`.
|
|
228
|
+
- `pageBackgroundColor` controls the page surface color.
|
|
229
|
+
- `pageGapBackgroundColor` controls the area between pages and defaults to transparent.
|
|
230
|
+
- In read-only dark document mode, the viewer uses an inversion-based night reader path so document content inverts cleanly while images keep their hues.
|
|
231
|
+
|
|
232
|
+
## License
|
|
233
|
+
|
|
234
|
+
See the repository license for usage terms.
|