@beyondwork/docx-react-component 1.0.41 → 1.0.43

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 (118) hide show
  1. package/package.json +38 -37
  2. package/src/api/awareness-identity-types.ts +35 -0
  3. package/src/api/comment-negotiation-types.ts +130 -0
  4. package/src/api/comment-presentation-types.ts +106 -0
  5. package/src/api/editor-state-types.ts +110 -0
  6. package/src/api/external-custody-types.ts +74 -0
  7. package/src/api/participants-types.ts +18 -0
  8. package/src/api/public-types.ts +541 -5
  9. package/src/api/scope-metadata-resolver-types.ts +88 -0
  10. package/src/core/commands/formatting-commands.ts +1 -1
  11. package/src/core/commands/index.ts +601 -9
  12. package/src/core/search/search-text.ts +15 -2
  13. package/src/index.ts +131 -1
  14. package/src/io/docx-session.ts +672 -2
  15. package/src/io/export/escape-xml-attribute.ts +26 -0
  16. package/src/io/export/external-send.ts +188 -0
  17. package/src/io/export/serialize-comments.ts +13 -16
  18. package/src/io/export/serialize-footnotes.ts +17 -24
  19. package/src/io/export/serialize-headers-footers.ts +17 -24
  20. package/src/io/export/serialize-main-document.ts +59 -62
  21. package/src/io/export/serialize-numbering.ts +20 -27
  22. package/src/io/export/serialize-runtime-revisions.ts +2 -9
  23. package/src/io/export/serialize-tables.ts +8 -15
  24. package/src/io/export/table-properties-xml.ts +25 -32
  25. package/src/io/import/external-reimport.ts +40 -0
  26. package/src/io/load-scheduler.ts +230 -0
  27. package/src/io/normalize/normalize-text.ts +83 -0
  28. package/src/io/ooxml/bw-xml.ts +244 -0
  29. package/src/io/ooxml/canonicalize-payload.ts +301 -0
  30. package/src/io/ooxml/comment-negotiation-payload.ts +288 -0
  31. package/src/io/ooxml/comment-presentation-payload.ts +311 -0
  32. package/src/io/ooxml/external-custody-payload.ts +102 -0
  33. package/src/io/ooxml/participants-payload.ts +97 -0
  34. package/src/io/ooxml/payload-signature.ts +112 -0
  35. package/src/io/ooxml/workflow-payload-validator.ts +367 -0
  36. package/src/io/ooxml/workflow-payload.ts +317 -7
  37. package/src/runtime/awareness-identity.ts +173 -0
  38. package/src/runtime/collab/event-types.ts +27 -0
  39. package/src/runtime/collab-session-bridge.ts +157 -0
  40. package/src/runtime/collab-session-facet.ts +193 -0
  41. package/src/runtime/collab-session.ts +273 -0
  42. package/src/runtime/comment-negotiation-sync.ts +91 -0
  43. package/src/runtime/comment-negotiation.ts +158 -0
  44. package/src/runtime/comment-presentation.ts +223 -0
  45. package/src/runtime/document-runtime.ts +639 -124
  46. package/src/runtime/editor-state-channel.ts +544 -0
  47. package/src/runtime/editor-state-integration.ts +217 -0
  48. package/src/runtime/external-send-runtime.ts +117 -0
  49. package/src/runtime/layout/docx-font-loader.ts +11 -30
  50. package/src/runtime/layout/index.ts +2 -0
  51. package/src/runtime/layout/inert-layout-facet.ts +4 -0
  52. package/src/runtime/layout/layout-engine-instance.ts +139 -14
  53. package/src/runtime/layout/page-graph.ts +79 -7
  54. package/src/runtime/layout/paginated-layout-engine.ts +441 -48
  55. package/src/runtime/layout/public-facet.ts +585 -14
  56. package/src/runtime/layout/table-row-split.ts +316 -0
  57. package/src/runtime/markdown-sanitizer.ts +132 -0
  58. package/src/runtime/participants.ts +134 -0
  59. package/src/runtime/perf-counters.ts +28 -0
  60. package/src/runtime/render/render-frame-types.ts +17 -0
  61. package/src/runtime/render/render-kernel.ts +172 -29
  62. package/src/runtime/resign-payload.ts +120 -0
  63. package/src/runtime/surface-projection.ts +10 -5
  64. package/src/runtime/tamper-gate.ts +157 -0
  65. package/src/runtime/workflow-markup.ts +80 -16
  66. package/src/runtime/workflow-rail-segments.ts +244 -5
  67. package/src/ui/WordReviewEditor.tsx +654 -45
  68. package/src/ui/editor-command-bag.ts +14 -0
  69. package/src/ui/editor-runtime-boundary.ts +111 -11
  70. package/src/ui/editor-shell-view.tsx +21 -0
  71. package/src/ui/editor-surface-controller.tsx +5 -0
  72. package/src/ui/headless/selection-helpers.ts +10 -0
  73. package/src/ui-tailwind/chrome/chrome-preset-model.ts +28 -0
  74. package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +62 -2
  75. package/src/ui-tailwind/chrome/collab-audience-chip.tsx +73 -0
  76. package/src/ui-tailwind/chrome/collab-negotiation-action-bar.tsx +244 -0
  77. package/src/ui-tailwind/chrome/collab-presence-strip.tsx +150 -0
  78. package/src/ui-tailwind/chrome/collab-role-chip.tsx +62 -0
  79. package/src/ui-tailwind/chrome/collab-send-to-supplier-button.tsx +68 -0
  80. package/src/ui-tailwind/chrome/collab-send-to-supplier-modal.tsx +149 -0
  81. package/src/ui-tailwind/chrome/collab-tamper-banner.tsx +68 -0
  82. package/src/ui-tailwind/chrome/collab-top-nav-container.tsx +281 -0
  83. package/src/ui-tailwind/chrome/forward-non-drag-click.ts +104 -0
  84. package/src/ui-tailwind/chrome/tw-mode-dock.tsx +1 -0
  85. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +7 -1
  86. package/src/ui-tailwind/chrome/tw-table-grip-layer.tsx +1 -38
  87. package/src/ui-tailwind/chrome-overlay/index.ts +6 -0
  88. package/src/ui-tailwind/chrome-overlay/scope-card-role-model.ts +78 -0
  89. package/src/ui-tailwind/chrome-overlay/scope-keyboard-cycle.ts +49 -0
  90. package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +106 -0
  91. package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +527 -0
  92. package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +120 -22
  93. package/src/ui-tailwind/chrome-overlay/tw-scope-card.tsx +310 -32
  94. package/src/ui-tailwind/chrome-overlay/tw-scope-rail-layer.tsx +93 -14
  95. package/src/ui-tailwind/editor-surface/paste-plain-text.ts +72 -0
  96. package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +118 -8
  97. package/src/ui-tailwind/editor-surface/pm-decorations.ts +35 -1
  98. package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +86 -3
  99. package/src/ui-tailwind/editor-surface/pm-schema.ts +167 -17
  100. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +35 -7
  101. package/src/ui-tailwind/editor-surface/remote-cursor-plugin.ts +20 -3
  102. package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +265 -0
  103. package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +10 -256
  104. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +9 -0
  105. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +66 -0
  106. package/src/ui-tailwind/index.ts +37 -1
  107. package/src/ui-tailwind/page-stack/tw-endnote-area.tsx +57 -0
  108. package/src/ui-tailwind/page-stack/tw-footnote-area.tsx +71 -0
  109. package/src/ui-tailwind/page-stack/tw-page-footer-band.tsx +73 -0
  110. package/src/ui-tailwind/page-stack/tw-page-header-band.tsx +74 -0
  111. package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +477 -0
  112. package/src/ui-tailwind/page-stack/tw-region-block-renderer.tsx +374 -0
  113. package/src/ui-tailwind/review/comment-markdown-renderer.tsx +155 -0
  114. package/src/ui-tailwind/review/tw-comment-sidebar.tsx +77 -16
  115. package/src/ui-tailwind/review/tw-review-rail-footer.tsx +29 -3
  116. package/src/ui-tailwind/status/tw-status-bar.tsx +52 -1
  117. package/src/ui-tailwind/theme/editor-theme.css +25 -0
  118. package/src/ui-tailwind/tw-review-workspace.tsx +455 -118
