@zeke-02/docx-editor 0.0.35 → 0.5.2

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 (168) hide show
  1. package/README.md +34 -29
  2. package/dist/{ClipboardManager-C1l58nzE.d.ts → ClipboardManager-CVKX0v9q.d.ts} +1 -1
  3. package/dist/{ClipboardManager-Cjb_v74d.d.mts → ClipboardManager-V3aaMnWE.d.mts} +1 -1
  4. package/dist/{DocumentAgent-E8OX_8j0.d.mts → DocumentAgent-BWflKHpH.d.mts} +1 -1
  5. package/dist/{DocumentAgent-iedmc_8s.d.ts → DocumentAgent-DsdXtetF.d.ts} +1 -1
  6. package/dist/{FindReplaceDialog-YW3R4FHM.mjs → FindReplaceDialog-L3YF5HIS.mjs} +1 -1
  7. package/dist/FindReplaceDialog-SEBWC5P7.js +1 -0
  8. package/dist/{FootnotePropertiesDialog-LNFJXQUG.mjs → FootnotePropertiesDialog-TNVJJCY6.mjs} +1 -1
  9. package/dist/{FootnotePropertiesDialog-7QX54WQT.js → FootnotePropertiesDialog-XQ7NIFIU.js} +1 -1
  10. package/dist/{HyperlinkDialog-HNYTXDCB.mjs → HyperlinkDialog-FR4IZZ7E.mjs} +1 -1
  11. package/dist/HyperlinkDialog-WEK6JSAC.js +1 -0
  12. package/dist/{ImagePositionDialog-M65BYQQE.js → ImagePositionDialog-2YXRAGZS.js} +1 -1
  13. package/dist/{ImagePositionDialog-B4RLP2W5.mjs → ImagePositionDialog-JSZSIKF5.mjs} +1 -1
  14. package/dist/ImagePropertiesDialog-527MFLQO.mjs +1 -0
  15. package/dist/{ImagePropertiesDialog-O4WQSF5M.js → ImagePropertiesDialog-HG4K3IE7.js} +1 -1
  16. package/dist/PageSetupDialog-GALVJMUB.js +1 -0
  17. package/dist/PageSetupDialog-TGQIAMI7.mjs +1 -0
  18. package/dist/SplitCellDialog-JIAC3RYV.js +1 -0
  19. package/dist/SplitCellDialog-NP3JJYHD.mjs +1 -0
  20. package/dist/{TablePropertiesDialog-WOZ4ES3H.js → TablePropertiesDialog-T7D4HSVP.js} +1 -1
  21. package/dist/TablePropertiesDialog-TIK4AA5M.mjs +1 -0
  22. package/dist/{clipboard-BWhM0CRj.d.mts → TableToolbar-DUgmob2I.d.ts} +227 -135
  23. package/dist/{clipboard-BvkuNZub.d.ts → TableToolbar-YL74HNS1.d.mts} +227 -135
  24. package/dist/{agentApi-mv532p8I.d.mts → agentApi-DLt94vXk.d.mts} +83 -5
  25. package/dist/{agentApi-mv532p8I.d.ts → agentApi-DLt94vXk.d.ts} +83 -5
  26. package/dist/chunk-23SXXIZS.js +111 -0
  27. package/dist/chunk-3F52AP2Q.js +1 -0
  28. package/dist/chunk-42O5GXM5.mjs +82 -0
  29. package/dist/chunk-54ULJEHM.mjs +1 -0
  30. package/dist/chunk-5XK326FI.mjs +1 -0
  31. package/dist/chunk-76IYR7C7.mjs +1 -0
  32. package/dist/chunk-AGRIVA4G.js +1 -0
  33. package/dist/chunk-BTCQ2QI3.mjs +3 -0
  34. package/dist/chunk-BXRC4U3X.mjs +2 -0
  35. package/dist/chunk-CPAYKE6X.mjs +1 -0
  36. package/dist/chunk-DACWLFKI.mjs +1 -0
  37. package/dist/{chunk-377ZVTSE.js → chunk-EHFEG3TX.js} +1 -1
  38. package/dist/chunk-EPBFWE36.js +2 -0
  39. package/dist/chunk-FXES3YDB.js +82 -0
  40. package/dist/chunk-HI66BSGS.mjs +9 -0
  41. package/dist/chunk-INTPVEO6.mjs +9 -0
  42. package/dist/chunk-IOAGVW6Q.mjs +2 -0
  43. package/dist/chunk-JCEWC5QL.mjs +4 -0
  44. package/dist/chunk-JTIUFACT.js +1 -0
  45. package/dist/{chunk-KCOGY3V2.js → chunk-LUF7PWIC.js} +4 -4
  46. package/dist/chunk-LVGJKS7Y.mjs +24 -0
  47. package/dist/chunk-MGEN6GOE.mjs +2 -0
  48. package/dist/chunk-MOE2ZGUE.js +18 -0
  49. package/dist/chunk-MWLHJWB6.js +9 -0
  50. package/dist/chunk-OFYVDN3U.mjs +2 -0
  51. package/dist/chunk-P4VSHBGZ.js +2 -0
  52. package/dist/chunk-P5FQHIES.mjs +1 -0
  53. package/dist/chunk-PBC7XAYZ.js +3 -0
  54. package/dist/chunk-PEMB6SZT.js +2 -0
  55. package/dist/chunk-PKEOQIQO.mjs +2 -0
  56. package/dist/chunk-PQMSZTBB.js +9 -0
  57. package/dist/chunk-Q7UDQXAF.js +1 -0
  58. package/dist/chunk-QGTAIC5E.js +1 -0
  59. package/dist/chunk-R3QMYPL5.mjs +59 -0
  60. package/dist/chunk-RBUTXXQJ.mjs +18 -0
  61. package/dist/chunk-RRWYZ2TS.mjs +111 -0
  62. package/dist/chunk-S3STEPVO.js +182 -0
  63. package/dist/{chunk-AU5NVRHP.js → chunk-SFUM35DH.js} +2 -2
  64. package/dist/chunk-SNLC6EK2.js +1 -0
  65. package/dist/chunk-TMTLIGLZ.js +59 -0
  66. package/dist/{chunk-RTFUE3KK.mjs → chunk-TSE2PWFX.mjs} +3 -3
  67. package/dist/chunk-UKESXQS5.mjs +182 -0
  68. package/dist/chunk-UWYD42WV.js +4 -0
  69. package/dist/chunk-UXVACQCY.mjs +1 -0
  70. package/dist/{chunk-Z26WOH6R.mjs → chunk-W4EIKDM6.mjs} +2 -2
  71. package/dist/chunk-WNS2RBQD.js +2 -0
  72. package/dist/chunk-YC5KZSYD.js +24 -0
  73. package/dist/chunk-Z3KMSHUP.js +1 -0
  74. package/dist/core-plugins-reexport.d.mts +4 -4
  75. package/dist/core-plugins-reexport.d.ts +4 -4
  76. package/dist/core-plugins-reexport.js +1 -1
  77. package/dist/core-plugins-reexport.mjs +1 -1
  78. package/dist/core-reexport.d.mts +47 -16
  79. package/dist/core-reexport.d.ts +47 -16
  80. package/dist/core-reexport.js +1 -1
  81. package/dist/core-reexport.mjs +1 -1
  82. package/dist/{colorResolver-C5fQ4fxP.d.mts → documentSerializer-DtS_-oGA.d.mts} +378 -376
  83. package/dist/{colorResolver-Bp9flT3l.d.ts → documentSerializer-Wj1p2ASa.d.ts} +378 -376
  84. package/dist/executor-C3VXF7QA.mjs +1 -0
  85. package/dist/executor-GDBV3AGV.js +1 -0
  86. package/dist/headless-reexport.d.mts +14 -12
  87. package/dist/headless-reexport.d.ts +14 -12
  88. package/dist/headless-reexport.js +1 -4
  89. package/dist/headless-reexport.mjs +1 -4
  90. package/dist/index.css +1 -1
  91. package/dist/index.d.mts +284 -172
  92. package/dist/index.d.ts +284 -172
  93. package/dist/index.js +17 -9
  94. package/dist/index.mjs +17 -9
  95. package/dist/{fontLoader-0G00frKD.d.mts → insertOperations-BTH1Asas.d.mts} +86 -86
  96. package/dist/{fontLoader-DPdt4JvW.d.ts → insertOperations-CbUnXAXH.d.ts} +86 -86
  97. package/dist/layout-bridge-EA4DJ227.js +1 -0
  98. package/dist/layout-bridge-XDPSO6GO.mjs +1 -0
  99. package/dist/mcp-reexport.d.mts +2 -2
  100. package/dist/mcp-reexport.d.ts +2 -2
  101. package/dist/mcp-reexport.js +8 -8
  102. package/dist/mcp-reexport.mjs +7 -7
  103. package/dist/processTemplate-MJ2PCSO5.js +1 -0
  104. package/dist/{processTemplate-LRHXOWMZ.mjs → processTemplate-W2C5PXZB.mjs} +1 -1
  105. package/dist/{react-1OO-DXvx.d.ts → react-B0W16SV6.d.ts} +384 -166
  106. package/dist/{react-B1dSZ_w1.d.mts → react-D0Pn1nww.d.mts} +384 -166
  107. package/dist/react.css +1 -1
  108. package/dist/react.d.mts +5 -5
  109. package/dist/react.d.ts +5 -5
  110. package/dist/react.js +1 -1
  111. package/dist/react.mjs +1 -1
  112. package/dist/{registry-BWGKcKc1.d.ts → registry-CH9V-IX0.d.ts} +1 -1
  113. package/dist/{registry-8XOdjHGC.d.mts → registry-CWBKYlNW.d.mts} +1 -1
  114. package/dist/styles.css +1 -1
  115. package/dist/{types-DIBvJ7AJ.d.mts → types-UDsUq8D3.d.mts} +1 -1
  116. package/dist/{types-CfAiObQo.d.ts → types-jbivc9Lj.d.ts} +1 -1
  117. package/dist/ui.d.mts +33 -83
  118. package/dist/ui.d.ts +33 -83
  119. package/dist/ui.js +1 -1
  120. package/dist/ui.mjs +1 -1
  121. package/dist/{variableDetector-DNO18eZ1.d.mts → variableDetector-CdQ7ZTzA.d.mts} +1 -1
  122. package/dist/{variableDetector-BIJFVpkl.d.ts → variableDetector-DsRV3A9z.d.ts} +1 -1
  123. package/i18n/de.json +49 -2
  124. package/i18n/en.json +55 -8
  125. package/i18n/he.json +792 -0
  126. package/i18n/pl.json +49 -2
  127. package/i18n/pt-BR.json +792 -0
  128. package/i18n/tr.json +792 -0
  129. package/i18n/zh-CN.json +792 -0
  130. package/package.json +17 -5
  131. package/dist/FindReplaceDialog-KNJETYJX.js +0 -1
  132. package/dist/HyperlinkDialog-GBAYMTUE.js +0 -1
  133. package/dist/ImagePropertiesDialog-JOGW3WDU.mjs +0 -1
  134. package/dist/PageSetupDialog-2GIBTKMJ.js +0 -1
  135. package/dist/PageSetupDialog-Q7SHEZIJ.mjs +0 -1
  136. package/dist/TablePropertiesDialog-LMXWX3FI.mjs +0 -1
  137. package/dist/chunk-2HDYCD2Q.mjs +0 -1
  138. package/dist/chunk-37SLIJPH.mjs +0 -58
  139. package/dist/chunk-3OKYQQQ5.js +0 -111
  140. package/dist/chunk-4VUZBV2S.js +0 -1
  141. package/dist/chunk-6YRWZ32V.js +0 -261
  142. package/dist/chunk-7MGFEP2R.mjs +0 -26
  143. package/dist/chunk-7QTNB64A.mjs +0 -9
  144. package/dist/chunk-AARNCPWR.js +0 -1
  145. package/dist/chunk-DC65PJYE.js +0 -4
  146. package/dist/chunk-DLVLK5FT.mjs +0 -24
  147. package/dist/chunk-EV3CM6TU.js +0 -1
  148. package/dist/chunk-FVUGBRDD.js +0 -1
  149. package/dist/chunk-FW5LYOOZ.mjs +0 -111
  150. package/dist/chunk-GZOCOWWB.mjs +0 -2
  151. package/dist/chunk-KUL2SDYC.js +0 -26
  152. package/dist/chunk-LYBG4YI7.mjs +0 -1
  153. package/dist/chunk-M5F4SK3W.mjs +0 -1
  154. package/dist/chunk-P7WEP4JU.js +0 -9
  155. package/dist/chunk-PB7VMDDP.js +0 -24
  156. package/dist/chunk-QAZ4233N.mjs +0 -1
  157. package/dist/chunk-QSUPYUOP.js +0 -2
  158. package/dist/chunk-QTSXJRP6.mjs +0 -1
  159. package/dist/chunk-S67UBZDL.mjs +0 -261
  160. package/dist/chunk-SE5EN2QL.js +0 -1
  161. package/dist/chunk-X5A54T6S.mjs +0 -4
  162. package/dist/chunk-YKBSKEBS.mjs +0 -2
  163. package/dist/chunk-ZJNGMDRE.js +0 -58
  164. package/dist/executor-L2MVKMXO.js +0 -1
  165. package/dist/executor-XKBCCVNY.mjs +0 -1
  166. package/dist/processTemplate-5ZST2Q5L.js +0 -1
  167. package/dist/selectionRects-DEX5THEG.js +0 -1
  168. package/dist/selectionRects-SQTAHMCH.mjs +0 -1
