@beyondwork/docx-react-component 1.0.84 → 1.0.85

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 (46) hide show
  1. package/package.json +1 -1
  2. package/src/api/internal/build-ref-projections.ts +3 -0
  3. package/src/api/public-types.ts +38 -0
  4. package/src/api/v3/_runtime-handle.ts +11 -0
  5. package/src/api/v3/runtime/content.ts +148 -1
  6. package/src/api/v3/runtime/formatting.ts +41 -0
  7. package/src/api/v3/runtime/review.ts +98 -0
  8. package/src/core/commands/index.ts +81 -25
  9. package/src/core/state/editor-state.ts +15 -0
  10. package/src/io/ooxml/header-footer-reference.ts +38 -0
  11. package/src/io/ooxml/parse-headers-footers.ts +11 -23
  12. package/src/io/ooxml/parse-main-document.ts +7 -10
  13. package/src/model/canonical-document.ts +9 -0
  14. package/src/model/review/comment-types.ts +2 -0
  15. package/src/runtime/document-runtime.ts +677 -54
  16. package/src/runtime/formatting/field/resolver.ts +73 -8
  17. package/src/runtime/layout/layout-engine-version.ts +31 -12
  18. package/src/runtime/layout/paginated-layout-engine.ts +18 -11
  19. package/src/runtime/layout/public-facet.ts +119 -16
  20. package/src/runtime/layout/resolve-page-fields.ts +68 -6
  21. package/src/runtime/layout/resolve-page-previews.ts +1 -1
  22. package/src/runtime/suggestions-snapshot.ts +24 -0
  23. package/src/runtime/surface-projection.ts +59 -2
  24. package/src/shell/ref-commands.ts +3 -354
  25. package/src/shell/session-bootstrap.ts +8 -0
  26. package/src/ui/WordReviewEditor.tsx +95 -9
  27. package/src/ui/editor-command-bag.ts +3 -1
  28. package/src/ui/headless/revision-decoration-model.ts +13 -0
  29. package/src/ui/headless/selection-tool-types.ts +2 -0
  30. package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +7 -3
  31. package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +175 -25
  32. package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +1 -1
  33. package/src/ui-tailwind/editor-surface/pm-decorations.ts +12 -0
  34. package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +18 -30
  35. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +1 -1
  36. package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +1 -1
  37. package/src/ui-tailwind/page-stack/tw-page-chrome-entry.tsx +20 -11
  38. package/src/ui-tailwind/page-stack/tw-page-footer-band.tsx +9 -4
  39. package/src/ui-tailwind/page-stack/tw-page-header-band.tsx +12 -7
  40. package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +29 -10
  41. package/src/ui-tailwind/page-stack/tw-region-block-renderer.tsx +1 -1
  42. package/src/ui-tailwind/review-workspace/types.ts +3 -2
  43. package/src/ui-tailwind/review-workspace/use-page-markers.ts +11 -1
  44. package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +2 -1
  45. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +2 -1
  46. package/src/ui-tailwind/tw-review-workspace.tsx +18 -2
@@ -20,6 +20,7 @@ import { classifyFieldInstruction } from "./parse-fields.ts";
20
20
  import { isSafeTableFieldInstruction } from "./table-opaque-preservation.ts";
21
21
  import { parseXmlWithOffsets as parseXml } from "./xml-parser.ts";
22
22
  import { localName, readStringAttr } from "./xml-attr-helpers.ts";
