@beyondwork/docx-react-component 1.0.37 → 1.0.38
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/package.json +1 -1
- package/src/api/public-types.ts +319 -1
- package/src/core/commands/section-layout-commands.ts +58 -0
- package/src/core/commands/table-grid.ts +431 -0
- package/src/core/commands/table-structure-commands.ts +815 -55
- package/src/io/export/serialize-main-document.ts +2 -11
- package/src/io/export/serialize-numbering.ts +1 -2
- package/src/io/export/serialize-tables.ts +74 -0
- package/src/io/export/table-properties-xml.ts +139 -4
- package/src/io/normalize/normalize-text.ts +15 -0
- package/src/io/ooxml/parse-footnotes.ts +60 -0
- package/src/io/ooxml/parse-headers-footers.ts +60 -0
- package/src/io/ooxml/parse-main-document.ts +137 -0
- package/src/io/ooxml/parse-tables.ts +249 -0
- package/src/model/canonical-document.ts +34 -0
- package/src/runtime/document-layout.ts +4 -2
- package/src/runtime/document-navigation.ts +1 -1
- package/src/runtime/document-runtime.ts +114 -0
- package/src/runtime/layout/default-page-format.ts +96 -0
- package/src/runtime/layout/index.ts +45 -0
- package/src/runtime/layout/inert-layout-facet.ts +14 -0
- package/src/runtime/layout/layout-engine-instance.ts +33 -23
- package/src/runtime/layout/margin-preset-catalog.ts +178 -0
- package/src/runtime/layout/page-format-catalog.ts +233 -0
- package/src/runtime/layout/page-graph.ts +19 -0
- package/src/runtime/layout/paginated-layout-engine.ts +142 -9
- package/src/runtime/layout/project-block-fragments.ts +91 -0
- package/src/runtime/layout/public-facet.ts +709 -16
- package/src/runtime/layout/table-render-plan.ts +229 -0
- package/src/runtime/render/block-fragment-projection.ts +35 -0
- package/src/runtime/render/decoration-resolver.ts +189 -0
- package/src/runtime/render/index.ts +57 -0
- package/src/runtime/render/pending-op-delta-reader.ts +129 -0
- package/src/runtime/render/render-frame-types.ts +317 -0
- package/src/runtime/render/render-kernel.ts +755 -0
- package/src/runtime/view-state.ts +67 -0
- package/src/runtime/workflow-markup.ts +1 -5
- package/src/runtime/workflow-rail-segments.ts +280 -0
- package/src/ui/WordReviewEditor.tsx +84 -15
- package/src/ui/editor-shell-view.tsx +6 -0
- package/src/ui/headless/chrome-registry.ts +280 -14
- package/src/ui/headless/scoped-chrome-policy.ts +20 -1
- package/src/ui/headless/selection-tool-types.ts +10 -0
- package/src/ui-tailwind/chrome/chrome-preset-model.ts +23 -2
- package/src/ui-tailwind/chrome/role-action-sets.ts +74 -0
- package/src/ui-tailwind/chrome/tw-detach-handle.tsx +147 -0
- package/src/ui-tailwind/chrome/tw-selection-anchor-resolver.ts +163 -0
- package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +57 -92
- package/src/ui-tailwind/chrome/tw-selection-tool-placement.ts +149 -0
- package/src/ui-tailwind/chrome/tw-selection-toolbar.tsx +15 -4
- package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +274 -138
- package/src/ui-tailwind/chrome-overlay/chrome-overlay-projector.ts +90 -0
- package/src/ui-tailwind/chrome-overlay/index.ts +22 -0
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +86 -0
- package/src/ui-tailwind/chrome-overlay/tw-scope-rail-layer.tsx +178 -0
- package/src/ui-tailwind/chrome-overlay/tw-workspace-view-switcher.tsx +95 -0
- package/src/ui-tailwind/editor-surface/fast-text-edit-lane.ts +4 -0
- package/src/ui-tailwind/editor-surface/local-edit-session-state.ts +11 -0
- package/src/ui-tailwind/editor-surface/perf-probe.ts +7 -1
- package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +12 -1
- package/src/ui-tailwind/editor-surface/pm-decorations.ts +22 -12
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +3 -0
- package/src/ui-tailwind/index.ts +33 -0
- package/src/ui-tailwind/review/tw-comment-sidebar.tsx +2 -2
- package/src/ui-tailwind/review/tw-rail-card.tsx +150 -0
- package/src/ui-tailwind/review/tw-review-rail-footer.tsx +52 -0
- package/src/ui-tailwind/review/tw-review-rail.tsx +166 -11
- package/src/ui-tailwind/review/tw-workflow-tab.tsx +108 -0
- package/src/ui-tailwind/theme/editor-theme.css +498 -163
- package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +559 -0
- package/src/ui-tailwind/toolbar/tw-scope-posture-menu.tsx +182 -0
- package/src/ui-tailwind/toolbar/tw-shell-header.tsx +162 -0
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +69 -0
- package/src/ui-tailwind/tw-review-workspace.tsx +136 -1
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
EditorRole,
|
|
3
|
+
WordReviewEditorChromePreset,
|
|
4
|
+
} from "../../api/public-types";
|
|
2
5
|
import type { SelectionToolKind } from "./selection-tool-types";
|
|
3
6
|
|
|
4
7
|
export type ChromeSurface = "top-toolbar" | "selection-tool";
|
|
@@ -6,6 +9,7 @@ export type ChromeDensity = "compact";
|
|
|
6
9
|
export type ToolbarChromePlacement = "inline" | "overflow" | "hidden";
|
|
7
10
|
|
|
8
11
|
export type ToolbarChromeItemId =
|
|
12
|
+
// Universal formatting + history
|
|
9
13
|
| "history"
|
|
10
14
|
| "text-style-selectors"
|
|
11
15
|
| "inline-formatting"
|
|
@@ -24,7 +28,25 @@ export type ToolbarChromeItemId =
|
|
|
24
28
|
| "workspace-mode"
|
|
25
29
|
| "zoom"
|
|
26
30
|
| "health"
|
|
27
|
-
| "export"
|
|
31
|
+
| "export"
|
|
32
|
+
// R1: role-scoped action region entries
|
|
33
|
+
| "editor-scope-posture-menu"
|
|
34
|
+
| "review-queue-prev"
|
|
35
|
+
| "review-queue-next"
|
|
36
|
+
| "review-queue-counts"
|
|
37
|
+
| "review-queue-active-label"
|
|
38
|
+
| "review-accept"
|
|
39
|
+
| "review-reject"
|
|
40
|
+
| "review-accept-all"
|
|
41
|
+
| "review-reject-all"
|
|
42
|
+
| "review-markup-mode"
|
|
43
|
+
| "workflow-prev"
|
|
44
|
+
| "workflow-next"
|
|
45
|
+
| "workflow-mark-complete"
|
|
46
|
+
| "workflow-claim"
|
|
47
|
+
| "workflow-skip"
|
|
48
|
+
| "workflow-mark-blocked"
|
|
49
|
+
| "workflow-jump-to-scope";
|
|
28
50
|
|
|
29
51
|
export interface ChromeRegistryEntryBase {
|
|
30
52
|
id: string;
|
|
@@ -42,12 +64,33 @@ export interface ToolbarChromeRegistryEntry extends ChromeRegistryEntryBase {
|
|
|
42
64
|
id: ToolbarChromeItemId;
|
|
43
65
|
surfaces: ["top-toolbar"];
|
|
44
66
|
presets: ReadonlyArray<WordReviewEditorChromePreset>;
|
|
67
|
+
/**
|
|
68
|
+
* Roles in which this entry appears. Empty = appears in every role.
|
|
69
|
+
* R1 uses this to filter the inline action set down to the per-role
|
|
70
|
+
* matrix described in the chrome-phase plan.
|
|
71
|
+
*/
|
|
72
|
+
roles: ReadonlyArray<EditorRole>;
|
|
45
73
|
fullPlacement: Exclude<ToolbarChromePlacement, "hidden">;
|
|
46
74
|
compactPlacement: ToolbarChromePlacement;
|
|
47
75
|
runtimeBehavior: "always" | "formatting" | "structure" | "comment";
|
|
48
76
|
scopeBehavior?: "default" | "scoped-only" | "hidden-when-scoped";
|
|
77
|
+
/**
|
|
78
|
+
* Optional per-role placement override. When a role overrides the
|
|
79
|
+
* placement (for instance, "text-style-selectors" is `inline` in editor
|
|
80
|
+
* but `overflow` in review/workflow), list the role-specific placement
|
|
81
|
+
* here. Missing roles inherit `fullPlacement` / `compactPlacement`.
|
|
82
|
+
*/
|
|
83
|
+
rolePlacement?: Partial<
|
|
84
|
+
Record<EditorRole, Exclude<ToolbarChromePlacement, "hidden">>
|
|
85
|
+
>;
|
|
49
86
|
}
|
|
50
87
|
|
|
88
|
+
const ALL_ROLES: ReadonlyArray<EditorRole> = ["editor", "review", "workflow"];
|
|
89
|
+
const EDITOR_ONLY: ReadonlyArray<EditorRole> = ["editor"];
|
|
90
|
+
const REVIEW_ONLY: ReadonlyArray<EditorRole> = ["review"];
|
|
91
|
+
const WORKFLOW_ONLY: ReadonlyArray<EditorRole> = ["workflow"];
|
|
92
|
+
const EDITOR_AND_REVIEW: ReadonlyArray<EditorRole> = ["editor", "review"];
|
|
93
|
+
|
|
51
94
|
export const SELECTION_TOOL_REGISTRY: ReadonlyArray<SelectionToolRegistryEntry> = [
|
|
52
95
|
{ id: "suggestion-review", surfaces: ["selection-tool"], group: "review", precedence: 10 },
|
|
53
96
|
{ id: "comment-thread", surfaces: ["selection-tool"], group: "review", precedence: 20 },
|
|
@@ -62,7 +105,8 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
62
105
|
id: "history",
|
|
63
106
|
surfaces: ["top-toolbar"],
|
|
64
107
|
group: "history",
|
|
65
|
-
presets: ["simple", "advanced", "review"],
|
|
108
|
+
presets: ["simple", "advanced", "review", "workflow"],
|
|
109
|
+
roles: ALL_ROLES,
|
|
66
110
|
fullPlacement: "inline",
|
|
67
111
|
compactPlacement: "inline",
|
|
68
112
|
runtimeBehavior: "always",
|
|
@@ -71,61 +115,94 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
71
115
|
id: "text-style-selectors",
|
|
72
116
|
surfaces: ["top-toolbar"],
|
|
73
117
|
group: "text",
|
|
74
|
-
presets: ["advanced"],
|
|
118
|
+
presets: ["advanced", "workflow"],
|
|
119
|
+
roles: ALL_ROLES,
|
|
75
120
|
fullPlacement: "inline",
|
|
76
121
|
compactPlacement: "overflow",
|
|
77
122
|
runtimeBehavior: "formatting",
|
|
123
|
+
rolePlacement: {
|
|
124
|
+
editor: "inline",
|
|
125
|
+
review: "overflow",
|
|
126
|
+
workflow: "overflow",
|
|
127
|
+
},
|
|
78
128
|
},
|
|
79
129
|
{
|
|
80
130
|
id: "inline-formatting",
|
|
81
131
|
surfaces: ["top-toolbar"],
|
|
82
132
|
group: "text",
|
|
83
|
-
presets: ["simple", "advanced", "review"],
|
|
133
|
+
presets: ["simple", "advanced", "review", "workflow"],
|
|
134
|
+
roles: ALL_ROLES,
|
|
84
135
|
fullPlacement: "inline",
|
|
85
136
|
compactPlacement: "inline",
|
|
86
137
|
runtimeBehavior: "formatting",
|
|
138
|
+
rolePlacement: {
|
|
139
|
+
editor: "inline",
|
|
140
|
+
review: "overflow",
|
|
141
|
+
workflow: "overflow",
|
|
142
|
+
},
|
|
87
143
|
},
|
|
88
144
|
{
|
|
89
145
|
id: "text-colors",
|
|
90
146
|
surfaces: ["top-toolbar"],
|
|
91
147
|
group: "text",
|
|
92
148
|
presets: ["simple", "advanced"],
|
|
149
|
+
roles: EDITOR_AND_REVIEW,
|
|
93
150
|
fullPlacement: "inline",
|
|
94
151
|
compactPlacement: "inline",
|
|
95
152
|
runtimeBehavior: "formatting",
|
|
153
|
+
rolePlacement: {
|
|
154
|
+
editor: "inline",
|
|
155
|
+
review: "overflow",
|
|
156
|
+
},
|
|
96
157
|
},
|
|
97
158
|
{
|
|
98
159
|
id: "paragraph-alignment",
|
|
99
160
|
surfaces: ["top-toolbar"],
|
|
100
161
|
group: "paragraph",
|
|
101
162
|
presets: ["simple", "advanced"],
|
|
163
|
+
roles: EDITOR_AND_REVIEW,
|
|
102
164
|
fullPlacement: "inline",
|
|
103
165
|
compactPlacement: "inline",
|
|
104
166
|
runtimeBehavior: "formatting",
|
|
167
|
+
rolePlacement: {
|
|
168
|
+
editor: "inline",
|
|
169
|
+
review: "overflow",
|
|
170
|
+
},
|
|
105
171
|
},
|
|
106
172
|
{
|
|
107
173
|
id: "list-actions",
|
|
108
174
|
surfaces: ["top-toolbar"],
|
|
109
175
|
group: "paragraph",
|
|
110
176
|
presets: ["simple", "advanced"],
|
|
177
|
+
roles: EDITOR_AND_REVIEW,
|
|
111
178
|
fullPlacement: "inline",
|
|
112
179
|
compactPlacement: "overflow",
|
|
113
180
|
runtimeBehavior: "formatting",
|
|
181
|
+
rolePlacement: {
|
|
182
|
+
editor: "inline",
|
|
183
|
+
review: "overflow",
|
|
184
|
+
},
|
|
114
185
|
},
|
|
115
186
|
{
|
|
116
187
|
id: "indentation",
|
|
117
188
|
surfaces: ["top-toolbar"],
|
|
118
189
|
group: "paragraph",
|
|
119
190
|
presets: ["simple", "advanced"],
|
|
191
|
+
roles: EDITOR_AND_REVIEW,
|
|
120
192
|
fullPlacement: "inline",
|
|
121
193
|
compactPlacement: "overflow",
|
|
122
194
|
runtimeBehavior: "formatting",
|
|
195
|
+
rolePlacement: {
|
|
196
|
+
editor: "inline",
|
|
197
|
+
review: "overflow",
|
|
198
|
+
},
|
|
123
199
|
},
|
|
124
200
|
{
|
|
125
201
|
id: "list-continuation",
|
|
126
202
|
surfaces: ["top-toolbar"],
|
|
127
203
|
group: "paragraph",
|
|
128
204
|
presets: ["simple", "advanced"],
|
|
205
|
+
roles: EDITOR_ONLY,
|
|
129
206
|
fullPlacement: "inline",
|
|
130
207
|
compactPlacement: "overflow",
|
|
131
208
|
runtimeBehavior: "formatting",
|
|
@@ -135,6 +212,7 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
135
212
|
surfaces: ["top-toolbar"],
|
|
136
213
|
group: "document",
|
|
137
214
|
presets: ["simple", "advanced"],
|
|
215
|
+
roles: EDITOR_ONLY,
|
|
138
216
|
fullPlacement: "inline",
|
|
139
217
|
compactPlacement: "overflow",
|
|
140
218
|
runtimeBehavior: "structure",
|
|
@@ -145,6 +223,7 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
145
223
|
surfaces: ["top-toolbar"],
|
|
146
224
|
group: "document",
|
|
147
225
|
presets: ["advanced"],
|
|
226
|
+
roles: EDITOR_ONLY,
|
|
148
227
|
fullPlacement: "inline",
|
|
149
228
|
compactPlacement: "overflow",
|
|
150
229
|
runtimeBehavior: "structure",
|
|
@@ -154,7 +233,8 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
154
233
|
id: "scope-status",
|
|
155
234
|
surfaces: ["top-toolbar"],
|
|
156
235
|
group: "scope",
|
|
157
|
-
presets: ["simple", "advanced", "review"],
|
|
236
|
+
presets: ["simple", "advanced", "review", "workflow"],
|
|
237
|
+
roles: ALL_ROLES,
|
|
158
238
|
fullPlacement: "inline",
|
|
159
239
|
compactPlacement: "inline",
|
|
160
240
|
runtimeBehavior: "always",
|
|
@@ -164,7 +244,8 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
164
244
|
id: "story-breadcrumb",
|
|
165
245
|
surfaces: ["top-toolbar"],
|
|
166
246
|
group: "scope",
|
|
167
|
-
presets: ["simple", "advanced", "review"],
|
|
247
|
+
presets: ["simple", "advanced", "review", "workflow"],
|
|
248
|
+
roles: ALL_ROLES,
|
|
168
249
|
fullPlacement: "inline",
|
|
169
250
|
compactPlacement: "inline",
|
|
170
251
|
runtimeBehavior: "always",
|
|
@@ -173,7 +254,8 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
173
254
|
id: "sidebar-toggle",
|
|
174
255
|
surfaces: ["top-toolbar"],
|
|
175
256
|
group: "review",
|
|
176
|
-
presets: ["simple", "advanced", "review"],
|
|
257
|
+
presets: ["simple", "advanced", "review", "workflow"],
|
|
258
|
+
roles: ALL_ROLES,
|
|
177
259
|
fullPlacement: "inline",
|
|
178
260
|
compactPlacement: "inline",
|
|
179
261
|
runtimeBehavior: "always",
|
|
@@ -182,7 +264,8 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
182
264
|
id: "comment",
|
|
183
265
|
surfaces: ["top-toolbar"],
|
|
184
266
|
group: "review",
|
|
185
|
-
presets: ["simple", "advanced", "review"],
|
|
267
|
+
presets: ["simple", "advanced", "review", "workflow"],
|
|
268
|
+
roles: ALL_ROLES,
|
|
186
269
|
fullPlacement: "inline",
|
|
187
270
|
compactPlacement: "inline",
|
|
188
271
|
runtimeBehavior: "comment",
|
|
@@ -191,7 +274,10 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
191
274
|
id: "tracked-changes-toggle",
|
|
192
275
|
surfaces: ["top-toolbar"],
|
|
193
276
|
group: "review",
|
|
194
|
-
|
|
277
|
+
// R1 promotes this toggle to every preset that shows a toolbar so the
|
|
278
|
+
// editor role can see inline tracked changes without switching preset.
|
|
279
|
+
presets: ["simple", "advanced", "review", "workflow"],
|
|
280
|
+
roles: ALL_ROLES,
|
|
195
281
|
fullPlacement: "inline",
|
|
196
282
|
compactPlacement: "inline",
|
|
197
283
|
runtimeBehavior: "always",
|
|
@@ -200,7 +286,8 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
200
286
|
id: "workspace-mode",
|
|
201
287
|
surfaces: ["top-toolbar"],
|
|
202
288
|
group: "view",
|
|
203
|
-
presets: ["simple", "advanced", "review"],
|
|
289
|
+
presets: ["simple", "advanced", "review", "workflow"],
|
|
290
|
+
roles: ALL_ROLES,
|
|
204
291
|
fullPlacement: "inline",
|
|
205
292
|
compactPlacement: "inline",
|
|
206
293
|
runtimeBehavior: "always",
|
|
@@ -209,7 +296,8 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
209
296
|
id: "zoom",
|
|
210
297
|
surfaces: ["top-toolbar"],
|
|
211
298
|
group: "view",
|
|
212
|
-
presets: ["simple", "advanced", "review"],
|
|
299
|
+
presets: ["simple", "advanced", "review", "workflow"],
|
|
300
|
+
roles: ALL_ROLES,
|
|
213
301
|
fullPlacement: "inline",
|
|
214
302
|
compactPlacement: "inline",
|
|
215
303
|
runtimeBehavior: "always",
|
|
@@ -218,7 +306,8 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
218
306
|
id: "health",
|
|
219
307
|
surfaces: ["top-toolbar"],
|
|
220
308
|
group: "status",
|
|
221
|
-
presets: ["simple", "advanced", "review"],
|
|
309
|
+
presets: ["simple", "advanced", "review", "workflow"],
|
|
310
|
+
roles: ALL_ROLES,
|
|
222
311
|
fullPlacement: "inline",
|
|
223
312
|
compactPlacement: "inline",
|
|
224
313
|
runtimeBehavior: "always",
|
|
@@ -227,9 +316,186 @@ export const TOOLBAR_CHROME_REGISTRY: ReadonlyArray<ToolbarChromeRegistryEntry>
|
|
|
227
316
|
id: "export",
|
|
228
317
|
surfaces: ["top-toolbar"],
|
|
229
318
|
group: "status",
|
|
230
|
-
presets: ["simple", "advanced", "review"],
|
|
319
|
+
presets: ["simple", "advanced", "review", "workflow"],
|
|
320
|
+
roles: ALL_ROLES,
|
|
321
|
+
fullPlacement: "inline",
|
|
322
|
+
compactPlacement: "inline",
|
|
323
|
+
runtimeBehavior: "always",
|
|
324
|
+
},
|
|
325
|
+
|
|
326
|
+
// ───── R1: Editor-role primaries ──────────────────────────────────────
|
|
327
|
+
{
|
|
328
|
+
id: "editor-scope-posture-menu",
|
|
329
|
+
surfaces: ["top-toolbar"],
|
|
330
|
+
group: "scope",
|
|
331
|
+
presets: ["advanced", "review", "workflow"],
|
|
332
|
+
roles: EDITOR_ONLY,
|
|
333
|
+
fullPlacement: "inline",
|
|
334
|
+
compactPlacement: "overflow",
|
|
335
|
+
runtimeBehavior: "always",
|
|
336
|
+
},
|
|
337
|
+
|
|
338
|
+
// ───── R1: Review-role primaries ──────────────────────────────────────
|
|
339
|
+
{
|
|
340
|
+
id: "review-queue-prev",
|
|
341
|
+
surfaces: ["top-toolbar"],
|
|
342
|
+
group: "review-queue",
|
|
343
|
+
presets: ["review", "workflow"],
|
|
344
|
+
roles: REVIEW_ONLY,
|
|
345
|
+
fullPlacement: "inline",
|
|
346
|
+
compactPlacement: "inline",
|
|
347
|
+
runtimeBehavior: "always",
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
id: "review-queue-next",
|
|
351
|
+
surfaces: ["top-toolbar"],
|
|
352
|
+
group: "review-queue",
|
|
353
|
+
presets: ["review", "workflow"],
|
|
354
|
+
roles: REVIEW_ONLY,
|
|
355
|
+
fullPlacement: "inline",
|
|
356
|
+
compactPlacement: "inline",
|
|
357
|
+
runtimeBehavior: "always",
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
id: "review-queue-counts",
|
|
361
|
+
surfaces: ["top-toolbar"],
|
|
362
|
+
group: "review-queue",
|
|
363
|
+
presets: ["review"],
|
|
364
|
+
roles: REVIEW_ONLY,
|
|
365
|
+
fullPlacement: "inline",
|
|
366
|
+
compactPlacement: "overflow",
|
|
367
|
+
runtimeBehavior: "always",
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
id: "review-queue-active-label",
|
|
371
|
+
surfaces: ["top-toolbar"],
|
|
372
|
+
group: "review-queue",
|
|
373
|
+
presets: ["review"],
|
|
374
|
+
roles: REVIEW_ONLY,
|
|
375
|
+
fullPlacement: "inline",
|
|
376
|
+
compactPlacement: "overflow",
|
|
377
|
+
runtimeBehavior: "always",
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
id: "review-accept",
|
|
381
|
+
surfaces: ["top-toolbar"],
|
|
382
|
+
group: "review-action",
|
|
383
|
+
presets: ["review"],
|
|
384
|
+
roles: REVIEW_ONLY,
|
|
385
|
+
fullPlacement: "inline",
|
|
386
|
+
compactPlacement: "inline",
|
|
387
|
+
runtimeBehavior: "always",
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
id: "review-reject",
|
|
391
|
+
surfaces: ["top-toolbar"],
|
|
392
|
+
group: "review-action",
|
|
393
|
+
presets: ["review"],
|
|
394
|
+
roles: REVIEW_ONLY,
|
|
395
|
+
fullPlacement: "inline",
|
|
396
|
+
compactPlacement: "inline",
|
|
397
|
+
runtimeBehavior: "always",
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
id: "review-accept-all",
|
|
401
|
+
surfaces: ["top-toolbar"],
|
|
402
|
+
group: "review-action",
|
|
403
|
+
presets: ["review"],
|
|
404
|
+
roles: REVIEW_ONLY,
|
|
405
|
+
fullPlacement: "inline",
|
|
406
|
+
compactPlacement: "overflow",
|
|
407
|
+
runtimeBehavior: "always",
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
id: "review-reject-all",
|
|
411
|
+
surfaces: ["top-toolbar"],
|
|
412
|
+
group: "review-action",
|
|
413
|
+
presets: ["review"],
|
|
414
|
+
roles: REVIEW_ONLY,
|
|
415
|
+
fullPlacement: "inline",
|
|
416
|
+
compactPlacement: "overflow",
|
|
417
|
+
runtimeBehavior: "always",
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
id: "review-markup-mode",
|
|
421
|
+
surfaces: ["top-toolbar"],
|
|
422
|
+
group: "review-action",
|
|
423
|
+
presets: ["review"],
|
|
424
|
+
roles: REVIEW_ONLY,
|
|
425
|
+
fullPlacement: "inline",
|
|
426
|
+
compactPlacement: "inline",
|
|
427
|
+
runtimeBehavior: "always",
|
|
428
|
+
},
|
|
429
|
+
|
|
430
|
+
// ───── R1: Workflow-role primaries ────────────────────────────────────
|
|
431
|
+
{
|
|
432
|
+
id: "workflow-prev",
|
|
433
|
+
surfaces: ["top-toolbar"],
|
|
434
|
+
group: "workflow-queue",
|
|
435
|
+
presets: ["workflow"],
|
|
436
|
+
roles: WORKFLOW_ONLY,
|
|
437
|
+
fullPlacement: "inline",
|
|
438
|
+
compactPlacement: "inline",
|
|
439
|
+
runtimeBehavior: "always",
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
id: "workflow-next",
|
|
443
|
+
surfaces: ["top-toolbar"],
|
|
444
|
+
group: "workflow-queue",
|
|
445
|
+
presets: ["workflow"],
|
|
446
|
+
roles: WORKFLOW_ONLY,
|
|
447
|
+
fullPlacement: "inline",
|
|
448
|
+
compactPlacement: "inline",
|
|
449
|
+
runtimeBehavior: "always",
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
id: "workflow-mark-complete",
|
|
453
|
+
surfaces: ["top-toolbar"],
|
|
454
|
+
group: "workflow-action",
|
|
455
|
+
presets: ["workflow"],
|
|
456
|
+
roles: WORKFLOW_ONLY,
|
|
457
|
+
fullPlacement: "inline",
|
|
458
|
+
compactPlacement: "inline",
|
|
459
|
+
runtimeBehavior: "always",
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
id: "workflow-claim",
|
|
463
|
+
surfaces: ["top-toolbar"],
|
|
464
|
+
group: "workflow-action",
|
|
465
|
+
presets: ["workflow"],
|
|
466
|
+
roles: WORKFLOW_ONLY,
|
|
231
467
|
fullPlacement: "inline",
|
|
232
468
|
compactPlacement: "inline",
|
|
233
469
|
runtimeBehavior: "always",
|
|
234
470
|
},
|
|
471
|
+
{
|
|
472
|
+
id: "workflow-skip",
|
|
473
|
+
surfaces: ["top-toolbar"],
|
|
474
|
+
group: "workflow-action",
|
|
475
|
+
presets: ["workflow"],
|
|
476
|
+
roles: WORKFLOW_ONLY,
|
|
477
|
+
fullPlacement: "inline",
|
|
478
|
+
compactPlacement: "overflow",
|
|
479
|
+
runtimeBehavior: "always",
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
id: "workflow-mark-blocked",
|
|
483
|
+
surfaces: ["top-toolbar"],
|
|
484
|
+
group: "workflow-action",
|
|
485
|
+
presets: ["workflow"],
|
|
486
|
+
roles: WORKFLOW_ONLY,
|
|
487
|
+
fullPlacement: "inline",
|
|
488
|
+
compactPlacement: "overflow",
|
|
489
|
+
runtimeBehavior: "always",
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
id: "workflow-jump-to-scope",
|
|
493
|
+
surfaces: ["top-toolbar"],
|
|
494
|
+
group: "workflow-action",
|
|
495
|
+
presets: ["workflow"],
|
|
496
|
+
roles: WORKFLOW_ONLY,
|
|
497
|
+
fullPlacement: "inline",
|
|
498
|
+
compactPlacement: "overflow",
|
|
499
|
+
runtimeBehavior: "always",
|
|
500
|
+
},
|
|
235
501
|
];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ActiveListContext,
|
|
3
|
+
EditorRole,
|
|
3
4
|
InteractionGuardSnapshot,
|
|
4
5
|
WorkflowScopeSnapshot,
|
|
5
6
|
WordReviewEditorChromePreset,
|
|
@@ -36,6 +37,13 @@ export interface ResolveScopedChromePolicyInput {
|
|
|
36
37
|
interactionGuardSnapshot?: InteractionGuardSnapshot;
|
|
37
38
|
workflowScopeSnapshot?: WorkflowScopeSnapshot | null;
|
|
38
39
|
activeListContext?: ActiveListContext | null;
|
|
40
|
+
/**
|
|
41
|
+
* Active chrome role (spec §6.4). When supplied, the policy filters
|
|
42
|
+
* registry entries whose `roles` array excludes the active role. When
|
|
43
|
+
* omitted, the preset filter alone drives visibility (back-compat for
|
|
44
|
+
* callers that haven't adopted the role model yet).
|
|
45
|
+
*/
|
|
46
|
+
role?: EditorRole;
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
export function resolveScopedChromePolicy(
|
|
@@ -62,6 +70,13 @@ export function resolveScopedChromePolicy(
|
|
|
62
70
|
TOOLBAR_CHROME_REGISTRY.map((entry) => {
|
|
63
71
|
let visible = entry.presets.includes(input.preset);
|
|
64
72
|
|
|
73
|
+
// Role filter — apply only when the caller supplied a role so existing
|
|
74
|
+
// host apps that haven't adopted the role model keep the pre-R1
|
|
75
|
+
// behavior (preset + capability only).
|
|
76
|
+
if (visible && input.role !== undefined) {
|
|
77
|
+
visible = entry.roles.includes(input.role);
|
|
78
|
+
}
|
|
79
|
+
|
|
65
80
|
if (visible) {
|
|
66
81
|
switch (entry.runtimeBehavior) {
|
|
67
82
|
case "formatting":
|
|
@@ -93,8 +108,12 @@ export function resolveScopedChromePolicy(
|
|
|
93
108
|
visible = !hasScopedContext;
|
|
94
109
|
}
|
|
95
110
|
|
|
111
|
+
// Resolve placement: when the entry overrides placement for the
|
|
112
|
+
// active role, that wins over the preset-density default.
|
|
113
|
+
const fullPlacement =
|
|
114
|
+
(input.role && entry.rolePlacement?.[input.role]) ?? entry.fullPlacement;
|
|
96
115
|
const placement = visible
|
|
97
|
-
? (input.compactMode ? entry.compactPlacement :
|
|
116
|
+
? (input.compactMode ? entry.compactPlacement : fullPlacement)
|
|
98
117
|
: "hidden";
|
|
99
118
|
const enabled =
|
|
100
119
|
visible &&
|
|
@@ -59,6 +59,16 @@ export interface FormattingInlineSelectionToolModel extends BaseSelectionToolMod
|
|
|
59
59
|
italicActive: boolean;
|
|
60
60
|
underlineActive: boolean;
|
|
61
61
|
canAddComment: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* One-click "apply" color for the text-color affordance. R2.5 plumbs
|
|
64
|
+
* the current `formattingState.textColor` (or the user's most recent
|
|
65
|
+
* pick) here so the mini-toolbar reflects the active color instead of
|
|
66
|
+
* a hardcoded blue. Consumers fall back to a fixed default when
|
|
67
|
+
* absent.
|
|
68
|
+
*/
|
|
69
|
+
textColorDefault?: string;
|
|
70
|
+
/** Matching one-click highlight color. See `textColorDefault`. */
|
|
71
|
+
highlightColorDefault?: string;
|
|
62
72
|
}
|
|
63
73
|
|
|
64
74
|
export interface SuggestionReviewSelectionToolModel extends BaseSelectionToolModel {
|
|
@@ -7,12 +7,15 @@ import type {
|
|
|
7
7
|
|
|
8
8
|
export function resolveChromePreset(
|
|
9
9
|
chromePreset: WordReviewEditorProps["chromePreset"],
|
|
10
|
-
|
|
10
|
+
reviewMode: WordReviewEditorProps["reviewMode"] = "review",
|
|
11
11
|
): WordReviewEditorChromePreset {
|
|
12
12
|
if (chromePreset) {
|
|
13
13
|
return chromePreset;
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
// When the host does not set an explicit preset, pick one from the
|
|
16
|
+
// review-mode signal so review sessions get the review strip inline
|
|
17
|
+
// with the toolbar (rather than the density default "advanced").
|
|
18
|
+
return reviewMode === "review" ? "review" : "advanced";
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
export function resolveChromePresetOptions(
|
|
@@ -40,6 +43,14 @@ export function resolveChromePresetOptions(
|
|
|
40
43
|
showSectionTagAction: true,
|
|
41
44
|
showReviewRail: true,
|
|
42
45
|
},
|
|
46
|
+
workflow: {
|
|
47
|
+
// Workflow role consolidates prev/next + mark-section into the top
|
|
48
|
+
// toolbar via the role-action region, so the separate queue bar
|
|
49
|
+
// strip is suppressed.
|
|
50
|
+
showReviewQueueBar: false,
|
|
51
|
+
showSectionTagAction: false,
|
|
52
|
+
showReviewRail: true,
|
|
53
|
+
},
|
|
43
54
|
};
|
|
44
55
|
|
|
45
56
|
return {
|
|
@@ -95,6 +106,16 @@ export function resolveChromeVisibilityForPreset(input: {
|
|
|
95
106
|
statusBar: true,
|
|
96
107
|
reviewRail: options.showReviewRail,
|
|
97
108
|
},
|
|
109
|
+
workflow: {
|
|
110
|
+
toolbar: true,
|
|
111
|
+
alerts: true,
|
|
112
|
+
selectionOverlay: true,
|
|
113
|
+
contextToolbars: true,
|
|
114
|
+
contextAnalytics: true,
|
|
115
|
+
pageChrome: true,
|
|
116
|
+
statusBar: true,
|
|
117
|
+
reviewRail: options.showReviewRail,
|
|
118
|
+
},
|
|
98
119
|
};
|
|
99
120
|
|
|
100
121
|
return {
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role → ordered primary-action id mapping for the top-toolbar's inline
|
|
3
|
+
* role-action region (spec §6.4).
|
|
4
|
+
*
|
|
5
|
+
* The registry in `chrome-registry.ts` knows which ids exist per role;
|
|
6
|
+
* this module decides the *rendering order* so the role region presents
|
|
7
|
+
* a tight, task-focused set instead of the preset-density order.
|
|
8
|
+
*
|
|
9
|
+
* Consumers of `TwRoleActionRegion` look up the array for the active
|
|
10
|
+
* role, iterate it in order, and let `scoped-chrome-policy` filter out
|
|
11
|
+
* anything currently invisible (for instance, review-role accept/reject
|
|
12
|
+
* buttons disappear when there are no pending revisions).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { EditorRole } from "../../api/public-types";
|
|
16
|
+
import type { ToolbarChromeItemId } from "../../ui/headless/chrome-registry";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Ordered role-action ids. Each array covers the *role-primary* actions
|
|
20
|
+
* only — the general left cluster (history, formatting, style selectors)
|
|
21
|
+
* and right cluster (tracked-changes, workspace mode, zoom, health,
|
|
22
|
+
* export) stay in the base `TwToolbar` layout regardless of role.
|
|
23
|
+
*/
|
|
24
|
+
export const ROLE_ACTION_SETS: Record<
|
|
25
|
+
EditorRole,
|
|
26
|
+
ReadonlyArray<ToolbarChromeItemId>
|
|
27
|
+
> = {
|
|
28
|
+
editor: [
|
|
29
|
+
// Posture menu replaces the flat "Mark section" button per spec §6.4.
|
|
30
|
+
"editor-scope-posture-menu",
|
|
31
|
+
// Insert menu (tables / images / page breaks / section breaks) — only
|
|
32
|
+
// meaningful for authoring, so it lives in the editor role's action
|
|
33
|
+
// region rather than the base toolbar.
|
|
34
|
+
"insert-actions",
|
|
35
|
+
"update-actions",
|
|
36
|
+
"list-continuation",
|
|
37
|
+
],
|
|
38
|
+
review: [
|
|
39
|
+
// Queue navigation + counts, collapsed from the old TwReviewQueueBar.
|
|
40
|
+
"review-queue-prev",
|
|
41
|
+
"review-queue-next",
|
|
42
|
+
"review-queue-counts",
|
|
43
|
+
"review-queue-active-label",
|
|
44
|
+
// Per-item accept/reject — the canonical review actions.
|
|
45
|
+
"review-accept",
|
|
46
|
+
"review-reject",
|
|
47
|
+
// Batch + markup-mode live in the overflow popover.
|
|
48
|
+
"review-accept-all",
|
|
49
|
+
"review-reject-all",
|
|
50
|
+
"review-markup-mode",
|
|
51
|
+
],
|
|
52
|
+
workflow: [
|
|
53
|
+
// Work-item navigation (distinct from review-queue nav).
|
|
54
|
+
"workflow-prev",
|
|
55
|
+
"workflow-next",
|
|
56
|
+
// Primary workflow actions.
|
|
57
|
+
"workflow-mark-complete",
|
|
58
|
+
"workflow-claim",
|
|
59
|
+
"workflow-skip",
|
|
60
|
+
"workflow-mark-blocked",
|
|
61
|
+
"workflow-jump-to-scope",
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Reverse lookup: role → entry order with registry details merged in.
|
|
67
|
+
* Consumers who need to iterate role actions with presets/runtimeBehavior
|
|
68
|
+
* import from here to avoid re-running `Array.find` per render.
|
|
69
|
+
*/
|
|
70
|
+
export function resolveRoleActionOrder(
|
|
71
|
+
role: EditorRole,
|
|
72
|
+
): ReadonlyArray<ToolbarChromeItemId> {
|
|
73
|
+
return ROLE_ACTION_SETS[role];
|
|
74
|
+
}
|