@@ -4,10 +4,10 @@ import * as prosemirror_view from 'prosemirror-view';
4
4
  import { EditorView } from 'prosemirror-view';
5
5
  import * as prosemirror_state from 'prosemirror-state';
6
6
  import { EditorState, Transaction } from 'prosemirror-state';
7
- import { T as TextFormatting, K as ParagraphFormatting, D as Document, a3 as Theme, C as Comment, e as Table } from './agentApi-mv532p8I.mjs';
8
- import { F as SidebarItem, g as EditorPluginCore, k as PluginPanelProps, R as RenderedDomContext, G as SidebarItemContext, f as EditorHandle, h as ErrorNotification, m as SavedDocumentData, d as AutoSaveStatus, e as ClipboardSelection } from './ClipboardManager-Cjb_v74d.mjs';
9
- import { g as PrintOptions, T as Translations, j as TableContext, i as TableAction, P as ParsedClipboardContent } from './clipboard-BWhM0CRj.mjs';
10
- import { g as DocxInput, D as DocumentAgent } from './DocumentAgent-E8OX_8j0.mjs';
7
+ import { T as TextFormatting, K as ParagraphFormatting, D as Document, a3 as Theme, C as Comment, e as Table } from './agentApi-DLt94vXk.mjs';
8
+ import { F as FontOption, i as PrintOptions, T as Translations, l as TableContext, k as TableAction, n as TableSplitConfig, P as ParsedClipboardContent } from './TableToolbar-YL74HNS1.mjs';
9
+ import { F as SidebarItem, g as EditorPluginCore, k as PluginPanelProps, R as RenderedDomContext, G as SidebarItemContext, f as EditorHandle, h as ErrorNotification, m as SavedDocumentData, d as AutoSaveStatus, e as ClipboardSelection } from './ClipboardManager-V3aaMnWE.mjs';
10
+ import { g as DocxInput, D as DocumentAgent } from './DocumentAgent-BWflKHpH.mjs';
11
11
  import * as react_jsx_runtime from 'react/jsx-runtime';
