@beyondwork/docx-react-component 1.0.73 → 1.0.74

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 (48) hide show
  1. package/package.json +1 -1
  2. package/src/api/anchor-conversion.ts +2 -2
  3. package/src/api/public-types.ts +33 -6
  4. package/src/api/v3/_runtime-handle.ts +15 -0
  5. package/src/api/v3/ui/_types.ts +21 -0
  6. package/src/api/v3/ui/overlays.ts +276 -2
  7. package/src/api/v3/ui/scope.ts +113 -1
  8. package/src/compare/diff-engine.ts +1 -2
  9. package/src/core/commands/index.ts +14 -15
  10. package/src/core/selection/anchor-conversion.ts +2 -2
  11. package/src/core/selection/mapping.ts +10 -8
  12. package/src/core/selection/review-anchors.ts +3 -3
  13. package/src/io/export/export-session.ts +53 -0
  14. package/src/io/export/serialize-comments.ts +4 -4
  15. package/src/io/export/serialize-runtime-revisions.ts +10 -10
  16. package/src/io/export/split-review-boundaries.ts +4 -4
  17. package/src/io/export/split-story-blocks-for-runtime-revisions.ts +2 -2
  18. package/src/io/ooxml/parse-comments.ts +2 -2
  19. package/src/model/anchor.ts +9 -1
  20. package/src/model/canonical-document.ts +76 -3
  21. package/src/preservation/store.ts +24 -0
  22. package/src/review/store/comment-anchors.ts +1 -1
  23. package/src/review/store/comment-remapping.ts +1 -1
  24. package/src/review/store/revision-actions.ts +4 -4
  25. package/src/review/store/revision-types.ts +1 -1
  26. package/src/review/store/scope-tag-diff.ts +1 -1
  27. package/src/runtime/collab/map-local-selection-on-remote-replay.ts +7 -7
  28. package/src/runtime/document-runtime.ts +205 -37
  29. package/src/runtime/formatting/formatting-context.ts +1 -1
  30. package/src/runtime/layout/inert-layout-facet.ts +1 -0
  31. package/src/runtime/layout/layout-engine-version.ts +9 -1
  32. package/src/runtime/layout/public-facet.ts +27 -0
  33. package/src/runtime/scopes/evidence.ts +1 -1
  34. package/src/runtime/scopes/review-bundle.ts +1 -1
  35. package/src/runtime/scopes/scope-range.ts +1 -1
  36. package/src/runtime/selection/post-edit-validator.ts +4 -4
  37. package/src/runtime/surface-projection.ts +39 -4
  38. package/src/session/import/review-import.ts +12 -12
  39. package/src/session/import/workflow-scope-import.ts +9 -8
  40. package/src/shell/session-bootstrap.ts +4 -0
  41. package/src/ui-tailwind/editor-surface/surface-build-keys.ts +5 -2
  42. package/src/ui-tailwind/page-stack/use-visible-block-range.ts +99 -43
  43. package/src/ui-tailwind/review-workspace/use-page-markers.ts +48 -7
  44. package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +8 -8
  45. package/src/ui-tailwind/tw-review-workspace.tsx +13 -35
  46. package/src/validation/compatibility-engine.ts +1 -1
  47. package/src/ui-tailwind/chrome/tw-layout-panel.tsx +0 -114
  48. package/src/ui-tailwind/review-workspace/tw-review-workspace-page-toolbar.tsx +0 -240
