@zeke-02/docx-editor 0.5.3 → 0.5.4
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/dist/{KeyboardShortcutsDialog-5D_FoAp6.d.ts → KeyboardShortcutsDialog-B0UFuR4w.d.ts} +2 -2
- package/dist/{KeyboardShortcutsDialog-D7ihAj18.d.mts → KeyboardShortcutsDialog-t6JKL4Aj.d.mts} +2 -2
- package/dist/PageSetupDialog-642IAVG2.js +1 -1
- package/dist/PageSetupDialog-ERUQDHAY.mjs +1 -1
- package/dist/PluginHost-HS31VIuo.d.mts +16 -0
- package/dist/PluginHost-zILZO7zX.d.ts +16 -0
- package/dist/{agentApi-D4AZmNfB.d.ts → agentApi-B2Y7kexW.d.ts} +1 -1
- package/dist/{agentApi-C41hiW-n.d.mts → agentApi-BzUJ_kao.d.mts} +1 -1
- package/dist/{chunk-E6MQXELR.js → chunk-HXDMASAR.js} +1 -1
- package/dist/chunk-JFRDFK7V.mjs +260 -0
- package/dist/{chunk-LUJ6HCMH.mjs → chunk-LWOHVYKW.mjs} +1 -1
- package/dist/chunk-MDTA25AN.mjs +60 -0
- package/dist/chunk-NOLMVQNN.mjs +40 -0
- package/dist/chunk-SGTUE33R.js +260 -0
- package/dist/chunk-WO3FIV4B.js +40 -0
- package/dist/{chunk-ONNHQWAX.mjs → chunk-XGJ2EORY.mjs} +1 -1
- package/dist/{chunk-AYMGSTNG.js → chunk-Y3SEHWZ2.js} +1 -1
- package/dist/chunk-YBEVHQCT.js +60 -0
- package/dist/{content-B2MzIMwA.d.mts → content-REFGFfEH.d.mts} +1 -1
- package/dist/{content-B2MzIMwA.d.ts → content-REFGFfEH.d.ts} +1 -1
- package/dist/dialogs.d.mts +4 -4
- package/dist/dialogs.d.ts +4 -4
- package/dist/dialogs.js +1 -1
- package/dist/dialogs.mjs +1 -1
- package/dist/{document-Di1qGqLS.d.mts → document-Cu2vq_wS.d.mts} +1 -1
- package/dist/{document-DZ_ZeZEH.d.ts → document-CxOagoLQ.d.ts} +1 -1
- package/dist/executor-WBHID2RK.mjs +1 -0
- package/dist/{executor-EPEB53SJ.js → executor-Y5VUOAHY.js} +1 -1
- package/dist/{findReplace-pkMskVJU.d.ts → findReplace-Bue0JaXh.d.ts} +1 -1
- package/dist/{findReplace-CpIoILbP.d.mts → findReplace-shXbOjFQ.d.mts} +1 -1
- package/dist/fork.css +1 -0
- package/dist/fork.d.mts +535 -0
- package/dist/fork.d.ts +535 -0
- package/dist/fork.js +1 -0
- package/dist/fork.mjs +1 -0
- package/dist/hooks.d.mts +6 -6
- package/dist/hooks.d.ts +6 -6
- package/dist/hooks.js +1 -1
- package/dist/hooks.mjs +1 -1
- package/dist/index-B5A-J9GC.d.ts +1119 -0
- package/dist/index-bw-PaozF.d.mts +1119 -0
- package/dist/index.d.mts +11 -1120
- package/dist/index.d.ts +11 -1120
- package/dist/index.js +1 -40
- package/dist/index.mjs +1 -40
- package/dist/plugin-api.d.mts +5 -16
- package/dist/plugin-api.d.ts +5 -16
- package/dist/plugin-api.js +1 -260
- package/dist/plugin-api.mjs +1 -260
- package/dist/{types-DZUhB7Ao.d.mts → types-BF48VxkC.d.mts} +1 -1
- package/dist/{types-DZUhB7Ao.d.ts → types-BF48VxkC.d.ts} +1 -1
- package/dist/{types-Bd_YzkhG.d.mts → types-BnIs4sE7.d.mts} +1 -1
- package/dist/{types-Bd_YzkhG.d.ts → types-BnIs4sE7.d.ts} +1 -1
- package/dist/{types-DcxHFUSc.d.ts → types-CW6HFAX6.d.ts} +1 -1
- package/dist/{types-CkfDgB0O.d.mts → types-DIsDCwTG.d.mts} +1 -1
- package/dist/ui.d.mts +9 -9
- package/dist/ui.d.ts +9 -9
- package/dist/ui.js +1 -1
- package/dist/ui.mjs +1 -1
- package/dist/{useFindReplace-eyhMSZZf.d.ts → useFindReplace-DKy-s3gS.d.ts} +2 -2
- package/dist/{useFindReplace-DDs533b-.d.mts → useFindReplace-vuoKpDKE.d.mts} +2 -2
- package/package.json +7 -7
- package/dist/chunk-47VJOBJD.mjs +0 -60
- package/dist/chunk-IP5NAYHL.js +0 -60
- package/dist/executor-TVJ6K6MW.mjs +0 -1
|
@@ -0,0 +1,1119 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ReactNode, CSSProperties } from 'react';
|
|
3
|
+
import * as prosemirror_view from 'prosemirror-view';
|
|
4
|
+
import { EditorView } from 'prosemirror-view';
|
|
5
|
+
import * as prosemirror_state from 'prosemirror-state';
|
|
6
|
+
import { EditorState, Transaction } from 'prosemirror-state';
|
|
7
|
+
import { D as Document, T as Theme } from './document-CxOagoLQ.js';
|
|
8
|
+
import { S as StyleInfo, A as AgentContext, P as Position, R as Range, a as AgentCommand, F as FontOption, b as PrintOptions } from './agentApi-B2Y7kexW.js';
|
|
9
|
+
import { R as RenderedDomContext, a as ReactSidebarItem } from './types-BnIs4sE7.js';
|
|
10
|
+
import { T as TextFormatting, P as ParagraphFormatting, C as Comment } from './content-REFGFfEH.js';
|
|
11
|
+
import { a as Translations, T as TranslationKey } from './types-BF48VxkC.js';
|
|
12
|
+
import { E as EditorHandle } from './types-CW6HFAX6.js';
|
|
13
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
14
|
+
|
|
15
|
+
interface LocaleProviderProps {
|
|
16
|
+
i18n?: Translations;
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
declare function LocaleProvider({ i18n, children }: LocaleProviderProps): react_jsx_runtime.JSX.Element;
|
|
20
|
+
declare function useTranslation(): {
|
|
21
|
+
t: (key: TranslationKey, vars?: Record<string, string | number>) => string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Selective Save Module
|
|
26
|
+
*
|
|
27
|
+
* Orchestrates selective XML patching for the save flow.
|
|
28
|
+
* Serializes full document.xml, validates patch safety, builds patched XML,
|
|
29
|
+
* and calls applyUpdatesToZip() to produce the final DOCX.
|
|
30
|
+
*
|
|
31
|
+
* Returns null on any failure, signaling the caller to fall back to full repack.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
interface SelectiveSaveOptions {
|
|
35
|
+
/** Changed paragraph IDs to selectively patch */
|
|
36
|
+
changedParaIds: Set<string>;
|
|
37
|
+
/** Whether structural changes occurred (paragraph add/delete) */
|
|
38
|
+
structuralChange: boolean;
|
|
39
|
+
/** Whether any changes affected paragraphs without paraId */
|
|
40
|
+
hasUntrackedChanges: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Flexible input types for DOCX documents.
|
|
45
|
+
*
|
|
46
|
+
* Accepts any common binary format so consumers don't need to manually
|
|
47
|
+
* convert before passing data to the editor or parser.
|
|
48
|
+
*/
|
|
49
|
+
/**
|
|
50
|
+
* Any binary representation of a DOCX file that the editor can consume.
|
|
51
|
+
*
|
|
52
|
+
* - `ArrayBuffer` — from `FileReader.readAsArrayBuffer()` or `fetch().arrayBuffer()`
|
|
53
|
+
* - `Uint8Array` — from Node.js `fs.readFile()` or streaming APIs
|
|
54
|
+
* - `Blob` — from drag-and-drop or `<input type="file">`
|
|
55
|
+
* - `File` — subclass of Blob, from `<input type="file">`
|
|
56
|
+
*/
|
|
57
|
+
type DocxInput = ArrayBuffer | Uint8Array | Blob | File;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* DocumentAgent - High-level fluent API for programmatic document manipulation
|
|
61
|
+
*
|
|
62
|
+
* Provides a convenient interface for:
|
|
63
|
+
* - Reading document content and metadata
|
|
64
|
+
* - Editing text with formatting
|
|
65
|
+
* - Inserting tables, images, and hyperlinks
|
|
66
|
+
* - Managing template variables
|
|
67
|
+
* - Exporting to DOCX buffer
|
|
68
|
+
*
|
|
69
|
+
* All operations are immutable - they return a new DocumentAgent instance
|
|
70
|
+
* or don't modify the underlying document.
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Options for inserting text
|
|
75
|
+
*/
|
|
76
|
+
interface InsertTextOptions {
|
|
77
|
+
/** Text formatting */
|
|
78
|
+
formatting?: TextFormatting;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Options for inserting table
|
|
82
|
+
*/
|
|
83
|
+
interface InsertTableOptions {
|
|
84
|
+
/** Table data (2D array of strings) */
|
|
85
|
+
data?: string[][];
|
|
86
|
+
/** Whether first row is a header */
|
|
87
|
+
hasHeader?: boolean;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Options for inserting image
|
|
91
|
+
*/
|
|
92
|
+
interface InsertImageOptions {
|
|
93
|
+
/** Image width in pixels */
|
|
94
|
+
width?: number;
|
|
95
|
+
/** Image height in pixels */
|
|
96
|
+
height?: number;
|
|
97
|
+
/** Alt text for accessibility */
|
|
98
|
+
alt?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Options for inserting hyperlink
|
|
102
|
+
*/
|
|
103
|
+
interface InsertHyperlinkOptions {
|
|
104
|
+
/** Display text (overrides selected text) */
|
|
105
|
+
displayText?: string;
|
|
106
|
+
/** Tooltip on hover */
|
|
107
|
+
tooltip?: string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Formatted text segment
|
|
111
|
+
*/
|
|
112
|
+
interface FormattedTextSegment {
|
|
113
|
+
/** Text content */
|
|
114
|
+
text: string;
|
|
115
|
+
/** Applied formatting */
|
|
116
|
+
formatting?: TextFormatting;
|
|
117
|
+
/** Is part of a hyperlink */
|
|
118
|
+
isHyperlink?: boolean;
|
|
119
|
+
/** Hyperlink URL if applicable */
|
|
120
|
+
hyperlinkUrl?: string;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* DocumentAgent provides a fluent API for document manipulation
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* const agent = new DocumentAgent(buffer);
|
|
128
|
+
*
|
|
129
|
+
* // Read operations
|
|
130
|
+
* const text = agent.getText();
|
|
131
|
+
* const wordCount = agent.getWordCount();
|
|
132
|
+
* const variables = agent.getVariables();
|
|
133
|
+
*
|
|
134
|
+
* // Write operations (returns new agent)
|
|
135
|
+
* const newAgent = agent
|
|
136
|
+
* .insertText({ paragraphIndex: 0, offset: 0 }, 'Hello ', { formatting: { bold: true } })
|
|
137
|
+
* .applyStyle({ paragraphIndex: 0, offset: 0 }, { paragraphIndex: 0, offset: 5 }, 'Heading1');
|
|
138
|
+
*
|
|
139
|
+
* // Export
|
|
140
|
+
* const newBuffer = await newAgent.toBuffer();
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
declare class DocumentAgent {
|
|
144
|
+
private _document;
|
|
145
|
+
private _pendingVariables;
|
|
146
|
+
/**
|
|
147
|
+
* Create a new DocumentAgent
|
|
148
|
+
*
|
|
149
|
+
* @param source - Document object or ArrayBuffer to parse
|
|
150
|
+
*/
|
|
151
|
+
constructor(source: Document | ArrayBuffer);
|
|
152
|
+
/**
|
|
153
|
+
* Create a DocumentAgent from a DOCX buffer (async)
|
|
154
|
+
*
|
|
155
|
+
* @param buffer - DOCX file as ArrayBuffer, Uint8Array, Blob, or File
|
|
156
|
+
* @returns Promise resolving to DocumentAgent
|
|
157
|
+
*/
|
|
158
|
+
static fromBuffer(buffer: DocxInput): Promise<DocumentAgent>;
|
|
159
|
+
/**
|
|
160
|
+
* Create a DocumentAgent from a Document object
|
|
161
|
+
*
|
|
162
|
+
* @param document - Parsed Document
|
|
163
|
+
* @returns DocumentAgent
|
|
164
|
+
*/
|
|
165
|
+
static fromDocument(document: Document): DocumentAgent;
|
|
166
|
+
/**
|
|
167
|
+
* Get the underlying document
|
|
168
|
+
*/
|
|
169
|
+
getDocument(): Document;
|
|
170
|
+
/**
|
|
171
|
+
* Get plain text content of the document
|
|
172
|
+
*
|
|
173
|
+
* @returns All document text concatenated
|
|
174
|
+
*/
|
|
175
|
+
getText(): string;
|
|
176
|
+
/**
|
|
177
|
+
* Get formatted text segments
|
|
178
|
+
*
|
|
179
|
+
* @returns Array of text segments with formatting info
|
|
180
|
+
*/
|
|
181
|
+
getFormattedText(): FormattedTextSegment[];
|
|
182
|
+
/**
|
|
183
|
+
* Get detected template variables
|
|
184
|
+
*
|
|
185
|
+
* @returns Array of variable names (without braces)
|
|
186
|
+
*/
|
|
187
|
+
getVariables(): string[];
|
|
188
|
+
/**
|
|
189
|
+
* Get available styles from the document
|
|
190
|
+
*
|
|
191
|
+
* @returns Array of style info
|
|
192
|
+
*/
|
|
193
|
+
getStyles(): StyleInfo[];
|
|
194
|
+
/**
|
|
195
|
+
* Get approximate page count
|
|
196
|
+
*
|
|
197
|
+
* Note: This is an estimate based on content length.
|
|
198
|
+
* Actual page count requires full layout computation.
|
|
199
|
+
*
|
|
200
|
+
* @returns Estimated page count
|
|
201
|
+
*/
|
|
202
|
+
getPageCount(): number;
|
|
203
|
+
/**
|
|
204
|
+
* Get word count
|
|
205
|
+
*
|
|
206
|
+
* @returns Number of words in the document
|
|
207
|
+
*/
|
|
208
|
+
getWordCount(): number;
|
|
209
|
+
/**
|
|
210
|
+
* Get character count
|
|
211
|
+
*
|
|
212
|
+
* @param includeSpaces - Whether to include whitespace
|
|
213
|
+
* @returns Number of characters
|
|
214
|
+
*/
|
|
215
|
+
getCharacterCount(includeSpaces?: boolean): number;
|
|
216
|
+
/**
|
|
217
|
+
* Get paragraph count
|
|
218
|
+
*
|
|
219
|
+
* @returns Number of paragraphs
|
|
220
|
+
*/
|
|
221
|
+
getParagraphCount(): number;
|
|
222
|
+
/**
|
|
223
|
+
* Get table count
|
|
224
|
+
*
|
|
225
|
+
* @returns Number of tables
|
|
226
|
+
*/
|
|
227
|
+
getTableCount(): number;
|
|
228
|
+
/**
|
|
229
|
+
* Get document context for AI agents
|
|
230
|
+
*
|
|
231
|
+
* @param outlineMaxChars - Max characters per paragraph in outline
|
|
232
|
+
* @returns Agent context
|
|
233
|
+
*/
|
|
234
|
+
getAgentContext(outlineMaxChars?: number): AgentContext;
|
|
235
|
+
/**
|
|
236
|
+
* Insert text at a position
|
|
237
|
+
*
|
|
238
|
+
* @param position - Where to insert
|
|
239
|
+
* @param text - Text to insert
|
|
240
|
+
* @param options - Insert options
|
|
241
|
+
* @returns New DocumentAgent with text inserted
|
|
242
|
+
*/
|
|
243
|
+
insertText(position: Position, text: string, options?: InsertTextOptions): DocumentAgent;
|
|
244
|
+
/**
|
|
245
|
+
* Replace text in a range
|
|
246
|
+
*
|
|
247
|
+
* @param range - Range to replace
|
|
248
|
+
* @param text - Replacement text
|
|
249
|
+
* @param options - Replace options
|
|
250
|
+
* @returns New DocumentAgent with text replaced
|
|
251
|
+
*/
|
|
252
|
+
replaceRange(range: Range, text: string, options?: InsertTextOptions): DocumentAgent;
|
|
253
|
+
/**
|
|
254
|
+
* Delete text in a range
|
|
255
|
+
*
|
|
256
|
+
* @param range - Range to delete
|
|
257
|
+
* @returns New DocumentAgent with text deleted
|
|
258
|
+
*/
|
|
259
|
+
deleteRange(range: Range): DocumentAgent;
|
|
260
|
+
/**
|
|
261
|
+
* Apply text formatting to a range
|
|
262
|
+
*
|
|
263
|
+
* @param range - Range to format
|
|
264
|
+
* @param formatting - Formatting to apply
|
|
265
|
+
* @returns New DocumentAgent with formatting applied
|
|
266
|
+
*/
|
|
267
|
+
applyFormatting(range: Range, formatting: Partial<TextFormatting>): DocumentAgent;
|
|
268
|
+
/**
|
|
269
|
+
* Apply a named style to a paragraph
|
|
270
|
+
*
|
|
271
|
+
* @param paragraphIndex - Index of the paragraph
|
|
272
|
+
* @param styleId - Style ID to apply
|
|
273
|
+
* @returns New DocumentAgent with style applied
|
|
274
|
+
*/
|
|
275
|
+
applyStyle(paragraphIndex: number, styleId: string): DocumentAgent;
|
|
276
|
+
/**
|
|
277
|
+
* Apply paragraph formatting
|
|
278
|
+
*
|
|
279
|
+
* @param paragraphIndex - Index of the paragraph
|
|
280
|
+
* @param formatting - Formatting to apply
|
|
281
|
+
* @returns New DocumentAgent with formatting applied
|
|
282
|
+
*/
|
|
283
|
+
applyParagraphFormatting(paragraphIndex: number, formatting: Partial<ParagraphFormatting>): DocumentAgent;
|
|
284
|
+
/**
|
|
285
|
+
* Insert a table at a position
|
|
286
|
+
*
|
|
287
|
+
* @param position - Where to insert the table
|
|
288
|
+
* @param rows - Number of rows
|
|
289
|
+
* @param cols - Number of columns
|
|
290
|
+
* @param options - Table options
|
|
291
|
+
* @returns New DocumentAgent with table inserted
|
|
292
|
+
*/
|
|
293
|
+
insertTable(position: Position, rows: number, cols: number, options?: InsertTableOptions): DocumentAgent;
|
|
294
|
+
/**
|
|
295
|
+
* Insert an image at a position
|
|
296
|
+
*
|
|
297
|
+
* @param position - Where to insert the image
|
|
298
|
+
* @param src - Image source (base64 data URL or URL)
|
|
299
|
+
* @param options - Image options
|
|
300
|
+
* @returns New DocumentAgent with image inserted
|
|
301
|
+
*/
|
|
302
|
+
insertImage(position: Position, src: string, options?: InsertImageOptions): DocumentAgent;
|
|
303
|
+
/**
|
|
304
|
+
* Insert a hyperlink
|
|
305
|
+
*
|
|
306
|
+
* @param range - Range to make into a hyperlink
|
|
307
|
+
* @param url - URL of the hyperlink
|
|
308
|
+
* @param options - Hyperlink options
|
|
309
|
+
* @returns New DocumentAgent with hyperlink inserted
|
|
310
|
+
*/
|
|
311
|
+
insertHyperlink(range: Range, url: string, options?: InsertHyperlinkOptions): DocumentAgent;
|
|
312
|
+
/**
|
|
313
|
+
* Remove a hyperlink but keep the text
|
|
314
|
+
*
|
|
315
|
+
* @param range - Range containing the hyperlink
|
|
316
|
+
* @returns New DocumentAgent with hyperlink removed
|
|
317
|
+
*/
|
|
318
|
+
removeHyperlink(range: Range): DocumentAgent;
|
|
319
|
+
/**
|
|
320
|
+
* Insert a paragraph break
|
|
321
|
+
*
|
|
322
|
+
* @param position - Where to break the paragraph
|
|
323
|
+
* @returns New DocumentAgent with paragraph broken
|
|
324
|
+
*/
|
|
325
|
+
insertParagraphBreak(position: Position): DocumentAgent;
|
|
326
|
+
/**
|
|
327
|
+
* Merge consecutive paragraphs
|
|
328
|
+
*
|
|
329
|
+
* @param startParagraphIndex - First paragraph index
|
|
330
|
+
* @param count - Number of paragraphs to merge with the first
|
|
331
|
+
* @returns New DocumentAgent with paragraphs merged
|
|
332
|
+
*/
|
|
333
|
+
mergeParagraphs(startParagraphIndex: number, count: number): DocumentAgent;
|
|
334
|
+
/**
|
|
335
|
+
* Set a template variable value
|
|
336
|
+
*
|
|
337
|
+
* Note: Variables are not applied until `applyVariables()` is called
|
|
338
|
+
*
|
|
339
|
+
* @param name - Variable name (without braces)
|
|
340
|
+
* @param value - Variable value
|
|
341
|
+
* @returns This DocumentAgent (for chaining)
|
|
342
|
+
*/
|
|
343
|
+
setVariable(name: string, value: string): DocumentAgent;
|
|
344
|
+
/**
|
|
345
|
+
* Set multiple template variables
|
|
346
|
+
*
|
|
347
|
+
* @param variables - Map of variable names to values
|
|
348
|
+
* @returns This DocumentAgent (for chaining)
|
|
349
|
+
*/
|
|
350
|
+
setVariables(variables: Record<string, string>): DocumentAgent;
|
|
351
|
+
/**
|
|
352
|
+
* Get pending variable values
|
|
353
|
+
*
|
|
354
|
+
* @returns Map of pending variable values
|
|
355
|
+
*/
|
|
356
|
+
getPendingVariables(): Record<string, string>;
|
|
357
|
+
/**
|
|
358
|
+
* Clear pending variables
|
|
359
|
+
*
|
|
360
|
+
* @returns This DocumentAgent (for chaining)
|
|
361
|
+
*/
|
|
362
|
+
clearPendingVariables(): DocumentAgent;
|
|
363
|
+
/**
|
|
364
|
+
* Apply all pending template variables
|
|
365
|
+
*
|
|
366
|
+
* Uses docxtemplater to substitute variables while preserving formatting.
|
|
367
|
+
*
|
|
368
|
+
* @param variables - Optional additional variables (merged with pending)
|
|
369
|
+
* @returns New DocumentAgent with variables applied
|
|
370
|
+
*/
|
|
371
|
+
applyVariables(variables?: Record<string, string>): Promise<DocumentAgent>;
|
|
372
|
+
/**
|
|
373
|
+
* Export document to DOCX ArrayBuffer
|
|
374
|
+
*
|
|
375
|
+
* @returns Promise resolving to DOCX file as ArrayBuffer
|
|
376
|
+
*/
|
|
377
|
+
toBuffer(options?: {
|
|
378
|
+
selective?: SelectiveSaveOptions;
|
|
379
|
+
}): Promise<ArrayBuffer>;
|
|
380
|
+
/**
|
|
381
|
+
* Export document to Blob
|
|
382
|
+
*
|
|
383
|
+
* @param mimeType - MIME type for the blob
|
|
384
|
+
* @returns Promise resolving to DOCX file as Blob
|
|
385
|
+
*/
|
|
386
|
+
toBlob(mimeType?: string): Promise<Blob>;
|
|
387
|
+
/**
|
|
388
|
+
* Execute multiple commands in sequence
|
|
389
|
+
*
|
|
390
|
+
* @param commands - Commands to execute
|
|
391
|
+
* @returns New DocumentAgent with all commands applied
|
|
392
|
+
*/
|
|
393
|
+
executeCommands(commands: AgentCommand[]): DocumentAgent;
|
|
394
|
+
/**
|
|
395
|
+
* Execute a single command and return new agent
|
|
396
|
+
*/
|
|
397
|
+
private _executeCommand;
|
|
398
|
+
/**
|
|
399
|
+
* Get plain text from document body
|
|
400
|
+
*/
|
|
401
|
+
private _getBodyText;
|
|
402
|
+
/**
|
|
403
|
+
* Get plain text from a paragraph
|
|
404
|
+
*/
|
|
405
|
+
private _getParagraphText;
|
|
406
|
+
/**
|
|
407
|
+
* Get plain text from a run
|
|
408
|
+
*/
|
|
409
|
+
private _getRunText;
|
|
410
|
+
/**
|
|
411
|
+
* Get plain text from a hyperlink
|
|
412
|
+
*/
|
|
413
|
+
private _getHyperlinkText;
|
|
414
|
+
/**
|
|
415
|
+
* Get plain text from a table
|
|
416
|
+
*/
|
|
417
|
+
private _getTableText;
|
|
418
|
+
/**
|
|
419
|
+
* Extract formatted text segments from a paragraph
|
|
420
|
+
*/
|
|
421
|
+
private _extractParagraphSegments;
|
|
422
|
+
/**
|
|
423
|
+
* Parse heading level from style ID
|
|
424
|
+
*/
|
|
425
|
+
private _parseHeadingLevel;
|
|
426
|
+
/**
|
|
427
|
+
* Check if document has images
|
|
428
|
+
*/
|
|
429
|
+
private _hasImages;
|
|
430
|
+
/**
|
|
431
|
+
* Check if document has hyperlinks
|
|
432
|
+
*/
|
|
433
|
+
private _hasHyperlinks;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Selection State Utilities
|
|
438
|
+
*
|
|
439
|
+
* Extracts selection state from ProseMirror for toolbar integration.
|
|
440
|
+
*/
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Selection state for toolbar integration
|
|
444
|
+
*/
|
|
445
|
+
interface SelectionState {
|
|
446
|
+
/** Whether there's an active selection (not just cursor) */
|
|
447
|
+
hasSelection: boolean;
|
|
448
|
+
/** Whether selection spans multiple paragraphs */
|
|
449
|
+
isMultiParagraph: boolean;
|
|
450
|
+
/** Current text formatting at selection/cursor */
|
|
451
|
+
textFormatting: TextFormatting;
|
|
452
|
+
/** Current paragraph formatting */
|
|
453
|
+
paragraphFormatting: ParagraphFormatting;
|
|
454
|
+
/** Current paragraph style ID (e.g., 'Heading1', 'Normal') */
|
|
455
|
+
styleId: string | null;
|
|
456
|
+
/** Start paragraph index */
|
|
457
|
+
startParagraphIndex: number;
|
|
458
|
+
/** End paragraph index */
|
|
459
|
+
endParagraphIndex: number;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Layout Engine Types
|
|
464
|
+
*
|
|
465
|
+
* Core types for the paginated layout engine.
|
|
466
|
+
* Converts document blocks + measurements into positioned fragments on pages.
|
|
467
|
+
*/
|
|
468
|
+
/**
|
|
469
|
+
* Unique identifier for a block in the document.
|
|
470
|
+
* Format: typically `${index}-${type}` or just the block index.
|
|
471
|
+
*/
|
|
472
|
+
type BlockId = string | number;
|
|
473
|
+
/**
|
|
474
|
+
* Base fragment properties common to all fragment types.
|
|
475
|
+
*/
|
|
476
|
+
type FragmentBase = {
|
|
477
|
+
/** Block ID this fragment belongs to. */
|
|
478
|
+
blockId: BlockId;
|
|
479
|
+
/** X position on page (relative to page left). */
|
|
480
|
+
x: number;
|
|
481
|
+
/** Y position on page (relative to page top). */
|
|
482
|
+
y: number;
|
|
483
|
+
/** Width of the fragment. */
|
|
484
|
+
width: number;
|
|
485
|
+
/** ProseMirror start position (for click mapping). */
|
|
486
|
+
pmStart?: number;
|
|
487
|
+
/** ProseMirror end position (for click mapping). */
|
|
488
|
+
pmEnd?: number;
|
|
489
|
+
};
|
|
490
|
+
/**
|
|
491
|
+
* A paragraph fragment positioned on a page.
|
|
492
|
+
* May span only part of the paragraph's lines if split across pages.
|
|
493
|
+
*/
|
|
494
|
+
type ParagraphFragment = FragmentBase & {
|
|
495
|
+
kind: 'paragraph';
|
|
496
|
+
/** First line index (inclusive) from the measure. */
|
|
497
|
+
fromLine: number;
|
|
498
|
+
/** Last line index (exclusive) from the measure. */
|
|
499
|
+
toLine: number;
|
|
500
|
+
/** Height of this fragment. */
|
|
501
|
+
height: number;
|
|
502
|
+
/** True if this continues from a previous page. */
|
|
503
|
+
continuesFromPrev?: boolean;
|
|
504
|
+
/** True if this continues onto the next page. */
|
|
505
|
+
continuesOnNext?: boolean;
|
|
506
|
+
};
|
|
507
|
+
/**
|
|
508
|
+
* A table fragment positioned on a page.
|
|
509
|
+
* May span only part of the table's rows if split across pages.
|
|
510
|
+
*/
|
|
511
|
+
type TableFragment = FragmentBase & {
|
|
512
|
+
kind: 'table';
|
|
513
|
+
/** First row index (inclusive). */
|
|
514
|
+
fromRow: number;
|
|
515
|
+
/** Last row index (exclusive). */
|
|
516
|
+
toRow: number;
|
|
517
|
+
/** Height of this fragment. */
|
|
518
|
+
height: number;
|
|
519
|
+
/** True if this is a floating table. */
|
|
520
|
+
isFloating?: boolean;
|
|
521
|
+
/** True if this continues from a previous page. */
|
|
522
|
+
continuesFromPrev?: boolean;
|
|
523
|
+
/** True if this continues onto the next page. */
|
|
524
|
+
continuesOnNext?: boolean;
|
|
525
|
+
/** Number of header rows prepended to this continuation fragment (0 or undefined for first fragment). */
|
|
526
|
+
headerRowCount?: number;
|
|
527
|
+
};
|
|
528
|
+
/**
|
|
529
|
+
* An image fragment positioned on a page.
|
|
530
|
+
*/
|
|
531
|
+
type ImageFragment = FragmentBase & {
|
|
532
|
+
kind: 'image';
|
|
533
|
+
/** Height of the image. */
|
|
534
|
+
height: number;
|
|
535
|
+
/** True if this is an anchored/floating image. */
|
|
536
|
+
isAnchored?: boolean;
|
|
537
|
+
/** Z-index for layering. */
|
|
538
|
+
zIndex?: number;
|
|
539
|
+
};
|
|
540
|
+
/**
|
|
541
|
+
* A text box fragment positioned on a page.
|
|
542
|
+
*/
|
|
543
|
+
type TextBoxFragment = FragmentBase & {
|
|
544
|
+
kind: 'textBox';
|
|
545
|
+
/** Height of the text box. */
|
|
546
|
+
height: number;
|
|
547
|
+
/** True when positioned outside normal document flow. */
|
|
548
|
+
isFloating?: boolean;
|
|
549
|
+
/** Stack order hint for anchored text boxes. */
|
|
550
|
+
zIndex?: number;
|
|
551
|
+
};
|
|
552
|
+
/**
|
|
553
|
+
* Union of all fragment types.
|
|
554
|
+
*/
|
|
555
|
+
type Fragment = ParagraphFragment | TableFragment | ImageFragment | TextBoxFragment;
|
|
556
|
+
/**
|
|
557
|
+
* Page margin configuration.
|
|
558
|
+
*/
|
|
559
|
+
type PageMargins = {
|
|
560
|
+
top: number;
|
|
561
|
+
right: number;
|
|
562
|
+
bottom: number;
|
|
563
|
+
left: number;
|
|
564
|
+
/** Distance from page top to header content. */
|
|
565
|
+
header?: number;
|
|
566
|
+
/** Distance from page bottom to footer content. */
|
|
567
|
+
footer?: number;
|
|
568
|
+
};
|
|
569
|
+
/**
|
|
570
|
+
* A rendered page containing positioned fragments.
|
|
571
|
+
*/
|
|
572
|
+
type Page = {
|
|
573
|
+
/** Page number (1-indexed). */
|
|
574
|
+
number: number;
|
|
575
|
+
/** Fragments positioned on this page. */
|
|
576
|
+
fragments: Fragment[];
|
|
577
|
+
/** Page margins. */
|
|
578
|
+
margins: PageMargins;
|
|
579
|
+
/** Page size (width, height). */
|
|
580
|
+
size: {
|
|
581
|
+
w: number;
|
|
582
|
+
h: number;
|
|
583
|
+
};
|
|
584
|
+
/** Page orientation. */
|
|
585
|
+
orientation?: 'portrait' | 'landscape';
|
|
586
|
+
/** Section index this page belongs to. */
|
|
587
|
+
sectionIndex?: number;
|
|
588
|
+
/** Header/footer references for this page. */
|
|
589
|
+
headerFooterRefs?: {
|
|
590
|
+
headerDefault?: string;
|
|
591
|
+
headerFirst?: string;
|
|
592
|
+
headerEven?: string;
|
|
593
|
+
footerDefault?: string;
|
|
594
|
+
footerFirst?: string;
|
|
595
|
+
footerEven?: string;
|
|
596
|
+
};
|
|
597
|
+
/** Footnote IDs that appear on this page (for rendering). */
|
|
598
|
+
footnoteIds?: number[];
|
|
599
|
+
/** Height reserved for the footnote area at page bottom (pixels). */
|
|
600
|
+
footnoteReservedHeight?: number;
|
|
601
|
+
/** Column layout for this page (if multi-column). */
|
|
602
|
+
columns?: ColumnLayout;
|
|
603
|
+
};
|
|
604
|
+
/**
|
|
605
|
+
* Column layout configuration.
|
|
606
|
+
*/
|
|
607
|
+
type ColumnLayout = {
|
|
608
|
+
count: number;
|
|
609
|
+
gap: number;
|
|
610
|
+
equalWidth?: boolean;
|
|
611
|
+
/** Draw vertical separator line between columns (w:sep). */
|
|
612
|
+
separator?: boolean;
|
|
613
|
+
};
|
|
614
|
+
/**
|
|
615
|
+
* Header/footer layout for a specific type.
|
|
616
|
+
*/
|
|
617
|
+
type HeaderFooterLayout = {
|
|
618
|
+
height: number;
|
|
619
|
+
fragments: Fragment[];
|
|
620
|
+
};
|
|
621
|
+
/**
|
|
622
|
+
* Final layout output ready for rendering/painting.
|
|
623
|
+
*/
|
|
624
|
+
type Layout = {
|
|
625
|
+
/** Default page size for the document. */
|
|
626
|
+
pageSize: {
|
|
627
|
+
w: number;
|
|
628
|
+
h: number;
|
|
629
|
+
};
|
|
630
|
+
/** All rendered pages with positioned fragments. */
|
|
631
|
+
pages: Page[];
|
|
632
|
+
/** Column configuration (if multi-column). */
|
|
633
|
+
columns?: ColumnLayout;
|
|
634
|
+
/** Header layouts by type (default, first, even). */
|
|
635
|
+
headers?: Record<string, HeaderFooterLayout>;
|
|
636
|
+
/** Footer layouts by type (default, first, even). */
|
|
637
|
+
footers?: Record<string, HeaderFooterLayout>;
|
|
638
|
+
/** Gap between pages in pixels (for rendering). */
|
|
639
|
+
pageGap?: number;
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
interface PagedEditorRef {
|
|
643
|
+
/** Get the current document. */
|
|
644
|
+
getDocument(): Document | null;
|
|
645
|
+
/** Get the ProseMirror EditorState. */
|
|
646
|
+
getState(): EditorState | null;
|
|
647
|
+
/** Get the ProseMirror EditorView. */
|
|
648
|
+
getView(): EditorView | null;
|
|
649
|
+
/** Focus the editor. */
|
|
650
|
+
focus(): void;
|
|
651
|
+
/** Blur the editor. */
|
|
652
|
+
blur(): void;
|
|
653
|
+
/** Check if focused. */
|
|
654
|
+
isFocused(): boolean;
|
|
655
|
+
/** Dispatch a transaction. */
|
|
656
|
+
dispatch(tr: Transaction): void;
|
|
657
|
+
/** Undo. */
|
|
658
|
+
undo(): boolean;
|
|
659
|
+
/** Redo. */
|
|
660
|
+
redo(): boolean;
|
|
661
|
+
/** Set selection by PM position. */
|
|
662
|
+
setSelection(anchor: number, head?: number): void;
|
|
663
|
+
/** Get current layout. */
|
|
664
|
+
getLayout(): Layout | null;
|
|
665
|
+
/** Force re-layout. */
|
|
666
|
+
relayout(): void;
|
|
667
|
+
/** Scroll the visible pages to bring a PM position into view. */
|
|
668
|
+
scrollToPosition(pmPos: number): void;
|
|
669
|
+
/**
|
|
670
|
+
* Scroll to the paragraph identified by Word `w14:paraId` / PM `paraId`.
|
|
671
|
+
* @returns whether a matching paragraph was found
|
|
672
|
+
*/
|
|
673
|
+
scrollToParaId(paraId: string): boolean;
|
|
674
|
+
/**
|
|
675
|
+
* Scroll the paginated view so `pageNumber` (1-indexed) is in view.
|
|
676
|
+
* No-op if the layout isn't ready yet or pageNumber is out of range.
|
|
677
|
+
*/
|
|
678
|
+
scrollToPage(pageNumber: number): void;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* DocxEditor props
|
|
683
|
+
*/
|
|
684
|
+
interface DocxEditorProps {
|
|
685
|
+
/** Document data — ArrayBuffer, Uint8Array, Blob, or File */
|
|
686
|
+
documentBuffer?: DocxInput | null;
|
|
687
|
+
/** Pre-parsed document (alternative to documentBuffer) */
|
|
688
|
+
document?: Document | null;
|
|
689
|
+
/** Callback when document is saved */
|
|
690
|
+
onSave?: (buffer: ArrayBuffer) => void;
|
|
691
|
+
/** Author name used for comments and track changes */
|
|
692
|
+
author?: string;
|
|
693
|
+
/** Callback when document changes */
|
|
694
|
+
onChange?: (document: Document) => void;
|
|
695
|
+
/** Callback when selection changes */
|
|
696
|
+
onSelectionChange?: (state: SelectionState | null) => void;
|
|
697
|
+
/** Callback on error */
|
|
698
|
+
onError?: (error: Error) => void;
|
|
699
|
+
/** Callback when fonts are loaded */
|
|
700
|
+
onFontsLoaded?: () => void;
|
|
701
|
+
/** External ProseMirror plugins (from PluginHost) */
|
|
702
|
+
externalPlugins?: prosemirror_state.Plugin[];
|
|
703
|
+
/**
|
|
704
|
+
* When true, the editor treats the `document` prop as a schema seed only and
|
|
705
|
+
* does not load it into ProseMirror on mount. Content is expected to come from
|
|
706
|
+
* external sources — typically `externalPlugins` such as `ySyncPlugin` from
|
|
707
|
+
* `y-prosemirror`, but also any code that dispatches transactions directly.
|
|
708
|
+
*
|
|
709
|
+
* You must still pass a `document` prop (e.g., `createEmptyDocument()`) so the
|
|
710
|
+
* editor can build its schema and render the shell.
|
|
711
|
+
*/
|
|
712
|
+
externalContent?: boolean;
|
|
713
|
+
/** Callback when editor view is ready (for PluginHost) */
|
|
714
|
+
onEditorViewReady?: (view: prosemirror_view.EditorView) => void;
|
|
715
|
+
/** Theme for styling */
|
|
716
|
+
theme?: Theme | null;
|
|
717
|
+
/** Whether to show toolbar (default: true) */
|
|
718
|
+
showToolbar?: boolean;
|
|
719
|
+
/** Whether to show zoom control (default: true) */
|
|
720
|
+
showZoomControl?: boolean;
|
|
721
|
+
/** Whether to show page margin guides/boundaries (default: false) */
|
|
722
|
+
showMarginGuides?: boolean;
|
|
723
|
+
/** Color for margin guides (default: '#c0c0c0') */
|
|
724
|
+
marginGuideColor?: string;
|
|
725
|
+
/** Whether to show horizontal ruler (default: false) */
|
|
726
|
+
showRuler?: boolean;
|
|
727
|
+
/** Unit for ruler display (default: 'inch') */
|
|
728
|
+
rulerUnit?: 'inch' | 'cm';
|
|
729
|
+
/** Initial zoom level (default: 1.0) */
|
|
730
|
+
initialZoom?: number;
|
|
731
|
+
/** Whether the editor is read-only. When true, hides toolbar and rulers */
|
|
732
|
+
readOnly?: boolean;
|
|
733
|
+
/**
|
|
734
|
+
* When true, the editor does not intercept Cmd/Ctrl+F or Cmd/Ctrl+H.
|
|
735
|
+
* This lets the browser or host app handle native find/history shortcuts.
|
|
736
|
+
*/
|
|
737
|
+
disableFindReplaceShortcuts?: boolean;
|
|
738
|
+
/** Custom toolbar actions */
|
|
739
|
+
toolbarExtra?: ReactNode;
|
|
740
|
+
/** Additional CSS class name */
|
|
741
|
+
className?: string;
|
|
742
|
+
/** Additional inline styles */
|
|
743
|
+
style?: CSSProperties;
|
|
744
|
+
/** Placeholder when no document */
|
|
745
|
+
placeholder?: ReactNode;
|
|
746
|
+
/** Loading indicator */
|
|
747
|
+
loadingIndicator?: ReactNode;
|
|
748
|
+
/** Whether to show the document outline sidebar (default: false) */
|
|
749
|
+
showOutline?: boolean;
|
|
750
|
+
/** Whether to show the floating outline toggle button (default: true) */
|
|
751
|
+
showOutlineButton?: boolean;
|
|
752
|
+
/**
|
|
753
|
+
* Custom list of fonts shown in the toolbar's font-family dropdown.
|
|
754
|
+
* Strings render in the "Other" group; pass `FontOption[]` for category
|
|
755
|
+
* grouping and CSS fallback chains. Omit to use the built-in 12-font
|
|
756
|
+
* default. An empty array renders an empty (but enabled) dropdown.
|
|
757
|
+
*
|
|
758
|
+
* Pass a stable reference (memoized or module-level) — inline arrays
|
|
759
|
+
* create a new identity per render and invalidate the picker's memo.
|
|
760
|
+
*
|
|
761
|
+
* @example fontFamilies={['Arial', 'Roboto']}
|
|
762
|
+
* @example fontFamilies={[{ name: 'Roboto', fontFamily: 'Roboto, sans-serif', category: 'sans-serif' }]}
|
|
763
|
+
*/
|
|
764
|
+
fontFamilies?: ReadonlyArray<string | FontOption>;
|
|
765
|
+
/** Whether to show print button in toolbar (default: true) */
|
|
766
|
+
showPrintButton?: boolean;
|
|
767
|
+
/** Whether to show the editing mode switcher (Editing/Suggesting/Viewing) in toolbar (default: true) */
|
|
768
|
+
showModeSwitcher?: boolean;
|
|
769
|
+
/** Whether to show the comments sidebar toggle button in toolbar (default: true) */
|
|
770
|
+
showCommentsSidebarToggle?: boolean;
|
|
771
|
+
/** Print options for print preview */
|
|
772
|
+
printOptions?: PrintOptions;
|
|
773
|
+
/**
|
|
774
|
+
* Callback when print is triggered. Pass it to enable the `File > Print`
|
|
775
|
+
* menu entry; omit to hide. The imperative `ref.current.print()` also
|
|
776
|
+
* invokes this callback.
|
|
777
|
+
*/
|
|
778
|
+
onPrint?: () => void;
|
|
779
|
+
/** Callback when content is copied */
|
|
780
|
+
onCopy?: () => void;
|
|
781
|
+
/** Callback when content is cut */
|
|
782
|
+
onCut?: () => void;
|
|
783
|
+
/** Callback when content is pasted */
|
|
784
|
+
onPaste?: () => void;
|
|
785
|
+
/** Editor mode: 'editing' (direct edits), 'suggesting' (track changes), or 'viewing' (read-only). Default: 'editing' */
|
|
786
|
+
mode?: EditorMode;
|
|
787
|
+
/** Callback when the editing mode changes */
|
|
788
|
+
onModeChange?: (mode: EditorMode) => void;
|
|
789
|
+
/** Callback when a comment is added via the UI */
|
|
790
|
+
onCommentAdd?: (comment: Comment) => void;
|
|
791
|
+
/** Callback when a comment is resolved via the UI */
|
|
792
|
+
onCommentResolve?: (comment: Comment) => void;
|
|
793
|
+
/** Callback when a comment is deleted via the UI */
|
|
794
|
+
onCommentDelete?: (comment: Comment) => void;
|
|
795
|
+
/** Callback when a reply is added to a comment via the UI */
|
|
796
|
+
onCommentReply?: (reply: Comment, parent: Comment) => void;
|
|
797
|
+
/**
|
|
798
|
+
* Controlled comments array. When provided, the editor reads comment thread
|
|
799
|
+
* metadata (text, author, replies, resolved status) from this prop instead
|
|
800
|
+
* of internal state, and emits every change through `onCommentsChange`.
|
|
801
|
+
*
|
|
802
|
+
* Use this with collaboration backends (Yjs, Liveblocks, Automerge, …) so
|
|
803
|
+
* comment threads sync across peers — the PM document only carries the
|
|
804
|
+
* range markers; thread metadata lives outside the doc and needs its own
|
|
805
|
+
* sync channel.
|
|
806
|
+
*
|
|
807
|
+
* If omitted, the editor falls back to internal state (current behavior).
|
|
808
|
+
* The granular `onCommentAdd`/`onCommentResolve`/`onCommentDelete`/
|
|
809
|
+
* `onCommentReply` callbacks fire in both modes.
|
|
810
|
+
*/
|
|
811
|
+
comments?: Comment[];
|
|
812
|
+
/** Fires whenever the comments array changes (controlled mode). */
|
|
813
|
+
onCommentsChange?: (comments: Comment[]) => void;
|
|
814
|
+
/**
|
|
815
|
+
* Callback when rendered DOM context is ready (for plugin overlays).
|
|
816
|
+
* Used by PluginHost to get access to the rendered page DOM for positioning.
|
|
817
|
+
*/
|
|
818
|
+
onRenderedDomContextReady?: (context: RenderedDomContext) => void;
|
|
819
|
+
/**
|
|
820
|
+
* Plugin overlays to render inside the editor viewport.
|
|
821
|
+
* Passed from PluginHost to render plugin-specific overlays.
|
|
822
|
+
*/
|
|
823
|
+
pluginOverlays?: ReactNode;
|
|
824
|
+
/** Sidebar items from plugins (passed from PluginHost). */
|
|
825
|
+
pluginSidebarItems?: ReactSidebarItem[];
|
|
826
|
+
/** Rendered DOM context from PluginHost (for sidebar position resolution). */
|
|
827
|
+
pluginRenderedDomContext?: RenderedDomContext | null;
|
|
828
|
+
/** Custom logo/icon for the title bar */
|
|
829
|
+
renderLogo?: () => ReactNode;
|
|
830
|
+
/** Document name shown in the title bar */
|
|
831
|
+
documentName?: string;
|
|
832
|
+
/** Callback when document name changes */
|
|
833
|
+
onDocumentNameChange?: (name: string) => void;
|
|
834
|
+
/** Whether the document name is editable (default: true) */
|
|
835
|
+
documentNameEditable?: boolean;
|
|
836
|
+
/** Custom right-side actions for the title bar */
|
|
837
|
+
renderTitleBarRight?: () => ReactNode;
|
|
838
|
+
/** Translation overrides. Import a locale JSON file and pass it directly. */
|
|
839
|
+
i18n?: Translations;
|
|
840
|
+
/**
|
|
841
|
+
* Mount a controllable agent panel on the right side of the editor. The
|
|
842
|
+
* panel is the chrome (header, close button, drag-resize); the consumer
|
|
843
|
+
* supplies whatever content goes inside via `render` — typically a chat
|
|
844
|
+
* UI from `@ai-sdk/react`'s `useChat`, `assistant-ui`, or any other
|
|
845
|
+
* framework. We do not ship message bubbles, a composer, or a chat engine.
|
|
846
|
+
*
|
|
847
|
+
* Three control patterns:
|
|
848
|
+
* - **Uncontrolled**: `agentPanel={{ render }}` — toolbar button + panel
|
|
849
|
+
* close button toggle the panel. Width persists to localStorage.
|
|
850
|
+
* - **Controlled**: `agentPanel={{ render, open, onOpenChange }}` — the
|
|
851
|
+
* consumer owns open state (e.g. tied to a global menu).
|
|
852
|
+
* - **Headless**: omit `agentPanel`, use the toolkit directly via
|
|
853
|
+
* `useDocxAgentTools` — render the panel anywhere you want.
|
|
854
|
+
*/
|
|
855
|
+
agentPanel?: {
|
|
856
|
+
/** Render-prop returning the panel content. Called only when open. */
|
|
857
|
+
render: (ctx: {
|
|
858
|
+
close: () => void;
|
|
859
|
+
}) => ReactNode;
|
|
860
|
+
/** Controlled open state. Omit for uncontrolled. */
|
|
861
|
+
open?: boolean;
|
|
862
|
+
/** Fires when toolbar button or panel close button is clicked. */
|
|
863
|
+
onOpenChange?: (open: boolean) => void;
|
|
864
|
+
/** Show the toolbar toggle button. Default: true. */
|
|
865
|
+
showToolbarButton?: boolean;
|
|
866
|
+
/** Optional badge / dot on the toolbar button. */
|
|
867
|
+
toolbarBadge?: ReactNode;
|
|
868
|
+
/** Optional panel title. Default: t('agentPanel.defaultTitle'). */
|
|
869
|
+
title?: string;
|
|
870
|
+
/** Optional panel header icon. Default: sparkle. */
|
|
871
|
+
icon?: ReactNode;
|
|
872
|
+
/** Initial panel width in px (uncontrolled). Default: 360. */
|
|
873
|
+
defaultWidth?: number;
|
|
874
|
+
/** Min drag width. Default: 280. */
|
|
875
|
+
minWidth?: number;
|
|
876
|
+
/** Max drag width. Default: 600. */
|
|
877
|
+
maxWidth?: number;
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* DocxEditor ref interface
|
|
882
|
+
*/
|
|
883
|
+
interface DocxEditorRef {
|
|
884
|
+
/** Get the DocumentAgent for programmatic access */
|
|
885
|
+
getAgent: () => DocumentAgent | null;
|
|
886
|
+
/** Get the current document */
|
|
887
|
+
getDocument: () => Document | null;
|
|
888
|
+
/** Get the editor ref */
|
|
889
|
+
getEditorRef: () => PagedEditorRef | null;
|
|
890
|
+
/** Save the document to buffer. Pass { selective: false } to force full repack. */
|
|
891
|
+
save: (options?: {
|
|
892
|
+
selective?: boolean;
|
|
893
|
+
}) => Promise<ArrayBuffer | null>;
|
|
894
|
+
/** Set zoom level */
|
|
895
|
+
setZoom: (zoom: number) => void;
|
|
896
|
+
/** Get current zoom level */
|
|
897
|
+
getZoom: () => number;
|
|
898
|
+
/** Focus the editor */
|
|
899
|
+
focus: () => void;
|
|
900
|
+
/** Get current page number */
|
|
901
|
+
getCurrentPage: () => number;
|
|
902
|
+
/** Get total page count */
|
|
903
|
+
getTotalPages: () => number;
|
|
904
|
+
/**
|
|
905
|
+
* Scroll the paginated view so the given page is in view.
|
|
906
|
+
* Page numbers are 1-indexed (matches `getCurrentPage` / `getTotalPages`).
|
|
907
|
+
* No-op for out-of-range or non-integer values.
|
|
908
|
+
* @example ref.current?.scrollToPage(2)
|
|
909
|
+
*/
|
|
910
|
+
scrollToPage: (pageNumber: number) => void;
|
|
911
|
+
/**
|
|
912
|
+
* Scroll the paginated view to the paragraph with the given Word `w14:paraId`.
|
|
913
|
+
* @returns whether a matching paragraph exists in the ProseMirror document
|
|
914
|
+
* @example ref.current?.scrollToParaId('1A2B3C4D')
|
|
915
|
+
*/
|
|
916
|
+
scrollToParaId: (paraId: string) => boolean;
|
|
917
|
+
/**
|
|
918
|
+
* Scroll the paginated view to a specific ProseMirror document position.
|
|
919
|
+
* Use this when you have a raw PM offset; for Word `w14:paraId` use
|
|
920
|
+
* `scrollToParaId` instead.
|
|
921
|
+
* @example ref.current?.scrollToPosition(42)
|
|
922
|
+
*/
|
|
923
|
+
scrollToPosition: (pmPos: number) => void;
|
|
924
|
+
/** Open print preview */
|
|
925
|
+
openPrintPreview: () => void;
|
|
926
|
+
/** Print the document directly */
|
|
927
|
+
print: () => void;
|
|
928
|
+
/** Load a pre-parsed document programmatically */
|
|
929
|
+
loadDocument: (doc: Document) => void;
|
|
930
|
+
/** Load a DOCX buffer programmatically (ArrayBuffer, Uint8Array, Blob, or File) */
|
|
931
|
+
loadDocumentBuffer: (buffer: DocxInput) => Promise<void>;
|
|
932
|
+
/**
|
|
933
|
+
* Apply document changes from a DocumentAgent while preserving undo history.
|
|
934
|
+
* This dispatches a PM transaction that replaces the document content,
|
|
935
|
+
* allowing undo/redo to work with agent-made changes.
|
|
936
|
+
*
|
|
937
|
+
* @param doc - The modified Document from an agent
|
|
938
|
+
* @returns true if the changes were applied, false if the editor is not ready
|
|
939
|
+
*
|
|
940
|
+
* @example
|
|
941
|
+
* ```ts
|
|
942
|
+
* const agent = EnhancedDocumentAgent.fromDocument(editorRef.current.getDocument());
|
|
943
|
+
* const updated = agent.toggleBulletList([0, 1, 2]).getDocument();
|
|
944
|
+
* editorRef.current.applyDocumentChanges(updated);
|
|
945
|
+
* // Ctrl+Z will undo the bullet list changes
|
|
946
|
+
* ```
|
|
947
|
+
*/
|
|
948
|
+
applyDocumentChanges: (doc: Document) => boolean;
|
|
949
|
+
/** Add a comment programmatically. Anchored by Word `w14:paraId` so
|
|
950
|
+
* it survives unrelated edits. Returns the comment ID, or null if
|
|
951
|
+
* the paraId is unknown or the search text isn't found / is ambiguous. */
|
|
952
|
+
addComment: (options: {
|
|
953
|
+
paraId: string;
|
|
954
|
+
text: string;
|
|
955
|
+
author: string;
|
|
956
|
+
/** Optional: anchor to a specific phrase within the paragraph (must be unique). */
|
|
957
|
+
search?: string;
|
|
958
|
+
}) => number | null;
|
|
959
|
+
/** Reply to an existing comment. Returns the reply comment ID. */
|
|
960
|
+
replyToComment: (commentId: number, text: string, author: string) => number | null;
|
|
961
|
+
/** Resolve (mark as done) a comment. */
|
|
962
|
+
resolveComment: (commentId: number) => void;
|
|
963
|
+
/** Suggest a tracked change. Pass `replaceWith: ''` to delete the matched text;
|
|
964
|
+
* pass `search: ''` to insert at paragraph end. Returns false on missing paraId,
|
|
965
|
+
* missing/ambiguous search, or attempt to layer on an existing tracked change. */
|
|
966
|
+
proposeChange: (options: {
|
|
967
|
+
paraId: string;
|
|
968
|
+
search: string;
|
|
969
|
+
replaceWith: string;
|
|
970
|
+
author: string;
|
|
971
|
+
}) => boolean;
|
|
972
|
+
/** Locate every paragraph containing `query` (case-insensitive substring).
|
|
973
|
+
* Returns a stable handle (paraId + the matched phrase) the agent can pass
|
|
974
|
+
* back to `addComment` / `proposeChange`. */
|
|
975
|
+
findInDocument: (query: string, options?: {
|
|
976
|
+
caseSensitive?: boolean;
|
|
977
|
+
limit?: number;
|
|
978
|
+
}) => Array<{
|
|
979
|
+
paraId: string;
|
|
980
|
+
match: string;
|
|
981
|
+
before: string;
|
|
982
|
+
after: string;
|
|
983
|
+
}>;
|
|
984
|
+
/**
|
|
985
|
+
* Apply character formatting (bold / italic / color / size / font / etc.)
|
|
986
|
+
* to a paragraph or to a unique phrase within it. This is a direct edit,
|
|
987
|
+
* not a tracked change. Returns false on missing paraId or ambiguous search.
|
|
988
|
+
*/
|
|
989
|
+
applyFormatting: (options: {
|
|
990
|
+
paraId: string;
|
|
991
|
+
search?: string;
|
|
992
|
+
marks: {
|
|
993
|
+
bold?: boolean;
|
|
994
|
+
italic?: boolean;
|
|
995
|
+
underline?: boolean | {
|
|
996
|
+
style?: string;
|
|
997
|
+
};
|
|
998
|
+
strike?: boolean;
|
|
999
|
+
color?: {
|
|
1000
|
+
rgb?: string;
|
|
1001
|
+
themeColor?: string;
|
|
1002
|
+
};
|
|
1003
|
+
highlight?: string;
|
|
1004
|
+
fontSize?: number;
|
|
1005
|
+
fontFamily?: {
|
|
1006
|
+
ascii?: string;
|
|
1007
|
+
hAnsi?: string;
|
|
1008
|
+
};
|
|
1009
|
+
};
|
|
1010
|
+
}) => boolean;
|
|
1011
|
+
/**
|
|
1012
|
+
* Apply a paragraph style by styleId (e.g. `'Heading1'`, `'Quote'`).
|
|
1013
|
+
* Direct edit, not a tracked change. Returns false if paraId is unknown.
|
|
1014
|
+
*/
|
|
1015
|
+
setParagraphStyle: (options: {
|
|
1016
|
+
paraId: string;
|
|
1017
|
+
styleId: string;
|
|
1018
|
+
}) => boolean;
|
|
1019
|
+
/**
|
|
1020
|
+
* Read the contents of a single page. 1-indexed; returns null if the page
|
|
1021
|
+
* does not exist. Each paragraph is returned with its stable paraId so the
|
|
1022
|
+
* agent can comment on or modify it without an extra round-trip.
|
|
1023
|
+
*/
|
|
1024
|
+
getPageContent: (pageNumber: number) => {
|
|
1025
|
+
pageNumber: number;
|
|
1026
|
+
text: string;
|
|
1027
|
+
paragraphs: Array<{
|
|
1028
|
+
paraId: string;
|
|
1029
|
+
text: string;
|
|
1030
|
+
styleId?: string;
|
|
1031
|
+
}>;
|
|
1032
|
+
} | null;
|
|
1033
|
+
/** Read the user's current cursor / selection — what's highlighted right now. */
|
|
1034
|
+
getSelectionInfo: () => {
|
|
1035
|
+
paraId: string | null;
|
|
1036
|
+
selectedText: string;
|
|
1037
|
+
paragraphText: string;
|
|
1038
|
+
before: string;
|
|
1039
|
+
after: string;
|
|
1040
|
+
} | null;
|
|
1041
|
+
/** Get all comments. */
|
|
1042
|
+
getComments: () => Comment[];
|
|
1043
|
+
/** Subscribe to document changes. Fires after every committed edit. Returns unsubscribe. */
|
|
1044
|
+
onContentChange: (listener: (document: Document) => void) => () => void;
|
|
1045
|
+
/** Subscribe to selection changes (cursor moves / selection changes). Returns unsubscribe. */
|
|
1046
|
+
onSelectionChange: (listener: (selection: SelectionState | null) => void) => () => void;
|
|
1047
|
+
}
|
|
1048
|
+
type EditorMode = 'editing' | 'suggesting' | 'viewing';
|
|
1049
|
+
/**
|
|
1050
|
+
* DocxEditor - Complete DOCX editor component
|
|
1051
|
+
*/
|
|
1052
|
+
declare const DocxEditor: React.ForwardRefExoticComponent<DocxEditorProps & React.RefAttributes<DocxEditorRef>>;
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* Simple imperative API for rendering a DOCX editor into a DOM element.
|
|
1056
|
+
*
|
|
1057
|
+
* Returns an `EditorHandle` (from @eigenpal/docx-editor-core) that works with
|
|
1058
|
+
* any framework implementation.
|
|
1059
|
+
*
|
|
1060
|
+
* Usage:
|
|
1061
|
+
* ```ts
|
|
1062
|
+
* import { renderAsync } from '@eigenpal/docx-editor-react';
|
|
1063
|
+
*
|
|
1064
|
+
* const editor = await renderAsync(docxBlob, document.getElementById('container'), {
|
|
1065
|
+
* readOnly: false,
|
|
1066
|
+
* showToolbar: true,
|
|
1067
|
+
* });
|
|
1068
|
+
*
|
|
1069
|
+
* // Save the edited document
|
|
1070
|
+
* const blob = await editor.save();
|
|
1071
|
+
*
|
|
1072
|
+
* // Clean up
|
|
1073
|
+
* editor.destroy();
|
|
1074
|
+
* ```
|
|
1075
|
+
*/
|
|
1076
|
+
|
|
1077
|
+
/**
|
|
1078
|
+
* Options for {@link renderAsync}. A subset of DocxEditorProps minus
|
|
1079
|
+
* `documentBuffer` / `document` (passed as the first argument instead).
|
|
1080
|
+
*/
|
|
1081
|
+
type RenderAsyncOptions = Omit<DocxEditorProps, 'documentBuffer' | 'document'>;
|
|
1082
|
+
/**
|
|
1083
|
+
* React-specific handle that extends the framework-agnostic EditorHandle
|
|
1084
|
+
* with zoom control.
|
|
1085
|
+
*/
|
|
1086
|
+
interface DocxEditorHandle extends EditorHandle {
|
|
1087
|
+
/** Set zoom level (1.0 = 100%). */
|
|
1088
|
+
setZoom: (zoom: number) => void;
|
|
1089
|
+
/** Scroll to a body paragraph by Word `w14:paraId`. */
|
|
1090
|
+
scrollToParaId: (paraId: string) => boolean;
|
|
1091
|
+
/** Scroll to a raw ProseMirror document position. */
|
|
1092
|
+
scrollToPosition: (pmPos: number) => void;
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* Render a DOCX editor into a container element.
|
|
1096
|
+
*
|
|
1097
|
+
* @param input - DOCX data as ArrayBuffer, Uint8Array, Blob, or File
|
|
1098
|
+
* @param container - DOM element to render into
|
|
1099
|
+
* @param options - Editor configuration (toolbar, readOnly, callbacks, etc.)
|
|
1100
|
+
* @returns A handle with save / destroy / getDocument methods
|
|
1101
|
+
*/
|
|
1102
|
+
declare function renderAsync(input: DocxInput, container: HTMLElement, options?: RenderAsyncOptions): Promise<DocxEditorHandle>;
|
|
1103
|
+
|
|
1104
|
+
/**
|
|
1105
|
+
* @eigenpal/docx-editor-react
|
|
1106
|
+
*
|
|
1107
|
+
* Curated root entry for the documented React editor API. Advanced surfaces
|
|
1108
|
+
* stay public through explicit subpaths:
|
|
1109
|
+
* - `@eigenpal/docx-editor-react/ui`
|
|
1110
|
+
* - `@eigenpal/docx-editor-react/dialogs`
|
|
1111
|
+
* - `@eigenpal/docx-editor-react/hooks`
|
|
1112
|
+
* - `@eigenpal/docx-editor-react/plugin-api`
|
|
1113
|
+
*
|
|
1114
|
+
* Framework-agnostic document utilities live in `@eigenpal/docx-editor-core`.
|
|
1115
|
+
* Agent/MCP surfaces live in `@eigenpal/docx-editor-agents`.
|
|
1116
|
+
*/
|
|
1117
|
+
declare const VERSION = "0.0.2";
|
|
1118
|
+
|
|
1119
|
+
export { type DocxInput as D, type EditorMode as E, LocaleProvider as L, type RenderAsyncOptions as R, VERSION as V, DocumentAgent as a, DocxEditor as b, type DocxEditorHandle as c, type DocxEditorProps as d, type DocxEditorRef as e, type LocaleProviderProps as f, renderAsync as r, useTranslation as u };
|