12
12
 
13
13
  /**
@@ -111,6 +111,167 @@ interface PluginHostRef {
111
111
  refreshPluginStates: () => void;
112
112
  }
113
113
 
114
+ /**
115
+ * Selection Highlight Utilities
116
+ *
117
+ * Provides visual highlighting for text selection across multiple runs.
118
+ * Browsers handle ::selection pseudo-element differently, especially when
119
+ * selection spans multiple elements with different backgrounds or styling.
120
+ *
121
+ * This module provides:
122
+ * - Custom selection highlight rendering
123
+ * - Programmatic selection range marking
124
+ * - Visual feedback for selection across runs
125
+ */
126
+ /** Framework-agnostic CSS properties type (compatible with React.CSSProperties) */
127
+ type CSSProperties = Record<string, any>;
128
+ /**
129
+ * Highlight rectangle representing a selected region
130
+ */
131
+ interface HighlightRect {
132
+ /** Left position in pixels */
133
+ left: number;
134
+ /** Top position in pixels */
135
+ top: number;
136
+ /** Width in pixels */
137
+ width: number;
138
+ /** Height in pixels */
139
+ height: number;
140
+ }
141
+ /**
142
+ * Selection highlight configuration
143
+ */
144
+ interface SelectionHighlightConfig {
145
+ /** Background color for selection */
146
+ backgroundColor: string;
147
+ /** Optional border color for selection */
148
+ borderColor?: string;
149
+ /** Optional border radius */
150
+ borderRadius?: number;
151
+ /** Z-index for overlay */
152
+ zIndex?: number;
153
+ /** Opacity for highlight */
154
+ opacity?: number;
155
+ /** Mix blend mode */
156
+ mixBlendMode?: CSSProperties['mixBlendMode'];
157
+ }
158
+ /**
159
+ * Selection range in document coordinates
160
+ */
161
+ interface SelectionRange {
162
+ /** Start position */
163
+ start: {
164
+ paragraphIndex: number;
165
+ contentIndex: number;
166
+ offset: number;
167
+ };
168
+ /** End position */
169
+ end: {
170
+ paragraphIndex: number;
171
+ contentIndex: number;
172
+ offset: number;
173
+ };
174
+ }
175
+ /**
176
+ * Default selection highlight style (matches Word/Google Docs)
177
+ */
178
+ declare const DEFAULT_SELECTION_STYLE: SelectionHighlightConfig;
179
+ /**
180
+ * High contrast selection style
181
+ */
182
+ declare const HIGH_CONTRAST_SELECTION_STYLE: SelectionHighlightConfig;
183
+ /**
184
+ * Selection highlight CSS custom properties
185
+ */
186
+ declare const SELECTION_CSS_VARS: {
187
+ readonly backgroundColor: "--docx-selection-bg";
188
+ readonly borderColor: "--docx-selection-border";
189
+ readonly textColor: "--docx-selection-text";
190
+ };
191
+ /**
192
+ * Get all selection rectangles from the current DOM selection
193
+ *
194
+ * Uses getClientRects() to get accurate rectangles even when
195
+ * selection spans multiple inline elements.
196
+ */
197
+ declare function getSelectionRects(containerElement?: HTMLElement | null): HighlightRect[];
198
+ /**
199
+ * Merge adjacent or overlapping rectangles
200
+ *
201
+ * This reduces the number of highlight elements needed and creates
202
+ * a cleaner visual appearance.
203
+ */
204
+ declare function mergeAdjacentRects(rects: HighlightRect[], tolerance?: number): HighlightRect[];
205
+ /**
206
+ * Get selection rectangles with merging applied
207
+ */
208
+ declare function getMergedSelectionRects(containerElement?: HTMLElement | null): HighlightRect[];
209
+ /**
210
+ * Generate CSS styles for a highlight rectangle
211
+ */
212
+ declare function getHighlightRectStyle(rect: HighlightRect, config?: SelectionHighlightConfig): CSSProperties;
213
+ /**
214
+ * Generate inline CSS for selection pseudo-elements
215
+ *
216
+ * This is used to inject consistent selection styling
217
+ * across all editable elements.
218
+ */
219
+ declare function generateSelectionCSS(selector: string, config?: SelectionHighlightConfig): string;
220
+ /**
221
+ * Check if there is an active text selection (not collapsed)
222
+ */
223
+ declare function hasActiveSelection(): boolean;
224
+ /**
225
+ * Get the selected text
226
+ */
227
+ declare function getSelectedText(): string;
228
+ /**
229
+ * Check if selection is within a specific element
230
+ */
231
+ declare function isSelectionWithin(element: HTMLElement): boolean;
232
+ /**
233
+ * Get the bounding rect of the current selection
234
+ */
235
+ declare function getSelectionBoundingRect(): DOMRect | null;
236
+ /**
237
+ * Create a selection highlight for a specific text range
238
+ *
239
+ * This is useful for find/replace highlighting, AI action previews, etc.
240
+ */
241
+ declare function highlightTextRange(_containerElement: HTMLElement, startNode: Node, startOffset: number, endNode: Node, endOffset: number): Range | null;
242
+ /**
243
+ * Select a text range programmatically
244
+ */
245
+ declare function selectRange(range: Range): void;
246
+ /**
247
+ * Clear the current selection
248
+ */
249
+ declare function clearSelection(): void;
250
+ /**
251
+ * Check if selection is backwards (focus before anchor)
252
+ */
253
+ declare function isSelectionBackwards(): boolean;
254
+ /**
255
+ * Normalize selection to always be forward (start before end)
256
+ */
257
+ declare function normalizeSelectionDirection(): void;
258
+ /**
259
+ * Inject selection highlight CSS into document
260
+ */
261
+ declare function injectSelectionStyles(config?: SelectionHighlightConfig): void;
262
+ /**
263
+ * Remove injected selection styles
264
+ */
265
+ declare function removeSelectionStyles(): void;
266
+ /**
267
+ * Check if selection styles are injected
268
+ */
269
+ declare function areSelectionStylesInjected(): boolean;
270
+ /**
271
+ * Create a selection change handler that updates highlight rects
272
+ */
273
+ declare function createSelectionChangeHandler(containerElement: HTMLElement | null, onRectsChange: (rects: HighlightRect[]) => void, merge?: boolean): () => void;
274
+
114
275
  /**
115
276
  * Selection State Utilities
116
277
  *
@@ -340,6 +501,16 @@ interface PagedEditorRef {
340
501
  relayout(): void;
341
502
  /** Scroll the visible pages to bring a PM position into view. */