@@ -73,6 +73,17 @@ export interface RuntimePageRegions {
73
73
  * pages, the top-level body is used and `columns` is undefined.
74
74
  */
75
75
  columns?: RuntimePageRegion[];
76
+ /**
77
+ * P4 — footnote regions reserved at the bottom of the page (above
78
+ * the footer band) when `noteAllocations` reserved space for one or
79
+ * more footnote bodies. Empty until the page-graph builder
80
+ * populates them, which lands alongside the P8 per-page region
81
+ * rendering work. The shape exists now so consumers
82
+ * (`getStoryRegionsOnPage` / `getLineBoxesForRegion("footnote-area")`)
83
+ * have a stable seam to read from when the builder catches up —
84
+ * pre-P8 reads return `[]` because no entries are populated.
85
+ */
86
+ footnotes?: RuntimePageRegion[];
76
87
  }
77
88
 
78
89
  export interface RuntimePageRegion {
@@ -158,6 +169,14 @@ export interface RuntimeNoteAllocation {
158
169
  noteId: string;
159
170
  /** Twips reserved at the bottom of the page for this note's content. */
160
171
  reservedHeightTwips: number;
172
+ /**
173
+ * P8 — fragment ID of this note's body. The corresponding
174
+ * `RuntimeBlockFragment` lives in `RuntimePageGraph.fragments` with
175
+ * `regionKind: "footnote-area"`. Undefined when the engine hasn't
176
+ * yet emitted a fragment for the allocation (back-compat for pre-P8
177
+ * callers).
178
+ */
179
+ fragmentId?: string;
161
180
  }
162
181
 
163
182
  export interface RuntimePageAnchor {
@@ -196,8 +215,15 @@ export interface BuildPageGraphInput {
196
215
  >;
197
216
  /** Optional per-page line boxes. */
198
217
  lineBoxes?: ReadonlyMap<string, RuntimeLineBox[]>;
199
- /** Optional per-page note allocations. */
218
+ /** Optional per-page note allocations keyed by graph-assigned pageId. */
200
219
  noteAllocations?: ReadonlyMap<string, RuntimeNoteAllocation[]>;
220
+ /**
221
+ * P8 — per-page note allocations keyed by pageIndex (0-based).
222
+ * Parallel to `fragmentsByPageIndex`; `buildPageGraph` uses the index to
223
+ * look up allocations without requiring callers to know the graph-internal
224
+ * `page-${revision}-${index}` pageId in advance.
225
+ */
226
+ noteAllocationsByPageIndex?: ReadonlyMap<number, RuntimeNoteAllocation[]>;
201
227
  }
202
228
 
203
229
  export function buildPageGraph(input: BuildPageGraphInput): RuntimePageGraph;
@@ -244,10 +270,15 @@ export function buildPageGraph(
244
270
  };
245
271
 
246
272
  const pageFragments = aggregatedFragments.filter((f) => f.pageId === pageId);
247
- const fragmentIds = pageFragments.map((f) => f.fragmentId);
273
+ // Split fragments into body-region ones (for the body fragmentIds list)
274
+ // and footnote-area ones (handled by buildRegions via noteAllocations).
275
+ const bodyPageFragments = pageFragments.filter(
276
+ (f) => f.regionKind !== "footnote-area",
277
+ );
278
+ const fragmentIds = bodyPageFragments.map((f) => f.fragmentId);
248
279
 
249
- // If no fragments were supplied, synthesize a coarse body fragment so the
250
- // graph is still internally consistent.
280
+ // If no body fragments were supplied, synthesize a coarse body fragment so
281
+ // the graph is still internally consistent.
251
282
  let bodyFragmentIds = fragmentIds;
252
283
  if (fragmentIds.length === 0 && page.endOffset > page.startOffset) {
253
284
  const coarse: RuntimeBlockFragment = {
@@ -264,6 +295,15 @@ export function buildPageGraph(
264
295
  bodyFragmentIds = [coarse.fragmentId];
265
296
  }
266
297
 
298
+ // Resolve per-page note allocations: prefer noteAllocationsByPageIndex
299
+ // (index-based, suitable when the caller doesn't know the graph-internal
300
+ // pageId) falling back to noteAllocations (pageId-keyed, used by the
301
+ // engine once it emits allocations).
302
+ const pageNoteAllocations: RuntimeNoteAllocation[] =
303
+ input.noteAllocationsByPageIndex?.get(index) ??
304
+ input.noteAllocations?.get(pageId) ??
305
+ [];
306
+
267
307
  const node: RuntimePageNode = {
268
308
  pageId,
269
309
  pageIndex: page.pageIndex,
@@ -273,9 +313,9 @@ export function buildPageGraph(
273
313
  endOffset: page.endOffset,
274
314
  layout: page.layout,
275
315
  stories,
276
- regions: buildRegions(page.layout, bodyFragmentIds, stories),
316
+ regions: buildRegions(page.layout, bodyFragmentIds, stories, pageNoteAllocations),
277
317
  lineBoxes: input.lineBoxes?.get(pageId) ?? [],
278
- noteAllocations: input.noteAllocations?.get(pageId) ?? [],
318
+ noteAllocations: pageNoteAllocations,
279
319
  isBlankFiller: page.pageInSection === -1,
280
320
  };
281
321
  pages.push(node);
@@ -302,12 +342,40 @@ function buildRegions(
302
342
  layout: PageLayoutSnapshot,
303
343
  bodyFragmentIds: readonly string[],
304
344
  stories: ResolvedPageStories,
345
+ noteAllocations: readonly RuntimeNoteAllocation[] = [],
305
346
  ): RuntimePageRegions {
306
347
  const bodyWidth =
307
348
  layout.pageWidth - layout.marginLeft - layout.marginRight;
308
- const bodyHeight =
349
+ let bodyHeight =
309
350
  layout.pageHeight - layout.marginTop - layout.marginBottom;
310
351
 
352
+ // P8 — footnote area sits at the bottom of the page (above the footer
353
+ // band). Body height shrinks by the total reserved note height so
354
+ // band-aware consumers can stack bands without overflowing the paper frame.
355
+ let footnotesRegion: RuntimePageRegion | undefined;
356
+ if (noteAllocations.length > 0) {
357
+ const fragmentIds = noteAllocations
358
+ .filter(
359
+ (a): a is RuntimeNoteAllocation & { fragmentId: string } =>
360
+ Boolean(a.fragmentId),
361
+ )
362
+ .map((a) => a.fragmentId);
363
+ const totalNoteHeight = noteAllocations.reduce(
364
+ (sum, a) => sum + a.reservedHeightTwips,
365
+ 0,
366
+ );
367
+ if (fragmentIds.length > 0) {
368
+ footnotesRegion = {
369
+ kind: "footnote-area",
370
+ originTwips: layout.pageHeight - layout.marginBottom - totalNoteHeight,
371
+ widthTwips: Math.max(0, bodyWidth),
372
+ heightTwips: Math.max(0, totalNoteHeight),
373
+ fragmentIds,
374
+ };
375
+ bodyHeight = Math.max(0, bodyHeight - totalNoteHeight);
376
+ }
377
+ }
378
+
311
379
  const body: RuntimePageRegion = {
312
380
  kind: "body",
313
381
  originTwips: layout.marginTop,
@@ -356,6 +424,10 @@ function buildRegions(
356
424
  regions.columns = columns;
357
425
  }
358
426
 
427
+ if (footnotesRegion) {
428
+ regions.footnotes = [footnotesRegion];
429
+ }
430
+
359
431
  return regions;
360
432
  }
361
433