@beyondwork/docx-react-component 1.0.106 → 1.0.108
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 +19 -5
- package/src/api/geometry-overlay-rects.ts +5 -0
- package/src/api/package-version.ts +1 -1
- package/src/api/page-anchor-id.ts +5 -0
- package/src/api/public-types.ts +16 -9
- package/src/api/table-node-specs.ts +6 -0
- package/src/api/v3/_create.ts +2 -1
- package/src/api/v3/_page-anchor-id.ts +52 -0
- package/src/api/v3/_runtime-handle.ts +92 -1
- package/src/api/v3/ai/_audit-time.ts +5 -0
- package/src/api/v3/ai/_pe2-evidence.ts +38 -0
- package/src/api/v3/ai/attach.ts +7 -2
- package/src/api/v3/ai/replacement.ts +101 -18
- package/src/api/v3/ai/resolve.ts +2 -2
- package/src/api/v3/ai/review.ts +177 -3
- package/src/api/v3/index.ts +1 -0
- package/src/api/v3/runtime/collab.ts +462 -0
- package/src/api/v3/runtime/document.ts +503 -20
- package/src/api/v3/runtime/geometry.ts +97 -0
- package/src/api/v3/runtime/layout.ts +744 -0
- package/src/api/v3/runtime/perf-probe.ts +14 -0
- package/src/api/v3/runtime/viewport.ts +9 -8
- package/src/api/v3/ui/_types.ts +149 -55
- package/src/api/v3/ui/chrome-preset-model.ts +5 -5
- package/src/api/v3/ui/debug.ts +115 -2
- package/src/api/v3/ui/index.ts +13 -0
- package/src/api/v3/ui/overlays.ts +0 -8
- package/src/api/v3/ui/surface.ts +56 -0
- package/src/api/v3/ui/viewport.ts +22 -9
- package/src/core/commands/image-commands.ts +1 -0
- package/src/core/commands/index.ts +6 -0
- package/src/core/schema/text-schema.ts +43 -5
- package/src/core/selection/mapping.ts +8 -1
- package/src/core/selection/review-anchors.ts +5 -1
- package/src/core/state/text-transaction.ts +8 -2
- package/src/io/export/serialize-revisions.ts +149 -1
- package/src/io/normalize/normalize-text.ts +6 -0
- package/src/io/ooxml/parse-bookmark-references.ts +55 -0
- package/src/io/ooxml/parse-fields.ts +24 -2
- package/src/io/ooxml/parse-headers-footers.ts +38 -5
- package/src/io/ooxml/parse-main-document.ts +153 -9
- package/src/io/ooxml/parse-numbering.ts +20 -0
- package/src/io/ooxml/parse-revisions.ts +19 -8
- package/src/io/opc/package-reader.ts +98 -8
- package/src/model/anchor.ts +4 -3
- package/src/model/canonical-document.ts +220 -2
- package/src/model/canonical-hash.ts +221 -0
- package/src/model/canonical-layout-inputs.ts +245 -6
- package/src/model/layout/index.ts +1 -0
- package/src/model/layout/page-graph-types.ts +118 -1
- package/src/model/review/revision-types.ts +14 -3
- package/src/preservation/store.ts +20 -4
- package/src/review/README.md +1 -1
- package/src/review/store/revision-actions.ts +14 -2
- package/src/runtime/collab/event-types.ts +67 -1
- package/src/runtime/collab/runtime-collab-sync.ts +177 -5
- package/src/runtime/diagnostics/layout-guard-warning.ts +18 -0
- package/src/runtime/document-heading-outline.ts +147 -0
- package/src/runtime/document-navigation.ts +8 -243
- package/src/runtime/document-runtime.ts +240 -97
- package/src/runtime/edit-dispatch/dispatch-text-command.ts +11 -0
- package/src/runtime/formatting/layout-inputs.ts +38 -5
- package/src/runtime/formatting/numbering/geometry.ts +28 -2
- package/src/runtime/geometry/adjacent-geometry-intake.ts +835 -0
- package/src/runtime/geometry/caret-geometry.ts +5 -6
- package/src/runtime/geometry/geometry-facet.ts +60 -10
- package/src/runtime/geometry/geometry-index.ts +591 -20
- package/src/runtime/geometry/geometry-types.ts +59 -0
- package/src/runtime/geometry/hit-test.ts +11 -1
- package/src/runtime/geometry/overlay-rects.ts +5 -3
- package/src/runtime/geometry/project-anchors.ts +1 -1
- package/src/runtime/geometry/word-layout-v2-line-intake.ts +323 -0
- package/src/runtime/layout/index.ts +6 -0
- package/src/runtime/layout/layout-engine-instance.ts +6 -1
- package/src/runtime/layout/layout-engine-version.ts +181 -16
- package/src/runtime/layout/layout-facet-types.ts +6 -0
- package/src/runtime/layout/page-graph.ts +21 -4
- package/src/runtime/layout/paginated-layout-engine.ts +139 -15
- package/src/runtime/layout/project-block-fragments.ts +265 -7
- package/src/runtime/layout/public-facet.ts +78 -24
- package/src/runtime/layout/table-row-continuation-contract.ts +107 -0
- package/src/runtime/layout/table-row-split.ts +92 -35
- package/src/runtime/prerender/cache-envelope.ts +2 -2
- package/src/runtime/prerender/cache-key.ts +5 -4
- package/src/runtime/prerender/customxml-cache.ts +0 -1
- package/src/runtime/render/render-kernel.ts +1 -1
- package/src/runtime/revision-runtime.ts +112 -10
- package/src/runtime/scopes/_scope-dependencies.ts +1 -0
- package/src/runtime/scopes/action-validation.ts +22 -2
- package/src/runtime/scopes/capabilities.ts +316 -0
- package/src/runtime/scopes/compile-scope-bundle.ts +14 -0
- package/src/runtime/scopes/compiler-service.ts +108 -4
- package/src/runtime/scopes/content-control-evidence.ts +79 -0
- package/src/runtime/scopes/create-issue.ts +5 -5
- package/src/runtime/scopes/evidence.ts +91 -0
- package/src/runtime/scopes/formatting/apply.ts +2 -0
- package/src/runtime/scopes/geometry-evidence.ts +130 -0
- package/src/runtime/scopes/index.ts +54 -0
- package/src/runtime/scopes/issue-lifecycle.ts +224 -0
- package/src/runtime/scopes/layout-evidence.ts +374 -0
- package/src/runtime/scopes/multi-paragraph-refusal.ts +37 -0
- package/src/runtime/scopes/preservation-boundary.ts +7 -1
- package/src/runtime/scopes/replacement/apply.ts +97 -34
- package/src/runtime/scopes/scope-kinds/paragraph.ts +108 -12
- package/src/runtime/scopes/semantic-scope-types.ts +242 -3
- package/src/runtime/scopes/visualization.ts +28 -0
- package/src/runtime/surface-projection.ts +44 -5
- package/src/runtime/telemetry/perf-probe.ts +216 -0
- package/src/runtime/virtualized-rendering.ts +36 -1
- package/src/runtime/workflow/ai-issue-lifecycle.ts +253 -0
- package/src/runtime/workflow/coordinator.ts +39 -11
- package/src/runtime/workflow/derived-scope-resolver.ts +63 -9
- package/src/runtime/workflow/index.ts +3 -0
- package/src/runtime/workflow/overlay-lane-types.ts +58 -0
- package/src/runtime/workflow/overlay-lanes.ts +168 -10
- package/src/runtime/workflow/overlay-store.ts +2 -2
- package/src/runtime/workflow/redline-posture-calibration.ts +257 -0
- package/src/runtime/workflow/word-field-matrix-calibration.ts +231 -0
- package/src/session/_sync-legacy.ts +17 -27
- package/src/session/import/loader.ts +6 -4
- package/src/session/import/source-package-evidence.ts +186 -2
- package/src/session/index.ts +5 -6
- package/src/session/session.ts +30 -56
- package/src/session/types.ts +8 -13
- package/src/shell/session-bootstrap.ts +155 -81
- package/src/ui/WordReviewEditor.tsx +520 -12
- package/src/ui/editor-shell-view.tsx +14 -4
- package/src/ui/editor-surface-controller.tsx +5 -3
- package/src/ui/headless/selection-tool-resolver.ts +1 -2
- package/src/ui/presence-overlay-lane.ts +0 -1
- package/src/ui/ui-controller-factory.ts +7 -0
- package/src/ui-tailwind/chrome/build-context-menu-entries.ts +5 -1
- package/src/ui-tailwind/chrome/editor-action-registry.ts +105 -5
- package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +7 -0
- package/src/ui-tailwind/chrome/layer-debug-contracts.ts +208 -0
- package/src/ui-tailwind/chrome/resolve-target-kind.ts +13 -0
- package/src/ui-tailwind/chrome/tw-alert-banner.tsx +11 -3
- package/src/ui-tailwind/chrome/tw-command-palette.tsx +36 -6
- package/src/ui-tailwind/chrome/tw-context-menu.tsx +6 -1
- package/src/ui-tailwind/chrome/tw-display-mode-selector.tsx +42 -109
- package/src/ui-tailwind/chrome/tw-inline-find-bar.tsx +26 -6
- package/src/ui-tailwind/chrome/tw-navigation-command-bar.tsx +328 -0
- package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +8 -4
- package/src/ui-tailwind/chrome/tw-runtime-repl-dialog.tsx +129 -1
- package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +19 -5
- package/src/ui-tailwind/chrome/tw-selection-tool-structure.tsx +5 -1
- package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +28 -12
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +30 -3
- package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +116 -10
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +223 -94
- package/src/ui-tailwind/chrome-overlay/tw-presence-overlay-lane.tsx +157 -0
- package/src/ui-tailwind/chrome-overlay/tw-review-overlay-lane-markers.tsx +259 -0
- package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +5 -2
- package/src/ui-tailwind/chrome-overlay/tw-substrate-overlay-lanes.tsx +314 -0
- package/src/ui-tailwind/debug/README.md +4 -1
- package/src/ui-tailwind/debug/layer11-consumer-readiness.ts +272 -0
- package/src/ui-tailwind/debug/layer11-word-field-matrix-evidence.ts +160 -0
- package/src/ui-tailwind/editor-surface/perf-probe.ts +14 -215
- package/src/ui-tailwind/editor-surface/pm-decorations.ts +42 -0
- package/src/ui-tailwind/editor-surface/pm-position-map.ts +38 -2
- package/src/ui-tailwind/editor-surface/pm-schema.ts +14 -4
- package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +34 -5
- package/src/ui-tailwind/editor-surface/runtime-decoration-plugin.ts +9 -19
- package/src/ui-tailwind/editor-surface/surface-build-keys.ts +2 -2
- package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +145 -0
- package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +16 -11
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +8 -10
- package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +3 -0
- package/src/ui-tailwind/page-stack/tw-page-chrome-entry.tsx +4 -2
- package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +60 -20
- package/src/ui-tailwind/page-stack/tw-region-block-renderer.tsx +16 -11
- package/src/ui-tailwind/review/tw-health-panel.tsx +36 -17
- package/src/ui-tailwind/review/tw-review-rail.tsx +7 -4
- package/src/ui-tailwind/review-workspace/diagnostics-visibility.ts +44 -0
- package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +11 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +16 -1
- package/src/ui-tailwind/review-workspace/types.ts +26 -12
- package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +40 -11
- package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +2 -1
- package/src/ui-tailwind/review-workspace/use-page-markers.ts +15 -26
- package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +35 -18
- package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +41 -32
- package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +2 -1
- package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +2 -1
- package/src/ui-tailwind/status/tw-status-bar.tsx +6 -5
- package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +52 -80
- package/src/ui-tailwind/toolbar/tw-shell-header.tsx +12 -48
- package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +9 -4
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +328 -361
- package/src/ui-tailwind/tw-review-workspace.tsx +152 -286
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
* Band placement
|
|
13
13
|
* --------------
|
|
14
14
|
* For each measured page rect the layer emits one
|
|
15
|
-
* `<div data-page-chrome-frame data-page-index={i}>`
|
|
16
|
-
* rect's top/height.
|
|
15
|
+
* `<div data-page-chrome-frame data-page-anchor data-page-index={i}>`
|
|
16
|
+
* positioned at the rect's top/height. Inside the frame, four children conditionally
|
|
17
17
|
* mount:
|
|
18
18
|
*
|
|
19
19
|
* 1. `<TwPageHeaderBand>` — when the page's `regions.header` + the
|
|
@@ -73,13 +73,17 @@ import type {
|
|
|
73
73
|
GeometryFacet,
|
|
74
74
|
WordReviewEditorLayoutFacet,
|
|
75
75
|
} from "../../api/public-types.ts";
|
|
76
|
+
import { buildPageAnchorSelector } from "../../api/v3/_page-anchor-id.ts";
|
|
76
77
|
import {
|
|
77
78
|
measureWidgetsViaOffsetChain,
|
|
78
79
|
measureWidgetsViaBoundingRect,
|
|
80
|
+
resolvePageOverlayRectsFromUiApi,
|
|
79
81
|
resolvePageOverlayRectsFromGeometry,
|
|
80
82
|
resolvePageOverlayRects,
|
|
83
|
+
reconcilePageStackRectsWithFlow,
|
|
81
84
|
type PageOverlayRect,
|
|
82
85
|
} from "../chrome-overlay/tw-page-stack-overlay-layer.tsx";
|
|
86
|
+
import { useUiApi } from "../ui-api-context.tsx";
|
|
83
87
|
import { TwEndnoteArea } from "./tw-endnote-area.tsx";
|
|
84
88
|
import { TwPageChromeEntry } from "./tw-page-chrome-entry.tsx";
|
|
85
89
|
import type { TwActiveBandRibbonProps } from "./tw-active-band-ribbon.tsx";
|
|
@@ -101,7 +105,7 @@ export interface TwPageStackChromeLayerProps {
|
|
|
101
105
|
facet: WordReviewEditorLayoutFacet;
|
|
102
106
|
/** Geometry facet — warm-path source of per-page frame rects. */
|
|
103
107
|
geometryFacet?: GeometryFacet;
|
|
104
|
-
/** Scroll root
|
|
108
|
+
/** Scroll root used only by the page-rect cold fallback before geometry is warm. */
|
|
105
109
|
scrollRoot: HTMLElement | null;
|
|
106
110
|
/**
|
|
107
111
|
* Render-frame revision tick incremented on `layout_recomputed`,
|
|
@@ -137,7 +141,7 @@ export interface TwPageStackChromeLayerProps {
|
|
|
137
141
|
* pages whose sequential index falls inside this range (with overscan
|
|
138
142
|
* already applied by the caller). Pages outside the range render a
|
|
139
143
|
* lightweight wrapper `div` carrying the `data-page-chrome-frame` +
|
|
140
|
-
* `data-page-
|
|
144
|
+
* shared `data-page-anchor` attributes — every position read (portal-slot
|
|
141
145
|
* query, per-page measurement) continues to resolve deterministically,
|
|
142
146
|
* but the four child React subtrees (Header/Footer/Footnote bands)
|
|
143
147
|
* never mount, eliminating the measured 412 ms Layout + 229 ms
|
|
@@ -183,9 +187,29 @@ const TwPageStackChromeLayerInner: React.FC<TwPageStackChromeLayerProps> = ({
|
|
|
183
187
|
mediaPreviews,
|
|
184
188
|
activeBandRibbonProps,
|
|
185
189
|
}) => {
|
|
190
|
+
const ui = useUiApi();
|
|
191
|
+
const resolveUiPageRects = React.useCallback(
|
|
192
|
+
(pageCount: number): readonly PageOverlayRect[] | null => {
|
|
193
|
+
if (!ui) return null;
|
|
194
|
+
const pageIds = Array.from(
|
|
195
|
+
{ length: pageCount },
|
|
196
|
+
(_, pageIndex) => facet.getPage(pageIndex)?.pageId ?? `page-${pageIndex}`,
|
|
197
|
+
);
|
|
198
|
+
return resolvePageOverlayRectsFromUiApi(
|
|
199
|
+
ui,
|
|
200
|
+
pageCount,
|
|
201
|
+
visiblePageIndexRange,
|
|
202
|
+
pageIds,
|
|
203
|
+
);
|
|
204
|
+
},
|
|
205
|
+
[facet, ui, visiblePageIndexRange],
|
|
206
|
+
);
|
|
207
|
+
|
|
186
208
|
const [rects, setRects] = React.useState<readonly PageOverlayRect[]>(() => {
|
|
187
|
-
if (!geometryFacet) return [];
|
|
188
209
|
const pageCount = facet.getPageCount();
|
|
210
|
+
const uiRects = resolveUiPageRects(pageCount);
|
|
211
|
+
if (uiRects !== null) return uiRects;
|
|
212
|
+
if (!geometryFacet) return [];
|
|
189
213
|
const warm = resolvePageOverlayRectsFromGeometry(
|
|
190
214
|
geometryFacet,
|
|
191
215
|
pageCount,
|
|
@@ -206,6 +230,20 @@ const TwPageStackChromeLayerInner: React.FC<TwPageStackChromeLayerProps> = ({
|
|
|
206
230
|
|
|
207
231
|
const refreshRectsNow = React.useCallback(() => {
|
|
208
232
|
const pageCount = facet.getPageCount();
|
|
233
|
+
const reconcileRects = (baseRects: readonly PageOverlayRect[]) =>
|
|
234
|
+
reconcilePageStackRectsWithFlow({
|
|
235
|
+
baseRects,
|
|
236
|
+
pageCount,
|
|
237
|
+
scrollRoot,
|
|
238
|
+
originElement: overlayRootRef.current,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const uiRects = resolveUiPageRects(pageCount);
|
|
242
|
+
if (uiRects !== null) {
|
|
243
|
+
setRects(reconcileRects(uiRects));
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
209
247
|
if (geometryFacet) {
|
|
210
248
|
const geometryRects = resolvePageOverlayRectsFromGeometry(
|
|
211
249
|
geometryFacet,
|
|
@@ -213,7 +251,7 @@ const TwPageStackChromeLayerInner: React.FC<TwPageStackChromeLayerProps> = ({
|
|
|
213
251
|
visiblePageIndexRange,
|
|
214
252
|
);
|
|
215
253
|
if (geometryRects !== null) {
|
|
216
|
-
setRects(geometryRects);
|
|
254
|
+
setRects(reconcileRects(geometryRects));
|
|
217
255
|
return;
|
|
218
256
|
}
|
|
219
257
|
}
|
|
@@ -240,29 +278,31 @@ const TwPageStackChromeLayerInner: React.FC<TwPageStackChromeLayerProps> = ({
|
|
|
240
278
|
: originRect.height > 0
|
|
241
279
|
? originRect.height
|
|
242
280
|
: scrollRoot.clientHeight;
|
|
281
|
+
const domRects = resolvePageOverlayRects({
|
|
282
|
+
widgets,
|
|
283
|
+
pageCount,
|
|
284
|
+
scrollHeight,
|
|
285
|
+
visiblePageIndexRange,
|
|
286
|
+
});
|
|
243
287
|
setRects(
|
|
244
|
-
|
|
245
|
-
widgets,
|
|
246
|
-
pageCount,
|
|
247
|
-
scrollHeight,
|
|
248
|
-
visiblePageIndexRange,
|
|
249
|
-
}),
|
|
288
|
+
reconcileRects(domRects),
|
|
250
289
|
);
|
|
251
290
|
} else {
|
|
252
291
|
const widgets = measureWidgetsViaOffsetChain(scrollRoot, {
|
|
253
292
|
pageCount,
|
|
254
293
|
visiblePageIndexRange,
|
|
255
294
|
});
|
|
295
|
+
const domRects = resolvePageOverlayRects({
|
|
296
|
+
widgets,
|
|
297
|
+
pageCount,
|
|
298
|
+
scrollHeight: scrollRoot.clientHeight,
|
|
299
|
+
visiblePageIndexRange,
|
|
300
|
+
});
|
|
256
301
|
setRects(
|
|
257
|
-
|
|
258
|
-
widgets,
|
|
259
|
-
pageCount,
|
|
260
|
-
scrollHeight: scrollRoot.clientHeight,
|
|
261
|
-
visiblePageIndexRange,
|
|
262
|
-
}),
|
|
302
|
+
reconcileRects(domRects),
|
|
263
303
|
);
|
|
264
304
|
}
|
|
265
|
-
}, [facet, geometryFacet, scrollRoot, visiblePageIndexRange]);
|
|
305
|
+
}, [facet, geometryFacet, resolveUiPageRects, scrollRoot, visiblePageIndexRange]);
|
|
266
306
|
|
|
267
307
|
const refreshRects = React.useCallback(() => {
|
|
268
308
|
if (!scrollRoot) {
|
|
@@ -384,7 +424,7 @@ const TwPageStackChromeLayerInner: React.FC<TwPageStackChromeLayerProps> = ({
|
|
|
384
424
|
const pageScopedSelector =
|
|
385
425
|
activeStoryPageIndex == null
|
|
386
426
|
? null
|
|
387
|
-
:
|
|
427
|
+
: `${buildPageAnchorSelector(activeStoryPageIndex)} [data-pm-portal-slot]`;
|
|
388
428
|
const activeSlot =
|
|
389
429
|
(pageScopedSelector
|
|
390
430
|
? overlay?.querySelector<HTMLElement>(pageScopedSelector)
|
|
@@ -7,12 +7,15 @@ import type {
|
|
|
7
7
|
import type { MediaPreviewDescriptor } from "../editor-surface/pm-state-from-snapshot.ts";
|
|
8
8
|
import {
|
|
9
9
|
buildMarkerStyle,
|
|
10
|
+
buildParagraphContentStyle,
|
|
10
11
|
buildParagraphStyle,
|
|
11
12
|
buildSegmentStyle,
|
|
12
|
-
|
|
13
|
+
buildTabStyle,
|
|
14
|
+
computeTabRenderInfoBySegment,
|
|
13
15
|
hasStyleEntries,
|
|
14
16
|
headingClassList,
|
|
15
17
|
resolveHeadingLevel,
|
|
18
|
+
type TabRenderInfo,
|
|
16
19
|
} from "../editor-surface/tw-page-block-view.helpers.ts";
|
|
17
20
|
import { shouldRenderAbsoluteFloatingImageInPageOverlay } from "./floating-image-overlay-model.ts";
|
|
18
21
|
|
|
@@ -61,7 +64,7 @@ function renderSegment(
|
|
|
61
64
|
seg: SurfaceInlineSegment,
|
|
62
65
|
mediaPreviews: Record<string, MediaPreviewDescriptor>,
|
|
63
66
|
fallbackDisplay: RegionImageFallbackDisplay,
|
|
64
|
-
|
|
67
|
+
tabInfoBySegment: Map<string, TabRenderInfo>,
|
|
65
68
|
): React.ReactNode {
|
|
66
69
|
switch (seg.kind) {
|
|
67
70
|
case "text": {
|
|
@@ -77,16 +80,13 @@ function renderSegment(
|
|
|
77
80
|
);
|
|
78
81
|
}
|
|
79
82
|
case "tab": {
|
|
80
|
-
const
|
|
81
|
-
const tabStyle: React.CSSProperties =
|
|
82
|
-
typeof widthPt === "number"
|
|
83
|
-
? { display: "inline-block", width: `${widthPt}pt`, minWidth: "8px" }
|
|
84
|
-
: { display: "inline-block", width: "32px", minWidth: "8px" };
|
|
83
|
+
const tabInfo = tabInfoBySegment.get(seg.segmentId);
|
|
85
84
|
return (
|
|
86
85
|
<span
|
|
87
86
|
key={seg.segmentId}
|
|
88
87
|
data-node-type="tab"
|
|
89
|
-
style={
|
|
88
|
+
style={buildTabStyle(tabInfo)}
|
|
89
|
+
title={tabInfo?.align ? `Tab stop · ${tabInfo.align}` : "Tab stop"}
|
|
90
90
|
>
|
|
91
91
|
{"\u00A0"}
|
|
92
92
|
</span>
|
|
@@ -248,7 +248,8 @@ function RegionParagraph({
|
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
const pStyle = buildParagraphStyle(block);
|
|
251
|
-
const
|
|
251
|
+
const tabInfoBySegment = computeTabRenderInfoBySegment(block);
|
|
252
|
+
const contentStyle = buildParagraphContentStyle(block);
|
|
252
253
|
|
|
253
254
|
// Numbering prefix span — matches tw-page-block-view so region content that
|
|
254
255
|
// happens to carry numbering (e.g. footnote bodies authored as lists) shows
|
|
@@ -312,8 +313,12 @@ function RegionParagraph({
|
|
|
312
313
|
return (
|
|
313
314
|
<div {...attrs}>
|
|
314
315
|
{prefixSpan}
|
|
315
|
-
<span
|
|
316
|
-
|
|
316
|
+
<span
|
|
317
|
+
className="pm-paragraph-content"
|
|
318
|
+
data-tab-layout={contentStyle ? "right" : undefined}
|
|
319
|
+
style={contentStyle}
|
|
320
|
+
>
|
|
321
|
+
{block.segments.map((seg) => renderSegment(seg, mediaPreviews, fallbackDisplay, tabInfoBySegment))}
|
|
317
322
|
</span>
|
|
318
323
|
</div>
|
|
319
324
|
);
|
|
@@ -2,17 +2,26 @@ import React from "react";
|
|
|
2
2
|
import { AlertTriangle, Info, Shield, ShieldAlert, ShieldCheck } from "lucide-react";
|
|
3
3
|
|
|
4
4
|
import type {
|
|
5
|
-
CompatibilityFeatureEntry,
|
|
6
5
|
CompatibilityPanelSnapshot,
|
|
7
6
|
EditorWarning,
|
|
8
7
|
WorkflowBlockedCommandReason,
|
|
9
8
|
} from "../../api/public-types";
|
|
10
9
|
import { TwEmptyState } from "../chrome/tw-empty-state";
|
|
10
|
+
import {
|
|
11
|
+
filterProductCompatibility,
|
|
12
|
+
filterProductWarnings,
|
|
13
|
+
} from "../review-workspace/diagnostics-visibility.ts";
|
|
11
14
|
|
|
12
15
|
export interface TwHealthPanelProps {
|
|
13
16
|
compatibility: CompatibilityPanelSnapshot;
|
|
14
17
|
warnings: EditorWarning[];
|
|
15
18
|
blockedReasons?: WorkflowBlockedCommandReason[];
|
|
19
|
+
/**
|
|
20
|
+
* Preserve-only / opaque diagnostics are debug/operator-only. Default
|
|
21
|
+
* product chrome shows export blockers and actionable warnings, not
|
|
22
|
+
* preservation internals.
|
|
23
|
+
*/
|
|
24
|
+
showPreservationDiagnostics?: boolean;
|
|
16
25
|
}
|
|
17
26
|
|
|
18
27
|
type SeverityKey = "error" | "warning" | "info";
|
|
@@ -91,7 +100,16 @@ function renderGroup(
|
|
|
91
100
|
}
|
|
92
101
|
|
|
93
102
|
export function TwHealthPanel(props: TwHealthPanelProps) {
|
|
94
|
-
const {
|
|
103
|
+
const {
|
|
104
|
+
blockedReasons = [],
|
|
105
|
+
showPreservationDiagnostics = false,
|
|
106
|
+
} = props;
|
|
107
|
+
const compatibility = showPreservationDiagnostics
|
|
108
|
+
? props.compatibility
|
|
109
|
+
: filterProductCompatibility(props.compatibility);
|
|
110
|
+
const warnings = showPreservationDiagnostics
|
|
111
|
+
? props.warnings
|
|
112
|
+
: filterProductWarnings(props.warnings);
|
|
95
113
|
|
|
96
114
|
// Blocked export group: unsupported-fatal entries
|
|
97
115
|
const blockedExportItems: IssueRow[] = compatibility.featureEntries
|
|
@@ -111,20 +129,22 @@ export function TwHealthPanel(props: TwHealthPanelProps) {
|
|
|
111
129
|
|
|
112
130
|
// Warning group: preserve-only entries + workflow blocked reasons + "warning"-severity EditorWarnings
|
|
113
131
|
const warningItems: IssueRow[] = [
|
|
114
|
-
...
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
132
|
+
...(showPreservationDiagnostics
|
|
133
|
+
? compatibility.featureEntries
|
|
134
|
+
.filter((e) => e.featureClass === "preserve-only")
|
|
135
|
+
.map((e) => ({
|
|
136
|
+
id: e.featureEntryId,
|
|
137
|
+
message: e.message,
|
|
138
|
+
detail: e.featureKey,
|
|
139
|
+
badge: "preserve-only",
|
|
140
|
+
icon: (
|
|
141
|
+
<Shield
|
|
142
|
+
className="h-4 w-4 shrink-0 mt-0.5"
|
|
143
|
+
style={{ color: "var(--color-semantic-warning)" }}
|
|
144
|
+
/>
|
|
145
|
+
),
|
|
146
|
+
}))
|
|
147
|
+
: []),
|
|
128
148
|
...blockedReasons.map((r, index) => ({
|
|
129
149
|
id: `blocked-reason-${index}`,
|
|
130
150
|
message: r.message,
|
|
@@ -186,4 +206,3 @@ export function TwHealthPanel(props: TwHealthPanelProps) {
|
|
|
186
206
|
</div>
|
|
187
207
|
);
|
|
188
208
|
}
|
|
189
|
-
|
|
@@ -31,8 +31,8 @@ import {
|
|
|
31
31
|
* to a signal-only chip. When `showHealthTab` is absent the rail retains the
|
|
32
32
|
* shipped three-tab layout for back-compat.
|
|
33
33
|
*
|
|
34
|
-
* The Workflow tab reads `scopeRailSegments` from the
|
|
35
|
-
*
|
|
34
|
+
* The Workflow tab reads `scopeRailSegments` from the mounted UI API seam by
|
|
35
|
+
* default. For hosts that need to override the Workflow card
|
|
36
36
|
* content (CLM, BW, agent integrations that derive their own model), pass
|
|
37
37
|
* `workflowTab` as a ReactNode and it will replace the built-in projection.
|
|
38
38
|
* Either way policy stays host-side; the runtime rail remains projection-only.
|
|
@@ -60,8 +60,8 @@ export interface TwReviewRailProps {
|
|
|
60
60
|
activeCommentId?: string;
|
|
61
61
|
activeRevisionId?: string;
|
|
62
62
|
/**
|
|
63
|
-
* Scope rail segments used by the Workflow tab.
|
|
64
|
-
*
|
|
63
|
+
* Scope rail segments used by the Workflow tab. Mounted consumers pass
|
|
64
|
+
* `api.ui.scope.rail().segments` through the workspace. When omitted the
|
|
65
65
|
* Workflow tab renders an empty state (unless `workflowTab` is set).
|
|
66
66
|
*/
|
|
67
67
|
scopeRailSegments?: readonly ScopeRailSegment[];
|
|
@@ -103,6 +103,8 @@ export interface TwReviewRailProps {
|
|
|
103
103
|
healthSeverity?: "info" | "warning" | "blocked";
|
|
104
104
|
/** Forwarded to the Health tab's `TwHealthPanel` to surface blocked reasons. */
|
|
105
105
|
workflowBlockedReasons?: WorkflowBlockedCommandReason[];
|
|
106
|
+
/** Debug/operator-only opt-in for preserve-only / opaque diagnostics. */
|
|
107
|
+
showPreservationDiagnostics?: boolean;
|
|
106
108
|
|
|
107
109
|
onActiveTabChange: (tab: ReviewRailTab) => void;
|
|
108
110
|
onOpenComment?: (thread: CommentSidebarThreadSnapshot) => void;
|
|
@@ -299,6 +301,7 @@ export function TwReviewRail(props: TwReviewRailProps) {
|
|
|
299
301
|
<TwHealthPanel
|
|
300
302
|
compatibility={props.compatibility}
|
|
301
303
|
warnings={props.warnings}
|
|
304
|
+
showPreservationDiagnostics={props.showPreservationDiagnostics}
|
|
302
305
|
{...(props.workflowBlockedReasons
|
|
303
306
|
? { blockedReasons: props.workflowBlockedReasons }
|
|
304
307
|
: {})}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CompatibilityFeatureEntry,
|
|
3
|
+
CompatibilityPanelSnapshot,
|
|
4
|
+
EditorWarning,
|
|
5
|
+
} from "../../api/public-types.ts";
|
|
6
|
+
|
|
7
|
+
const DEBUG_ONLY_WARNING_CODES = new Set<EditorWarning["code"]>([
|
|
8
|
+
"unsupported_ooxml_preserved",
|
|
9
|
+
"unsupported_ooxml_locked",
|
|
10
|
+
]);
|
|
11
|
+
|
|
12
|
+
export function isDebugOnlyCompatibilityFeature(
|
|
13
|
+
entry: CompatibilityFeatureEntry,
|
|
14
|
+
): boolean {
|
|
15
|
+
return entry.featureClass === "preserve-only";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function isDebugOnlyWarning(warning: EditorWarning): boolean {
|
|
19
|
+
return (
|
|
20
|
+
warning.source === "preservation" ||
|
|
21
|
+
DEBUG_ONLY_WARNING_CODES.has(warning.code)
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function filterProductWarnings(
|
|
26
|
+
warnings: readonly EditorWarning[] | undefined,
|
|
27
|
+
): EditorWarning[] {
|
|
28
|
+
return (warnings ?? []).filter((warning) => !isDebugOnlyWarning(warning));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function filterProductCompatibility(
|
|
32
|
+
compatibility: CompatibilityPanelSnapshot,
|
|
33
|
+
): CompatibilityPanelSnapshot {
|
|
34
|
+
const featureEntries = compatibility.featureEntries.filter(
|
|
35
|
+
(entry) => !isDebugOnlyCompatibilityFeature(entry),
|
|
36
|
+
);
|
|
37
|
+
if (featureEntries.length === compatibility.featureEntries.length) {
|
|
38
|
+
return compatibility;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
...compatibility,
|
|
42
|
+
featureEntries,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -12,6 +12,9 @@ export const FRAME_PX_PER_TWIP_AT_96DPI = 96 / 1440;
|
|
|
12
12
|
/** Floor on header/footer band heights so empty bands stay clickable. */
|
|
13
13
|
export const MIN_BAND_HEIGHT_PX = 20;
|
|
14
14
|
|
|
15
|
+
/** Word's default Letter body width: 8.5in page minus 1in margins at 96dpi. */
|
|
16
|
+
export const DEFAULT_CANVAS_BODY_WIDTH_PX = 624;
|
|
17
|
+
|
|
15
18
|
const FIT_WIDTH_CHROME_RESERVATION_PX = 96;
|
|
16
19
|
const FIT_HEIGHT_CHROME_RESERVATION_PX = 180;
|
|
17
20
|
const MIN_FIT_ZOOM = 0.5;
|
|
@@ -22,6 +25,8 @@ export interface PageShellMetrics {
|
|
|
22
25
|
frameWidthPx?: number;
|
|
23
26
|
/** P2.a — page frame CSS px height = `pageHeight × FRAME_PX_PER_TWIP_AT_96DPI`. */
|
|
24
27
|
frameHeightPx?: number;
|
|
28
|
+
/** Word body column width after subtracting left/right section margins. */
|
|
29
|
+
contentWidthPx?: number;
|
|
25
30
|
contentInsetStyle: CSSProperties;
|
|
26
31
|
pageFrameStyle: CSSProperties;
|
|
27
32
|
}
|
|
@@ -35,6 +40,7 @@ export function buildPageShellMetrics(
|
|
|
35
40
|
pageFrameStyle: {},
|
|
36
41
|
frameWidthPx: 0,
|
|
37
42
|
frameHeightPx: 0,
|
|
43
|
+
contentWidthPx: 0,
|
|
38
44
|
};
|
|
39
45
|
}
|
|
40
46
|
|
|
@@ -43,6 +49,10 @@ export function buildPageShellMetrics(
|
|
|
43
49
|
const frameHeightPx = Math.round(pageLayout.pageHeight * pxPerTwip);
|
|
44
50
|
const horizontalInsetPx = Math.round(pageLayout.marginLeft * pxPerTwip);
|
|
45
51
|
const horizontalInsetRightPx = Math.round(pageLayout.marginRight * pxPerTwip);
|
|
52
|
+
const contentWidthPx = Math.max(
|
|
53
|
+
0,
|
|
54
|
+
frameWidthPx - horizontalInsetPx - horizontalInsetRightPx,
|
|
55
|
+
);
|
|
46
56
|
|
|
47
57
|
return {
|
|
48
58
|
contentInsetStyle: {
|
|
@@ -58,6 +68,7 @@ export function buildPageShellMetrics(
|
|
|
58
68
|
},
|
|
59
69
|
frameWidthPx,
|
|
60
70
|
frameHeightPx,
|
|
71
|
+
contentWidthPx,
|
|
61
72
|
};
|
|
62
73
|
}
|
|
63
74
|
|
|
@@ -7,6 +7,8 @@ import { TwReviewRail, type TwReviewRailProps } from "../review/tw-review-rail";
|
|
|
7
7
|
*
|
|
8
8
|
* - `docked` — render the rail inline as a sibling of the document
|
|
9
9
|
* column (standard desktop width).
|
|
10
|
+
* - `overlay` — render the rail over the canvas, so opening the rail never
|
|
11
|
+
* shrinks or left-shifts the continuous editor column.
|
|
10
12
|
* - `drawer` — render the rail behind a dismiss-overlay button so the
|
|
11
13
|
* narrow-viewport scrim can close it.
|
|
12
14
|
* - `hidden` — render nothing (the parent already decided the rail
|
|
@@ -16,7 +18,7 @@ import { TwReviewRail, type TwReviewRailProps } from "../review/tw-review-rail";
|
|
|
16
18
|
* `rail`; the wrapper owns the `variant` slot so the parent doesn't have
|
|
17
19
|
* to branch twice on posture.
|
|
18
20
|
*/
|
|
19
|
-
export type TwReviewWorkspaceRailMode = "docked" | "drawer" | "hidden";
|
|
21
|
+
export type TwReviewWorkspaceRailMode = "docked" | "overlay" | "drawer" | "hidden";
|
|
20
22
|
|
|
21
23
|
export interface TwReviewWorkspaceRailProps {
|
|
22
24
|
mode: TwReviewWorkspaceRailMode;
|
|
@@ -40,6 +42,19 @@ export function TwReviewWorkspaceRail({
|
|
|
40
42
|
return <TwReviewRail {...rail} />;
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
if (mode === "overlay") {
|
|
46
|
+
return (
|
|
47
|
+
<div
|
|
48
|
+
className="pointer-events-none absolute inset-y-0 right-0 z-30 flex justify-end"
|
|
49
|
+
data-testid="review-rail-overlay"
|
|
50
|
+
>
|
|
51
|
+
<div className="pointer-events-auto h-full">
|
|
52
|
+
<TwReviewRail variant="drawer" {...rail} />
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
43
58
|
return (
|
|
44
59
|
<div
|
|
45
60
|
className="pointer-events-none absolute inset-0 z-30 flex justify-end"
|
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
EditorViewStateSnapshot,
|
|
10
10
|
FormattingStateSnapshot,
|
|
11
11
|
FormattingAlignment,
|
|
12
|
+
GeometryFacet,
|
|
12
13
|
HeaderFooterLinkPatch,
|
|
13
14
|
InteractionGuardSnapshot,
|
|
14
15
|
InsertImageOptions,
|
|
@@ -17,11 +18,14 @@ import type {
|
|
|
17
18
|
ReviewQueueSnapshot,
|
|
18
19
|
SectionPageNumberingPatch,
|
|
19
20
|
SectionBreakType,
|
|
21
|
+
CollabSession,
|
|
20
22
|
StyleCatalogSnapshot,
|
|
21
23
|
TrackedChangeEntrySnapshot,
|
|
24
|
+
WordReviewEditorLayoutFacet,
|
|
22
25
|
WordReviewEditorChromeOptions,
|
|
23
26
|
WordReviewEditorChromePreset,
|
|
24
27
|
WordReviewEditorChromeVisibility,
|
|
28
|
+
WorkflowFacet,
|
|
25
29
|
WorkflowScopeSnapshot,
|
|
26
30
|
WorkspaceMode,
|
|
27
31
|
ZoomLevel,
|
|
@@ -31,6 +35,10 @@ import type {
|
|
|
31
35
|
ActiveSelectionToolModel,
|
|
32
36
|
SelectionToolAnchor,
|
|
33
37
|
} from "../../ui/headless/selection-tool-types";
|
|
38
|
+
import type {
|
|
39
|
+
UiObjectDragSession,
|
|
40
|
+
UiObjectDragStartInput,
|
|
41
|
+
} from "../../api/v3/ui/_types.ts";
|
|
34
42
|
import type { MarkupDisplay } from "../../ui/headless/comment-decoration-model";
|
|
35
43
|
import type { EditorCommandBag } from "../../ui/editor-command-bag.ts";
|
|
36
44
|
import type { EditorActionHostCallbacks } from "../chrome/editor-action-registry";
|
|
@@ -54,7 +62,7 @@ export interface TwReviewWorkspaceProps {
|
|
|
54
62
|
* supplied, the ChromeOverlay plane (scope rail, workflow dock, etc.)
|
|
55
63
|
* renders over the document column.
|
|
56
64
|
*/
|
|
57
|
-
layoutFacet?:
|
|
65
|
+
layoutFacet?: WordReviewEditorLayoutFacet;
|
|
58
66
|
/**
|
|
59
67
|
* Layer-05 geometry facet (`runtime.geometry`). Required by chrome
|
|
60
68
|
* overlay layers (scope rail, object selection, table grip, page-break
|
|
@@ -63,7 +71,7 @@ export interface TwReviewWorkspaceProps {
|
|
|
63
71
|
* through the now-`@deprecated` `layoutFacet.getRenderFrame` /
|
|
64
72
|
* `.getRenderZoom` methods.
|
|
65
73
|
*/
|
|
66
|
-
geometryFacet?:
|
|
74
|
+
geometryFacet?: GeometryFacet;
|
|
67
75
|
/**
|
|
68
76
|
* Layer-06 workflow facet — canonical source of scope rail segments
|
|
69
77
|
* and scope card models (`runtime.workflow`). Required by the scope
|
|
@@ -71,19 +79,16 @@ export interface TwReviewWorkspaceProps {
|
|
|
71
79
|
* removed those methods from `WordReviewEditorLayoutFacet`. When
|
|
72
80
|
* absent, those layers render nothing.
|
|
73
81
|
*/
|
|
74
|
-
workflowFacet?:
|
|
82
|
+
workflowFacet?: WorkflowFacet;
|
|
75
83
|
/**
|
|
76
84
|
* Optional shell header override. Mounted above the formatting toolbar.
|
|
77
85
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* workspace mounts a default `<TwShellHeader />` with the 4-mode
|
|
81
|
-
* switcher (edit / review / workflow / more) so mode authority is
|
|
82
|
-
* always visible and centralized.
|
|
86
|
+
* The default product workspace no longer mounts a top mode-strip shell.
|
|
87
|
+
* Edit / Review / Workflow mode authority lives in the main toolbar.
|
|
83
88
|
*
|
|
84
|
-
* Hosts that need a custom brand,
|
|
89
|
+
* Hosts that need a custom brand, actions, or primary CTA pass a
|
|
85
90
|
* pre-assembled `<TwShellHeader />` here; the custom node replaces the
|
|
86
|
-
* default entirely.
|
|
91
|
+
* empty default shell entirely.
|
|
87
92
|
*/
|
|
88
93
|
shellHeader?: ReactNode;
|
|
89
94
|
/**
|
|
@@ -121,7 +126,7 @@ export interface TwReviewWorkspaceProps {
|
|
|
121
126
|
/**
|
|
122
127
|
* Optional host-provided Workflow-tab override for the review rail.
|
|
123
128
|
* When unset the rail renders the built-in `TwWorkflowTab` sourced from
|
|
124
|
-
* `
|
|
129
|
+
* `api.ui.scope.rail()` on mounted paths.
|
|
125
130
|
*/
|
|
126
131
|
reviewRailWorkflowTab?: ReactNode;
|
|
127
132
|
reviewRailWorkflowCount?: number;
|
|
@@ -136,6 +141,13 @@ export interface TwReviewWorkspaceProps {
|
|
|
136
141
|
searchLabel?: string;
|
|
137
142
|
helpLabel?: string;
|
|
138
143
|
};
|
|
144
|
+
/**
|
|
145
|
+
* Internal debug/operator switch for opaque/preserve-only diagnostics.
|
|
146
|
+
* Default product chrome must leave this unset so the shipping component
|
|
147
|
+
* never exposes preservation internals, health badges, or debug detail by
|
|
148
|
+
* default.
|
|
149
|
+
*/
|
|
150
|
+
showDebugDiagnostics?: boolean;
|
|
139
151
|
/** Opens the built-in inline find surface from More/Search and command palette. */
|
|
140
152
|
onOpenInlineFind?: () => void;
|
|
141
153
|
document: ReactNode;
|
|
@@ -157,7 +169,7 @@ export interface TwReviewWorkspaceProps {
|
|
|
157
169
|
chromeOptions?: Partial<WordReviewEditorChromeOptions>;
|
|
158
170
|
density?: "compact" | "standard" | "comfortable";
|
|
159
171
|
/** P9g — live collab session for the `"collab"` chrome preset's top nav. */
|
|
160
|
-
collabSession?:
|
|
172
|
+
collabSession?: CollabSession;
|
|
161
173
|
collabTransportStatus?: import("../../api/awareness-identity-types.ts").TransportStatus;
|
|
162
174
|
collabActorId?: string;
|
|
163
175
|
collabSendBaseline?: {
|
|
@@ -179,6 +191,8 @@ export interface TwReviewWorkspaceProps {
|
|
|
179
191
|
}) => void;
|
|
180
192
|
/** N6 — release the grabbed image/shape. Wired to `runtime.deselectObject()` by the host. */
|
|
181
193
|
onDeselectObject?: () => void;
|
|
194
|
+
/** Object handle drag lifecycle; routed through the mounted UI API seam. */
|
|
195
|
+
onBeginObjectDrag?: (input: UiObjectDragStartInput) => UiObjectDragSession;
|
|
182
196
|
activeSelectionTool?: ActiveSelectionToolModel | null;
|
|
183
197
|
selectionToolAnchor?: SelectionToolAnchor | null;
|
|
184
198
|
documentNavigation?: DocumentNavigationSnapshot;
|