342
503
  scrollToPosition(pmPos: number): void;
504
+ /**
505
+ * Scroll to the paragraph identified by Word `w14:paraId` / PM `paraId`.
506
+ * @returns whether a matching paragraph was found
507
+ */
508
+ scrollToParaId(paraId: string): boolean;
509
+ /**
510
+ * Scroll the paginated view so `pageNumber` (1-indexed) is in view.
511
+ * No-op if the layout isn't ready yet or pageNumber is out of range.
512
+ */
513
+ scrollToPage(pageNumber: number): void;
343
514
  }
344
515
 
345
516
  /**
@@ -364,6 +535,16 @@ interface DocxEditorProps {
364
535
  onFontsLoaded?: () => void;
365
536
  /** External ProseMirror plugins (from PluginHost) */
366
537
  externalPlugins?: prosemirror_state.Plugin[];
538
+ /**
539
+ * When true, the editor treats the `document` prop as a schema seed only and
540
+ * does not load it into ProseMirror on mount. Content is expected to come from
541
+ * external sources — typically `externalPlugins` such as `ySyncPlugin` from
542
+ * `y-prosemirror`, but also any code that dispatches transactions directly.
543
+ *
544
+ * You must still pass a `document` prop (e.g., `createEmptyDocument()`) so the
545
+ * editor can build its schema and render the shell.
546
+ */
547
+ externalContent?: boolean;
367
548
  /** Callback when editor view is ready (for PluginHost) */