@@ -1,240 +0,0 @@
1
- import React from "react";
2
-
3
- import { ChevronRight } from "lucide-react";
4
-
5
- import { preserveEditorSelectionMouseDown } from "../../ui/headless/preserve-editor-selection";
6
- import { TwPageRuler } from "../chrome/tw-page-ruler";
7
- import { TwLayoutPanel } from "../chrome/tw-layout-panel";
8
- import type {
9
- DocumentNavigationSnapshot,
10
- EditorViewStateSnapshot,
11
- HeaderFooterLinkPatch,
12
- RuntimeRenderSnapshot,
13
- SectionBreakType,
14
- SectionLayoutPatch,
15
- SectionPageNumberingPatch,
16
- } from "../../api/public-types";
17
- import type { ActiveParagraphLayout } from "./paragraph-layout";
18
-
19
- /**
20
- * Page-mode inline toolbar: the "Page N of M · Section N · orientation"
21
- * summary strip plus the expandable `TwPageRuler` + `TwLayoutPanel`
22
- * cluster. Lifted verbatim from `tw-review-workspace.tsx` — no behavior
23
- * changes.
24
- */
25
- export interface TwReviewWorkspacePageToolbarProps {
26
- /** `isPageWorkspace && chromeVisibility.pageChrome && snapshot.pageLayout` */
27
- enabled: boolean;
28
- pageLayout: RuntimeRenderSnapshot["pageLayout"];
29
- activeStory: RuntimeRenderSnapshot["activeStory"];
30
- activePage: DocumentNavigationSnapshot["pages"][number] | null;
31
- pageCount: number;
32
- headerVariant: HeaderFooterLinkPatch["variant"];
33
- footerVariant: HeaderFooterLinkPatch["variant"];
34
- allowLocalChromeMutations: boolean;
35
- pageChromeReadOnly: boolean;
36
- layoutToolsOpen: boolean;
37
- setLayoutToolsOpen: (fn: (open: boolean) => boolean) => void;
38
- viewState: EditorViewStateSnapshot;
39
- activeParagraphLayout: ActiveParagraphLayout | null;
40
-
41
- /** Dismiss the floating selection toolbar before committing any action. */
42
- dismissSelectionToolbar: () => void;
43
- /** Wrap an optional nullary callback so it dismisses the toolbar first. */
44
- runWithSelectionToolbarDismiss: (action?: () => void) => () => void;
45
-
46
- onCloseStory?: () => void;
47
- onOpenHeaderStory?: () => void;
48
- onOpenFooterStory?: () => void;
49
- onSetHeaderFooterLink?: (sectionIndex: number, patch: HeaderFooterLinkPatch) => void;
50
- onSetParagraphIndentation?: (indentation: Parameters<NonNullable<React.ComponentProps<typeof TwPageRuler>["onSetIndentation"]>>[0]) => void;
51
- onSetParagraphTabStops?: (tabStops: Parameters<NonNullable<React.ComponentProps<typeof TwPageRuler>["onSetTabStops"]>>[0]) => void;
52
- onRestartNumbering?: () => void;
53
- onContinueNumbering?: () => void;
54
- onInsertSectionBreak?: (type: SectionBreakType) => void;
55
- onDeleteSectionBreak?: (sectionIndex: number) => void;
56
- onUpdateSectionLayout?: (sectionIndex: number, patch: SectionLayoutPatch) => void;
57
- onSetSectionPageNumbering?: (sectionIndex: number, patch: SectionPageNumberingPatch | null) => void;
58
- }
59
-
60
- export function TwReviewWorkspacePageToolbar({
61
- enabled,
62
- pageLayout,
63
- activeStory,
64
- activePage,
65
- pageCount,
66
- headerVariant,
67
- footerVariant,
68
- allowLocalChromeMutations,
69
- pageChromeReadOnly,
70
- layoutToolsOpen,
71
- setLayoutToolsOpen,
72
- viewState,
73
- activeParagraphLayout,
74
- dismissSelectionToolbar,
75
- runWithSelectionToolbarDismiss,
76
- onCloseStory,
77
- onOpenHeaderStory,
78
- onOpenFooterStory,
79
- onSetHeaderFooterLink,
80
- onSetParagraphIndentation,
81
- onSetParagraphTabStops,
82
- onRestartNumbering,
83
- onContinueNumbering,
84
- onInsertSectionBreak,
85
- onDeleteSectionBreak,
86
- onUpdateSectionLayout,
87
- onSetSectionPageNumbering,
88
- }: TwReviewWorkspacePageToolbarProps): React.ReactElement | null {
89
- if (!enabled || !pageLayout) return null;
90
-
91
- return (
92
- <>
93
- <div className="border-b border-border/70 bg-surface/65 px-5 py-3" data-testid="page-context-summary">
94
- <div className="flex flex-wrap items-center justify-between gap-2">
95
- <div className="flex flex-wrap items-center gap-2 text-xs text-secondary">
96
- <span className="rounded-full bg-canvas px-2 py-1 font-medium text-primary">
97
- {activePage
98
- ? `Page ${activePage.pageIndex + 1} of ${pageCount}`
99
- : "Page workspace"}
100
- </span>
101
- <span>{`Section ${pageLayout.sectionIndex + 1}`}</span>
102
- <span className="uppercase tracking-[0.12em] text-tertiary">
103
- {pageLayout.orientation}
104
- </span>
105
- </div>
106
- <div className="flex items-center gap-2">
107
- {activeStory.kind !== "main" ? (
108
- <button
109
- type="button"
110
- aria-label="Return to document body"
111
- onMouseDown={preserveEditorSelectionMouseDown}
112
- onClick={runWithSelectionToolbarDismiss(onCloseStory)}
113
- className="inline-flex items-center gap-1 rounded-md border border-border bg-canvas px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-surface"
114
- >
115
- Body
116
- </button>
117
- ) : null}
118
- {activeStory.kind === "main" && pageLayout.sectionIndex > 0 ? (
119
- <>
120
- <button
121
- type="button"
122
- aria-label="Link header to previous"
123
- disabled={!onSetHeaderFooterLink || !allowLocalChromeMutations}
124
- onMouseDown={preserveEditorSelectionMouseDown}
125
- onClick={() => {
126
- dismissSelectionToolbar();
127
- onSetHeaderFooterLink?.(pageLayout.sectionIndex, {
128
- kind: "header",
129
- variant: headerVariant,
130
- linkToPrevious: true,
131
- });
132
- }}
133
- className="inline-flex items-center gap-1 rounded-md border border-border bg-canvas px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-40"
134
- >
135
- Link header
136
- </button>
137
- <button
138
- type="button"
139
- aria-label="Link footer to previous"
140
- disabled={!onSetHeaderFooterLink || !allowLocalChromeMutations}
141
- onMouseDown={preserveEditorSelectionMouseDown}
142
- onClick={() => {
143
- dismissSelectionToolbar();
144
- onSetHeaderFooterLink?.(pageLayout.sectionIndex, {
145
- kind: "footer",
146
- variant: footerVariant,
147
- linkToPrevious: true,
148
- });
149
- }}
150
- className="inline-flex items-center gap-1 rounded-md border border-border bg-canvas px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-40"
151
- >
152
- Link footer
153
- </button>
154
- </>
155
- ) : null}
156
- <button
157
- type="button"
158
- aria-label="Toggle layout tools"
159
- aria-expanded={layoutToolsOpen}
160
- onMouseDown={preserveEditorSelectionMouseDown}
161
- onClick={() => {
162
- dismissSelectionToolbar();
163
- setLayoutToolsOpen((open) => !open);
164
- }}
165
- className="inline-flex items-center gap-1 rounded-md border border-border bg-canvas px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-surface"
166
- >
167
- <ChevronRight className={`h-3.5 w-3.5 transition-transform ${layoutToolsOpen ? "rotate-90" : ""}`} />
168
- Layout tools
169
- </button>
170
- </div>
171
- </div>
172
- </div>
173
- {layoutToolsOpen ? (
174
- <div className="px-5 pt-3">
175
- <TwPageRuler
176
- pageLayout={pageLayout}
177
- viewState={viewState}
178
- paragraphLayout={activeParagraphLayout}
179
- readOnly={pageChromeReadOnly}
180
- onReturnToBody={onCloseStory
181
- ? runWithSelectionToolbarDismiss(onCloseStory)
182
- : () => undefined}
183
- onOpenHeader={onOpenHeaderStory
184
- ? runWithSelectionToolbarDismiss(onOpenHeaderStory)
185
- : undefined}
186
- onOpenFooter={onOpenFooterStory
187
- ? runWithSelectionToolbarDismiss(onOpenFooterStory)
188
- : undefined}
189
- onSetIndentation={onSetParagraphIndentation
190
- ? (indentation) => {
191
- dismissSelectionToolbar();
192
- onSetParagraphIndentation?.(indentation);
193
- }
194
- : undefined}
195
- onSetTabStops={onSetParagraphTabStops
196
- ? (tabStops) => {
197
- dismissSelectionToolbar();
198
- onSetParagraphTabStops?.(tabStops);
199
- }
200
- : undefined}
201
- onRestartNumbering={onRestartNumbering
202
- ? runWithSelectionToolbarDismiss(onRestartNumbering)
203
- : undefined}
204
- onContinueNumbering={onContinueNumbering
205
- ? runWithSelectionToolbarDismiss(onContinueNumbering)
206
- : undefined}
207
- />
208
- <TwLayoutPanel
209
- pageLayout={pageLayout}
210
- readOnly={pageChromeReadOnly}
211
- onInsertSectionBreak={onInsertSectionBreak
212
- ? (type) => {
213
- dismissSelectionToolbar();
214
- onInsertSectionBreak?.(type);
215
- }
216
- : undefined}
217
- onDeleteSectionBreak={onDeleteSectionBreak
218
- ? (sectionIndex) => {
219
- dismissSelectionToolbar();
220
- onDeleteSectionBreak?.(sectionIndex);
221
- }
222
- : undefined}
223
- onUpdateSectionLayout={onUpdateSectionLayout
224
- ? (sectionIndex, patch) => {
225
- dismissSelectionToolbar();
226
- onUpdateSectionLayout?.(sectionIndex, patch);
227
- }
228
- : undefined}
229
- onSetSectionPageNumbering={onSetSectionPageNumbering
230
- ? (sectionIndex, patch) => {
231
- dismissSelectionToolbar();
232
- onSetSectionPageNumbering?.(sectionIndex, patch);
233
- }
234
- : undefined}
235
- />
236
- </div>
237
- ) : null}
238
- </>
239
- );
240
- }