23
+ import { readHeaderFooterReferenceAttributes } from "./header-footer-reference.ts";
23
24
  import {
24
25
  readCellBorders,
25
26
  readCellCnfStyle,
@@ -200,40 +201,27 @@ function extractSectPrRefs(
200
201
  const name = localName(child.name);
201
202
  if (name === "headerReference" || name === "footerReference") {
202
203
  const kind: "header" | "footer" = name === "headerReference" ? "header" : "footer";
203
- const rawType =
204
- readStringAttr(child, "w:type") ?? "default";
205
- const variant = toHeaderFooterVariant(rawType);
206
- const relationshipId =
207
- child.attributes["r:id"] ??
208
- child.attributes["r:Id"] ??
209
- child.attributes.id ??
210
- child.attributes.Id ??
211
- "";
212
-
213
- if (relationshipId) {
204
+ const ref = readHeaderFooterReferenceAttributes(child);
205
+
206
+ if (ref) {
214
207
  // Avoid duplicates (multiple sectPr may reference same header)
215
- const dedupeKey = `${kind}:${variant}:${relationshipId}`;
208
+ const dedupeKey = `${kind}:${ref.variant}:${ref.relationshipId}`;
216
209
  const alreadyAdded = refs.some(
217
210
  (ref) => `${ref.kind}:${ref.variant}:${ref.relationshipId}` === dedupeKey,
218
211
  );
219
212
  if (!alreadyAdded) {
220
- refs.push({ variant, relationshipId, kind, sectionIndex });
213
+ refs.push({
214
+ variant: ref.variant,
215
+ relationshipId: ref.relationshipId,
216
+ kind,
217
+ sectionIndex,
218
+ });
221
219
  }
222
220
  }
223
221
  }
224
222
  }
225
223
  }
226
224
 
227
- function toHeaderFooterVariant(raw: string): HeaderFooterVariant {
228
- if (raw === "first") {
229
- return "first";
230
- }
231
- if (raw === "even") {
232
- return "even";
233
- }
234
- return "default";
235
- }
236
-
237
225
  function parseHdrFtrXml(
238
226
  xml: string,
239
227
  rootLocalName: "hdr" | "ftr",
@@ -21,8 +21,6 @@ import type {
21
21
  PageMargins,
22
22
  ColumnProperties,
23
23
  PageNumbering,
24
- HeaderFooterReference,
25
- HeaderFooterVariant,
26
24
  SectionDocumentGrid,
27
25
  SectionLineNumbering,
28
26
  SectionPageBorders,
@@ -45,6 +43,7 @@ import { parseComplexContentXml, type ChartPartLookup } from "./parse-complex-co
45
43
  import { parseShapeXml, parseVmlXml } from "./parse-shapes.ts";
46
44
  import { parseObject } from "./parse-object.ts";
47
45
  import { parseDrawingFrame } from "./parse-drawing.ts";
46
+ import { readHeaderFooterReferenceAttributes } from "./header-footer-reference.ts";
48
47
  import { readFrameProperties } from "./parse-paragraph-formatting.ts";
49
48
  import { tableRequiresOpaquePreservation } from "./table-opaque-preservation.ts";
50
49
  import { classifyFieldInstruction } from "./parse-fields.ts";
@@ -3756,20 +3755,18 @@ export function parseSectionPropertiesFromElement(
3756
3755
  break;
3757
3756
  }
3758
3757
  case "headerReference": {
3759
- const variant = child.attributes["w:type"] as HeaderFooterVariant | undefined;
3760
- const rId = child.attributes["r:id"];
3761
- if (variant && rId) {
3758
+ const ref = readHeaderFooterReferenceAttributes(child);
3759
+ if (ref) {
3762
3760
  if (!props.headerReferences) props.headerReferences = [];
3763
- props.headerReferences.push({ variant, relationshipId: rId });
3761
+ props.headerReferences.push(ref);
3764
3762
  }
3765
3763
  break;
3766
3764
  }
3767
3765
  case "footerReference": {
3768
- const variant = child.attributes["w:type"] as HeaderFooterVariant | undefined;
3769
- const rId = child.attributes["r:id"];
3770
- if (variant && rId) {
3766
+ const ref = readHeaderFooterReferenceAttributes(child);
3767
+ if (ref) {
3771
3768
  if (!props.footerReferences) props.footerReferences = [];
3772
- props.footerReferences.push({ variant, relationshipId: rId });
3769
+ props.footerReferences.push(ref);
3773
3770
  }
3774
3771
  break;
3775
3772
  }
@@ -2095,6 +2095,12 @@ export interface CommentThreadMetadata {
2095
2095
  source?: "runtime" | "import";
2096
2096
  rootOoxmlCommentId?: string;
2097
2097
  rootParaId?: string;
2098
+ /**
2099
+ * Runtime-authored discussion thread for a tracked change. The comment
2100
+ * anchor points at the revision range; this metadata keeps the review
2101
+ * relation stable after remaps and lets suggestion cards surface replies.
2102
+ */
2103
+ linkedRevisionId?: string;
2098
2104
  detachedReason?: "incomplete-markers" | "multi-paragraph" | "opaque-region" | "revision-overlap";
2099
2105
  actionabilityNote?: string;
2100
2106
  }
@@ -3323,6 +3329,9 @@ function validateCommentThreadMetadata(
3323
3329
  if (record.rootParaId !== undefined) {
3324
3330
  expectString(record.rootParaId, `${path}.rootParaId`, issues);
3325
3331
  }
3332
+ if (record.linkedRevisionId !== undefined) {
3333
+ expectString(record.linkedRevisionId, `${path}.linkedRevisionId`, issues);
3334
+ }
3326
3335
  }
3327
3336
 
3328
3337
  function validateRevisionKind(
@@ -62,6 +62,8 @@ export interface CommentThreadMetadata {
62
62
  source?: "runtime" | "import";
63
63
  rootOoxmlCommentId?: string;
64
64
  rootParaId?: string;
65
+ /** Stable link from a comment thread to the tracked change it discusses. */
66
+ linkedRevisionId?: string;
65
67
  detachedReason?: "incomplete-markers" | "multi-paragraph" | "opaque-region" | "revision-overlap";
66
68
  actionabilityNote?: string;
67
69
  }