368
549
  onEditorViewReady?: (view: prosemirror_view.EditorView) => void;
369
550
  /** Theme for styling */
@@ -384,6 +565,11 @@ interface DocxEditorProps {
384
565
  initialZoom?: number;
385
566
  /** Whether the editor is read-only. When true, hides toolbar and rulers */
386
567
  readOnly?: boolean;
568
+ /**
569
+ * When true, the editor does not intercept Cmd/Ctrl+F or Cmd/Ctrl+H.
570
+ * This lets the browser or host app handle native find/history shortcuts.
571
+ */
572
+ disableFindReplaceShortcuts?: boolean;
387
573
  /** Custom toolbar actions */
388
574
  toolbarExtra?: ReactNode;
389
575
  /** Additional CSS class name */
@@ -398,6 +584,19 @@ interface DocxEditorProps {
398
584
  showOutline?: boolean;
399
585
  /** Whether to show the floating outline toggle button (default: true) */
400
586
  showOutlineButton?: boolean;
587
+ /**
588
+ * Custom list of fonts shown in the toolbar's font-family dropdown.
589
+ * Strings render in the "Other" group; pass `FontOption[]` for category
590
+ * grouping and CSS fallback chains. Omit to use the built-in 12-font
591
+ * default. An empty array renders an empty (but enabled) dropdown.
592
+ *
593
+ * Pass a stable reference (memoized or module-level) — inline arrays
594
+ * create a new identity per render and invalidate the picker's memo.
595
+ *
596
+ * @example fontFamilies={['Arial', 'Roboto']}
597
+ * @example fontFamilies={[{ name: 'Roboto', fontFamily: 'Roboto, sans-serif', category: 'sans-serif' }]}
598
+ */
599
+ fontFamilies?: ReadonlyArray<string | FontOption>;
401
600
  /** Whether to show print button in toolbar (default: true) */
402
601
  showPrintButton?: boolean;
403
602
  /** Whether to show the editing mode switcher (Editing/Suggesting/Viewing) in toolbar (default: true) */
@@ -426,6 +625,23 @@ interface DocxEditorProps {
426
625
  onCommentDelete?: (comment: Comment) => void;
427
626
  /** Callback when a reply is added to a comment via the UI */
428
627
  onCommentReply?: (reply: Comment, parent: Comment) => void;
628
+ /**
629
+ * Controlled comments array. When provided, the editor reads comment thread
630
+ * metadata (text, author, replies, resolved status) from this prop instead
631
+ * of internal state, and emits every change through `onCommentsChange`.
632
+ *
633
+ * Use this with collaboration backends (Yjs, Liveblocks, Automerge, …) so
634
+ * comment threads sync across peers — the PM document only carries the
635
+ * range markers; thread metadata lives outside the doc and needs its own
636
+ * sync channel.
637
+ *
638
+ * If omitted, the editor falls back to internal state (current behavior).
639
+ * The granular `onCommentAdd`/`onCommentResolve`/`onCommentDelete`/
640
+ * `onCommentReply` callbacks fire in both modes.
641
+ */
642
+ comments?: Comment[];
643
+ /** Fires whenever the comments array changes (controlled mode). */
644
+ onCommentsChange?: (comments: Comment[]) => void;
429
645
  /**
430
646
  * Callback when rendered DOM context is ready (for plugin overlays).
431
647
  * Used by PluginHost to get access to the rendered page DOM for positioning.
@@ -452,6 +668,45 @@ interface DocxEditorProps {
452
668
  renderTitleBarRight?: () => ReactNode;
453
669
  /** Translation overrides. Import a locale JSON file and pass it directly. */
454
670
  i18n?: Translations;
671
+ /**
672
+ * Mount a controllable agent panel on the right side of the editor. The
673
+ * panel is the chrome (header, close button, drag-resize); the consumer
674
+ * supplies whatever content goes inside via `render` — typically a chat
675
+ * UI from `@ai-sdk/react`'s `useChat`, `assistant-ui`, or any other
676
+ * framework. We do not ship message bubbles, a composer, or a chat engine.
677
+ *
678
+ * Three control patterns:
679
+ * - **Uncontrolled**: `agentPanel={{ render }}` — toolbar button + panel
680
+ * close button toggle the panel. Width persists to localStorage.
681
+ * - **Controlled**: `agentPanel={{ render, open, onOpenChange }}` — the
682
+ * consumer owns open state (e.g. tied to a global menu).
683
+ * - **Headless**: omit `agentPanel`, use the toolkit directly via
684
+ * `useDocxAgentTools` — render the panel anywhere you want.
685
+ */
686
+ agentPanel?: {
687
+ /** Render-prop returning the panel content. Called only when open. */
688
+ render: (ctx: {
689
+ close: () => void;
690
+ }) => ReactNode;
691
+ /** Controlled open state. Omit for uncontrolled. */
692
+ open?: boolean;
693
+ /** Fires when toolbar button or panel close button is clicked. */
694
+ onOpenChange?: (open: boolean) => void;
695
+ /** Show the toolbar toggle button. Default: true. */
696
+ showToolbarButton?: boolean;
697
+ /** Optional badge / dot on the toolbar button. */
698
+ toolbarBadge?: ReactNode;
699
+ /** Optional panel title. Default: t('agentPanel.defaultTitle'). */
700
+ title?: string;
701
+ /** Optional panel header icon. Default: sparkle. */
702
+ icon?: ReactNode;
703
+ /** Initial panel width in px (uncontrolled). Default: 360. */
704
+ defaultWidth?: number;
705
+ /** Min drag width. Default: 280. */
706
+ minWidth?: number;
707
+ /** Max drag width. Default: 600. */
708
+ maxWidth?: number;
709
+ };
455
710
  }
456
711
  /**
457
712
  * DocxEditor ref interface
@@ -477,8 +732,26 @@ interface DocxEditorRef {
477
732
  getCurrentPage: () => number;
478
733
  /** Get total page count */
479
734
  getTotalPages: () => number;
480
- /** Scroll to a specific page */
735
+ /**
736
+ * Scroll the paginated view so the given page is in view.
737
+ * Page numbers are 1-indexed (matches `getCurrentPage` / `getTotalPages`).
738
+ * No-op for out-of-range or non-integer values.
739
+ * @example ref.current?.scrollToPage(2)
740
+ */
481
741
  scrollToPage: (pageNumber: number) => void;
742
+ /**
743
+ * Scroll the paginated view to the paragraph with the given Word `w14:paraId`.
744
+ * @returns whether a matching paragraph exists in the ProseMirror document
745
+ * @example ref.current?.scrollToParaId('1A2B3C4D')
746
+ */
747
+ scrollToParaId: (paraId: string) => boolean;
748
+ /**
749
+ * Scroll the paginated view to a specific ProseMirror document position.
750
+ * Use this when you have a raw PM offset; for Word `w14:paraId` use
751
+ * `scrollToParaId` instead.
752
+ * @example ref.current?.scrollToPosition(42)
753
+ */
754
+ scrollToPosition: (pmPos: number) => void;
482
755
  /** Open print preview */
483
756
  openPrintPreview: () => void;
484
757
  /** Print the document directly */
@@ -504,6 +777,104 @@ interface DocxEditorRef {
504
777
  * ```
505
778
  */
506
779
  applyDocumentChanges: (doc: Document) => boolean;
780
+ /** Add a comment programmatically. Anchored by Word `w14:paraId` so
781
+ * it survives unrelated edits. Returns the comment ID, or null if
782
+ * the paraId is unknown or the search text isn't found / is ambiguous. */
783
+ addComment: (options: {
784
+ paraId: string;
785
+ text: string;
786
+ author: string;
787
+ /** Optional: anchor to a specific phrase within the paragraph (must be unique). */
788
+ search?: string;
789
+ }) => number | null;
790
+ /** Reply to an existing comment. Returns the reply comment ID. */
791
+ replyToComment: (commentId: number, text: string, author: string) => number | null;
792
+ /** Resolve (mark as done) a comment. */
793
+ resolveComment: (commentId: number) => void;
794
+ /** Suggest a tracked change. Pass `replaceWith: ''` to delete the matched text;
795
+ * pass `search: ''` to insert at paragraph end. Returns false on missing paraId,
796
+ * missing/ambiguous search, or attempt to layer on an existing tracked change. */
797
+ proposeChange: (options: {
798
+ paraId: string;
799
+ search: string;
800
+ replaceWith: string;
801
+ author: string;
802
+ }) => boolean;
803
+ /** Locate every paragraph containing `query` (case-insensitive substring).
804
+ * Returns a stable handle (paraId + the matched phrase) the agent can pass
805
+ * back to `addComment` / `proposeChange`. */
806
+ findInDocument: (query: string, options?: {
807
+ caseSensitive?: boolean;
808
+ limit?: number;
809
+ }) => Array<{
810
+ paraId: string;
811
+ match: string;
812
+ before: string;
813
+ after: string;
814
+ }>;
815
+ /**
816
+ * Apply character formatting (bold / italic / color / size / font / etc.)
817
+ * to a paragraph or to a unique phrase within it. This is a direct edit,
818
+ * not a tracked change. Returns false on missing paraId or ambiguous search.
819
+ */
820
+ applyFormatting: (options: {
821
+ paraId: string;
822
+ search?: string;
823
+ marks: {
824
+ bold?: boolean;
825
+ italic?: boolean;
826
+ underline?: boolean | {
827
+ style?: string;
828
+ };
829
+ strike?: boolean;
830
+ color?: {
831
+ rgb?: string;
832
+ themeColor?: string;
833
+ };
834
+ highlight?: string;
835
+ fontSize?: number;
836
+ fontFamily?: {
837
+ ascii?: string;
838
+ hAnsi?: string;
839
+ };
840
+ };
841
+ }) => boolean;
842
+ /**
843
+ * Apply a paragraph style by styleId (e.g. `'Heading1'`, `'Quote'`).
844
+ * Direct edit, not a tracked change. Returns false if paraId is unknown.
845
+ */
846
+ setParagraphStyle: (options: {
847
+ paraId: string;
848
+ styleId: string;
849
+ }) => boolean;
850
+ /**
851
+ * Read the contents of a single page. 1-indexed; returns null if the page
852
+ * does not exist. Each paragraph is returned with its stable paraId so the
853
+ * agent can comment on or modify it without an extra round-trip.
854
+ */
855
+ getPageContent: (pageNumber: number) => {
856
+ pageNumber: number;
857
+ text: string;
858
+ paragraphs: Array<{
859
+ paraId: string;
860
+ text: string;
861
+ styleId?: string;
862
+ }>;
863
+ } | null;
864
+ /** Read the user's current cursor / selection — what's highlighted right now. */
865
+ getSelectionInfo: () => {
866
+ paraId: string | null;
867
+ selectedText: string;
868
+ paragraphText: string;
869
+ before: string;
870
+ after: string;
871
+ } | null;
872
+ /** Get all comments. */
873
+ getComments: () => Comment[];
874
+ /** Subscribe to document changes. Fires after every committed edit. Returns unsubscribe. */
875
+ onContentChange: (listener: (document: Document) => void) => () => void;
876
+ /** Subscribe to selection changes (cursor moves / selection changes). Returns unsubscribe. */
877
+ onSelectionChange: (listener: (selection: SelectionState | null) => void) => () => void;
507
878
  }
508
879
  type EditorMode = 'editing' | 'suggesting' | 'viewing';
509
880
  /**
@@ -546,6 +917,10 @@ type RenderAsyncOptions = Omit<DocxEditorProps, 'documentBuffer' | 'document'>;
546
917
  interface DocxEditorHandle extends EditorHandle {
547
918
  /** Set zoom level (1.0 = 100%). */
548
919
  setZoom: (zoom: number) => void;
920
+ /** Scroll to a body paragraph by Word `w14:paraId`. */
921
+ scrollToParaId: (paraId: string) => boolean;
922
+ /** Scroll to a raw ProseMirror document position. */
923
+ scrollToPosition: (pmPos: number) => void;
549
924
  }
550
925
  /**
551
926
  * Render a DOCX editor into a container element.
@@ -670,6 +1045,8 @@ interface UseTableSelectionReturn {
670
1045
  state: TableSelectionState;
671
1046
  handleCellClick: (tableIndex: number, rowIndex: number, columnIndex: number) => void;
672
1047
  handleAction: (action: TableAction) => void;
1048
+ getSplitCellConfig: () => TableSplitConfig | null;
1049
+ applySplitCell: (rows: number, cols: number) => void;
673
1050
  clearSelection: () => void;
674
1051
  isCellSelected: (tableIndex: number, rowIndex: number, columnIndex: number) => boolean;
675
1052
  tableContext: TableContext | null;
@@ -829,167 +1206,6 @@ declare function isZoomPreset(zoom: number): boolean;
829
1206
  */
830
1207
  declare function clampZoom(zoom: number, minZoom?: number, maxZoom?: number): number;
831
1208
 
832
- /**
833
- * Selection Highlight Utilities
834
- *
835
- * Provides visual highlighting for text selection across multiple runs.
836
- * Browsers handle ::selection pseudo-element differently, especially when
837
- * selection spans multiple elements with different backgrounds or styling.
838
- *
839
- * This module provides:
840
- * - Custom selection highlight rendering
841
- * - Programmatic selection range marking
842
- * - Visual feedback for selection across runs
843
- */
844
- /** Framework-agnostic CSS properties type (compatible with React.CSSProperties) */
845
- type CSSProperties = Record<string, any>;
846
- /**
847
- * Highlight rectangle representing a selected region
848
- */
849
- interface HighlightRect {
850
- /** Left position in pixels */
851
- left: number;
852
- /** Top position in pixels */
853
- top: number;
854
- /** Width in pixels */
855
- width: number;
856
- /** Height in pixels */
857
- height: number;
858
- }
859
- /**
860
- * Selection highlight configuration
861
- */
862
- interface SelectionHighlightConfig {
863
- /** Background color for selection */
864
- backgroundColor: string;
865
- /** Optional border color for selection */
866
- borderColor?: string;
867
- /** Optional border radius */
868
- borderRadius?: number;
869
- /** Z-index for overlay */
870
- zIndex?: number;
871
- /** Opacity for highlight */
872
- opacity?: number;
873
- /** Mix blend mode */
874
- mixBlendMode?: CSSProperties['mixBlendMode'];
875
- }
876
- /**
877
- * Selection range in document coordinates
878
- */
879
- interface SelectionRange {
880
- /** Start position */
881
- start: {
882
- paragraphIndex: number;
883
- contentIndex: number;
884
- offset: number;
885
- };
886
- /** End position */
887
- end: {
888
- paragraphIndex: number;
889
- contentIndex: number;
890
- offset: number;
891
- };
892
- }
893
- /**
894
- * Default selection highlight style (matches Word/Google Docs)
895
- */
896
- declare const DEFAULT_SELECTION_STYLE: SelectionHighlightConfig;
897
- /**
898
- * High contrast selection style
899
- */
900
- declare const HIGH_CONTRAST_SELECTION_STYLE: SelectionHighlightConfig;
901
- /**
902
- * Selection highlight CSS custom properties
903
- */
904
- declare const SELECTION_CSS_VARS: {
905
- readonly backgroundColor: "--docx-selection-bg";
906
- readonly borderColor: "--docx-selection-border";
907
- readonly textColor: "--docx-selection-text";
908
- };
909
- /**
910
- * Get all selection rectangles from the current DOM selection
911
- *
912
- * Uses getClientRects() to get accurate rectangles even when
913
- * selection spans multiple inline elements.
914
- */
915
- declare function getSelectionRects(containerElement?: HTMLElement | null): HighlightRect[];
916
- /**
917
- * Merge adjacent or overlapping rectangles
918
- *
919
- * This reduces the number of highlight elements needed and creates
920
- * a cleaner visual appearance.
921
- */
922
- declare function mergeAdjacentRects(rects: HighlightRect[], tolerance?: number): HighlightRect[];
923
- /**
924
- * Get selection rectangles with merging applied
925
- */
926
- declare function getMergedSelectionRects(containerElement?: HTMLElement | null): HighlightRect[];
927
- /**
928
- * Generate CSS styles for a highlight rectangle
929
- */
930
- declare function getHighlightRectStyle(rect: HighlightRect, config?: SelectionHighlightConfig): CSSProperties;
931
- /**
932
- * Generate inline CSS for selection pseudo-elements
933
- *
934
- * This is used to inject consistent selection styling
935
- * across all editable elements.
936
- */
937
- declare function generateSelectionCSS(selector: string, config?: SelectionHighlightConfig): string;
938
- /**
939
- * Check if there is an active text selection (not collapsed)
940
- */
941
- declare function hasActiveSelection(): boolean;
942
- /**
943
- * Get the selected text
944
- */
945
- declare function getSelectedText(): string;
946
- /**
947
- * Check if selection is within a specific element
948
- */
949
- declare function isSelectionWithin(element: HTMLElement): boolean;
950
- /**
951
- * Get the bounding rect of the current selection
952
- */
953
- declare function getSelectionBoundingRect(): DOMRect | null;
954
- /**
955
- * Create a selection highlight for a specific text range
956
- *
957
- * This is useful for find/replace highlighting, AI action previews, etc.
958
- */
959
- declare function highlightTextRange(_containerElement: HTMLElement, startNode: Node, startOffset: number, endNode: Node, endOffset: number): Range | null;
960
- /**
961
- * Select a text range programmatically
962
- */
963
- declare function selectRange(range: Range): void;
964
- /**
965
- * Clear the current selection
966
- */
967
- declare function clearSelection(): void;
968
- /**
969
- * Check if selection is backwards (focus before anchor)
970
- */
971
- declare function isSelectionBackwards(): boolean;
972
- /**
973
- * Normalize selection to always be forward (start before end)
974
- */
975
- declare function normalizeSelectionDirection(): void;
976
- /**
977
- * Inject selection highlight CSS into document
978
- */
979
- declare function injectSelectionStyles(config?: SelectionHighlightConfig): void;
980
- /**
981
- * Remove injected selection styles
982
- */
983
- declare function removeSelectionStyles(): void;
984
- /**
985
- * Check if selection styles are injected
986
- */
987
- declare function areSelectionStylesInjected(): boolean;
988
- /**
989
- * Create a selection change handler that updates highlight rects
990
- */
991
- declare function createSelectionChangeHandler(containerElement: HTMLElement | null, onRectsChange: (rects: HighlightRect[]) => void, merge?: boolean): () => void;
992
-
993
1209
  /**
994
1210
  * Selection Highlight Hook
995
1211
  *
@@ -1083,6 +1299,8 @@ interface UseClipboardOptions {
1083
1299
  cleanWordFormatting?: boolean;
1084
1300
  editable?: boolean;
1085
1301
  onError?: (error: Error) => void;
1302
+ /** Document theme — used to resolve themed colors in the HTML clipboard payload. */
1303
+ theme?: Theme | null;
1086
1304
  }
1087
1305
  interface UseClipboardReturn {
1088
1306
  copy: (selection: ClipboardSelection) => Promise<boolean>;