@beyondwork/docx-react-component 1.0.67 → 1.0.70

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 (384) hide show
  1. package/README.md +75 -932
  2. package/package.json +26 -27
  3. package/src/api/anchor-conversion.ts +43 -0
  4. package/src/api/editor-state-types.ts +2 -1
  5. package/src/api/public-types.ts +504 -101
  6. package/src/api/session-state.ts +4 -0
  7. package/src/api/v3/README.md +91 -0
  8. package/src/api/v3/_create.ts +146 -0
  9. package/src/api/v3/_layer-metadata.ts +362 -0
  10. package/src/api/v3/_mocks.ts +84 -0
  11. package/src/api/v3/_runtime-handle.ts +162 -0
  12. package/src/api/v3/_ux-response.ts +73 -0
  13. package/src/api/v3/ai/_metadata-audit.ts +225 -0
  14. package/src/api/v3/ai/attach.ts +235 -0
  15. package/src/api/v3/ai/bundle.ts +132 -0
  16. package/src/api/v3/ai/explain.ts +144 -0
  17. package/src/api/v3/ai/export.ts +54 -0
  18. package/src/api/v3/ai/inspect.ts +118 -0
  19. package/src/api/v3/ai/policy.ts +77 -0
  20. package/src/api/v3/ai/replacement.ts +341 -0
  21. package/src/api/v3/ai/resolve.ts +133 -0
  22. package/src/api/v3/index.ts +79 -0
  23. package/src/api/v3/runtime/chart.ts +310 -0
  24. package/src/api/v3/runtime/clipboard.ts +81 -0
  25. package/src/api/v3/runtime/collab.ts +331 -0
  26. package/src/api/v3/runtime/content.ts +236 -0
  27. package/src/api/v3/runtime/document.ts +282 -0
  28. package/src/api/v3/runtime/formatting.ts +186 -0
  29. package/src/api/v3/runtime/geometry.ts +349 -0
  30. package/src/api/v3/runtime/layout.ts +108 -0
  31. package/src/api/v3/runtime/review.ts +129 -0
  32. package/src/api/v3/runtime/search.ts +74 -0
  33. package/src/api/v3/runtime/table.ts +63 -0
  34. package/src/api/v3/runtime/workflow.ts +434 -0
  35. package/src/api/v3/ui/_context.ts +86 -0
  36. package/src/api/v3/ui/_create.ts +65 -0
  37. package/src/api/v3/ui/_types.ts +520 -0
  38. package/src/api/v3/ui/chrome-composition.ts +342 -0
  39. package/src/{ui-tailwind/chrome → api/v3/ui}/chrome-preset-model.ts +11 -1
  40. package/src/api/v3/ui/chrome.ts +476 -0
  41. package/src/api/v3/ui/debug.ts +124 -0
  42. package/src/api/v3/ui/index.ts +64 -0
  43. package/src/api/v3/ui/overlays-visibility.ts +170 -0
  44. package/src/api/v3/ui/overlays.ts +427 -0
  45. package/src/api/v3/ui/scope.ts +71 -0
  46. package/src/api/v3/ui/session.ts +100 -0
  47. package/src/api/v3/ui/surface.ts +170 -0
  48. package/src/api/v3/ui/viewport.ts +303 -0
  49. package/src/core/commands/index.ts +28 -6
  50. package/src/core/commands/list-commands.ts +3 -2
  51. package/src/core/commands/section-layout-commands.ts +9 -8
  52. package/src/core/schema/text-schema.ts +16 -0
  53. package/src/core/selection/mapping.ts +33 -72
  54. package/src/core/state/editor-state.ts +96 -189
  55. package/src/index.ts +23 -4
  56. package/src/io/chart-preview-resolver.ts +1 -1
  57. package/src/io/docx-session.ts +36 -4797
  58. package/src/io/export/build-app-properties-xml.ts +1 -1
  59. package/src/io/export/serialize-comments.ts +1 -1
  60. package/src/io/export/serialize-headers-footers.ts +6 -1
  61. package/src/io/export/serialize-main-document.ts +45 -0
  62. package/src/io/export/serialize-run-formatting.ts +17 -2
  63. package/src/io/export/twip.ts +1 -1
  64. package/src/io/normalize/normalize-text.ts +27 -20
  65. package/src/io/ooxml/chart/parse-series.ts +1 -1
  66. package/src/io/ooxml/chart/resolve-color.ts +2 -2
  67. package/src/io/ooxml/chart/types.ts +1 -1
  68. package/src/io/ooxml/classify-embedding.ts +83 -33
  69. package/src/io/ooxml/parse-fill.ts +1 -1
  70. package/src/io/ooxml/parse-main-document.ts +71 -1
  71. package/src/io/ooxml/parse-object.ts +14 -10
  72. package/src/io/ooxml/parse-run-formatting.ts +47 -1
  73. package/src/io/ooxml/property-grab-bag.ts +2 -2
  74. package/src/io/ooxml/units.ts +11 -0
  75. package/src/io/ooxml/workflow-payload.ts +282 -7
  76. package/src/model/anchor.ts +85 -0
  77. package/src/model/canonical-document.ts +351 -15
  78. package/src/model/chart-types.ts +1 -1
  79. package/src/model/layout/index.ts +83 -0
  80. package/src/model/layout/page-graph-types.ts +181 -0
  81. package/src/model/layout/page-layout-snapshot.ts +105 -0
  82. package/src/model/layout/resolved-layout-types.ts +47 -0
  83. package/src/model/layout/runtime-page-graph-types.ts +102 -0
  84. package/src/model/paragraph-scope-ids.ts +72 -0
  85. package/src/model/review/comment-types.ts +112 -0
  86. package/src/model/review/index.ts +2 -0
  87. package/src/model/review/revision-types.ts +215 -0
  88. package/src/model/snapshot.ts +32 -0
  89. package/src/review/store/comment-store.ts +21 -47
  90. package/src/review/store/revision-types.ts +40 -198
  91. package/src/runtime/collab/base-doc-fingerprint.ts +6 -1
  92. package/src/runtime/collab/runtime-collab-sync.ts +13 -3
  93. package/src/runtime/collab-session.ts +1 -1
  94. package/src/runtime/debug/build-debug-inspector-snapshot.ts +686 -0
  95. package/src/runtime/debug/event-ring-buffer.ts +64 -0
  96. package/src/runtime/debug/probability-sampler.ts +18 -0
  97. package/src/runtime/debug/runtime-debug-facet.ts +67 -0
  98. package/src/runtime/debug/stage-tokens.ts +31 -0
  99. package/src/runtime/debug/telemetry-bus.ts +271 -0
  100. package/src/runtime/debug/types.ts +275 -0
  101. package/src/runtime/debug/wrap-ref-for-telemetry.ts +118 -0
  102. package/src/runtime/document-layout.ts +8 -6
  103. package/src/runtime/document-runtime.ts +843 -1141
  104. package/src/runtime/document-search.ts +1 -1
  105. package/src/runtime/edit-ops/index.ts +1 -1
  106. package/src/runtime/external-send-runtime.ts +1 -1
  107. package/src/runtime/formatting/document-lookup.ts +235 -0
  108. package/src/runtime/formatting/field/registry.ts +41 -0
  109. package/src/runtime/{field-resolver.ts → formatting/field/resolver.ts} +27 -2
  110. package/src/runtime/formatting/font-resolution.ts +83 -0
  111. package/src/runtime/formatting/formatting-context.ts +903 -0
  112. package/src/runtime/formatting/formatting-types.ts +157 -0
  113. package/src/runtime/{hyperlink-color-resolver.ts → formatting/hyperlink-color.ts} +2 -2
  114. package/src/runtime/formatting/index.ts +125 -0
  115. package/src/runtime/{resolved-numbering-geometry.ts → formatting/numbering/geometry.ts} +1 -1
  116. package/src/runtime/{numbering-prefix.ts → formatting/numbering/prefix.ts} +170 -3
  117. package/src/runtime/formatting/paragraph-style-resolver.ts +92 -0
  118. package/src/runtime/formatting/projector.ts +75 -0
  119. package/src/runtime/formatting/resolve-effective.ts +407 -0
  120. package/src/runtime/formatting/revision-display.ts +105 -0
  121. package/src/runtime/{paragraph-style-resolver.ts → formatting/style-cascade.ts} +84 -141
  122. package/src/runtime/{table-style-resolver.ts → formatting/table-style-resolver.ts} +1 -1
  123. package/src/runtime/formatting/telemetry-bridge.ts +106 -0
  124. package/src/runtime/{theme-color-resolver.ts → formatting/theme-color.ts} +2 -30
  125. package/src/runtime/geometry/caret-geometry.ts +164 -0
  126. package/src/runtime/geometry/geometry-facet.ts +364 -0
  127. package/src/runtime/geometry/geometry-types.ts +256 -0
  128. package/src/runtime/geometry/hit-test.ts +125 -0
  129. package/src/runtime/geometry/index.ts +71 -0
  130. package/src/runtime/geometry/inert-geometry-facet.ts +43 -0
  131. package/src/runtime/geometry/invalidation.ts +35 -0
  132. package/src/runtime/geometry/object-handles.ts +77 -0
  133. package/src/runtime/geometry/overlay-rects.ts +85 -0
  134. package/src/runtime/geometry/project-anchors.ts +100 -0
  135. package/src/runtime/geometry/project-fragments.ts +216 -0
  136. package/src/runtime/geometry/projector.ts +129 -0
  137. package/src/runtime/geometry/replacement-envelope.ts +130 -0
  138. package/src/runtime/geometry/viewport.ts +218 -0
  139. package/src/runtime/layout/compat-input-ledger.ts +211 -0
  140. package/src/runtime/layout/index.ts +6 -1
  141. package/src/runtime/layout/inert-layout-facet.ts +12 -7
  142. package/src/runtime/layout/layout-engine-instance.ts +189 -11
  143. package/src/runtime/layout/layout-engine-version.ts +450 -1
  144. package/src/runtime/layout/layout-facet-types.ts +60 -0
  145. package/src/runtime/layout/layout-measurement-provider.ts +13 -0
  146. package/src/runtime/layout/measurement-backend-canvas.ts +14 -2
  147. package/src/runtime/layout/measurement-backend-empirical.ts +23 -4
  148. package/src/runtime/layout/page-graph.ts +62 -209
  149. package/src/runtime/layout/page-story-resolver.ts +7 -12
  150. package/src/runtime/layout/paginated-layout-engine.ts +186 -11
  151. package/src/runtime/layout/project-block-fragments.ts +11 -0
  152. package/src/runtime/layout/projector.ts +90 -0
  153. package/src/runtime/layout/public-facet.ts +187 -442
  154. package/src/runtime/layout/resolved-formatting-state.ts +158 -26
  155. package/src/runtime/layout/table-render-plan.ts +1 -1
  156. package/src/runtime/prerender/cache-envelope.ts +6 -1
  157. package/src/runtime/prerender/prerender-document.ts +18 -23
  158. package/src/runtime/render/decoration-resolver.ts +1 -1
  159. package/src/runtime/render/render-frame-types.ts +20 -0
  160. package/src/runtime/render/render-kernel.ts +94 -25
  161. package/src/runtime/scopes/_formatting-seam.ts +262 -0
  162. package/src/runtime/scopes/_scope-dependencies.ts +49 -0
  163. package/src/runtime/scopes/action-validation.ts +356 -0
  164. package/src/runtime/scopes/attach-explanation.ts +102 -0
  165. package/src/runtime/scopes/audit-bundle.ts +71 -0
  166. package/src/runtime/scopes/compile-scope-bundle.ts +163 -0
  167. package/src/runtime/scopes/compile-scope.ts +262 -0
  168. package/src/runtime/scopes/compiler-service.ts +431 -0
  169. package/src/runtime/scopes/create-issue.ts +107 -0
  170. package/src/runtime/scopes/enumerate-scopes.ts +543 -0
  171. package/src/runtime/scopes/evidence.ts +233 -0
  172. package/src/runtime/scopes/index.ts +150 -0
  173. package/src/runtime/scopes/position-map.ts +214 -0
  174. package/src/runtime/scopes/preservation-boundary.ts +91 -0
  175. package/src/runtime/scopes/projector.ts +49 -0
  176. package/src/runtime/scopes/replaceability.ts +87 -0
  177. package/src/runtime/scopes/replacement/apply.ts +228 -0
  178. package/src/runtime/scopes/replacement/compile.ts +59 -0
  179. package/src/runtime/scopes/replacement/propose.ts +42 -0
  180. package/src/runtime/scopes/resolve-reference.ts +347 -0
  181. package/src/runtime/scopes/review-bundle.ts +141 -0
  182. package/src/runtime/scopes/scope-kinds/_paragraph-text.ts +57 -0
  183. package/src/runtime/scopes/scope-kinds/_table-text.ts +42 -0
  184. package/src/runtime/scopes/scope-kinds/comment-thread.ts +59 -0
  185. package/src/runtime/scopes/scope-kinds/field.ts +65 -0
  186. package/src/runtime/scopes/scope-kinds/heading.ts +84 -0
  187. package/src/runtime/scopes/scope-kinds/list-item.ts +77 -0
  188. package/src/runtime/scopes/scope-kinds/paragraph.ts +182 -0
  189. package/src/runtime/scopes/scope-kinds/revision.ts +62 -0
  190. package/src/runtime/scopes/scope-kinds/table-cell.ts +57 -0
  191. package/src/runtime/scopes/scope-kinds/table-row.ts +61 -0
  192. package/src/runtime/scopes/scope-kinds/table.ts +55 -0
  193. package/src/runtime/scopes/scope-range.ts +208 -0
  194. package/src/runtime/scopes/semantic-scope-types.ts +454 -0
  195. package/src/runtime/scopes/workflow-overlap.ts +92 -0
  196. package/src/runtime/selection/index.ts +1 -1
  197. package/src/runtime/structure-ops/fragment-insert.ts +1 -1
  198. package/src/runtime/structure-ops/index.ts +1 -1
  199. package/src/runtime/surface-projection.ts +232 -262
  200. package/src/runtime/units.ts +4 -2
  201. package/src/runtime/workflow/coordinator.ts +1348 -0
  202. package/src/runtime/workflow/derived-scope-resolver.ts +125 -0
  203. package/src/runtime/workflow/index.ts +25 -0
  204. package/src/runtime/workflow/markup-mode-policy.ts +98 -0
  205. package/src/runtime/{workflow-markup.ts → workflow/markup.ts} +6 -6
  206. package/src/runtime/workflow/metadata-persistence.ts +306 -0
  207. package/src/runtime/workflow/metadata-writer.ts +123 -0
  208. package/src/runtime/workflow/overlay-store.ts +690 -0
  209. package/src/runtime/workflow/projector.ts +127 -0
  210. package/src/runtime/{query-scopes.ts → workflow/query-scopes.ts} +3 -3
  211. package/src/runtime/{workflow-rail-segments.ts → workflow/rail/compose.ts} +60 -165
  212. package/src/runtime/workflow/rail/types.ts +198 -0
  213. package/src/runtime/workflow/scope-rail-composer.ts +39 -0
  214. package/src/runtime/{scope-resolver.ts → workflow/scope-resolver.ts} +3 -3
  215. package/src/runtime/workflow/scope-writer.ts +188 -0
  216. package/src/runtime/{tamper-gate.ts → workflow/tamper-gate.ts} +1 -1
  217. package/src/runtime/workflow/visibility-policy.ts +129 -0
  218. package/src/session/_sync-legacy.ts +66 -0
  219. package/src/session/export/embedded-reconstitute.ts +104 -0
  220. package/src/session/export/export-diagnostics.ts +85 -0
  221. package/src/session/export/export-validation.ts +110 -0
  222. package/src/session/export/index.ts +34 -0
  223. package/src/session/export/preservation-reattach.ts +30 -0
  224. package/src/session/export/serialize-dispatch.ts +165 -0
  225. package/src/session/export/stateful-export-pipeline.ts +432 -0
  226. package/src/session/export/stateful-export.ts +684 -0
  227. package/src/session/import/canonical-assembly.ts +227 -0
  228. package/src/session/import/diagnostics-session.ts +54 -0
  229. package/src/session/import/embedded-discovery.ts +225 -0
  230. package/src/session/import/embedded-offload.ts +337 -0
  231. package/src/session/import/import-diagnostics.ts +69 -0
  232. package/src/session/import/loader-types.ts +313 -0
  233. package/src/session/import/loader.ts +1834 -0
  234. package/src/session/import/normalize.ts +195 -0
  235. package/src/session/import/package-parts.ts +217 -0
  236. package/src/session/import/package-read.ts +195 -0
  237. package/src/session/import/parse-orchestration.ts +105 -0
  238. package/src/session/import/part-constants.ts +70 -0
  239. package/src/session/import/part-discovery.ts +94 -0
  240. package/src/session/import/preservation-index.ts +46 -0
  241. package/src/{runtime/read-only-diagnostics-runtime.ts → session/import/read-only-diagnostics.ts} +24 -3
  242. package/src/session/import/review-import.ts +508 -0
  243. package/src/session/import/styles-consolidation.ts +281 -0
  244. package/src/session/import/workflow-scope-import.ts +256 -0
  245. package/src/session/index.ts +37 -0
  246. package/src/session/session-state.ts +69 -0
  247. package/src/session/session.ts +532 -0
  248. package/src/session/shared/protection.ts +228 -0
  249. package/src/session/shared/session-utils.ts +82 -0
  250. package/src/session/types.ts +499 -0
  251. package/src/shell/chart-snapshots.ts +96 -0
  252. package/src/shell/media-previews.ts +85 -0
  253. package/src/shell/overlay-anchor-bridge.ts +53 -0
  254. package/src/shell/paste-adapter.ts +23 -0
  255. package/src/shell/ref-commands.ts +1697 -0
  256. package/src/shell/ref-utilities.ts +48 -0
  257. package/src/shell/search.ts +51 -0
  258. package/src/{ui/editor-runtime-boundary.ts → shell/session-bootstrap.ts} +243 -67
  259. package/src/shell/ui-subscriber-channels.ts +81 -0
  260. package/src/shell/use-collab-sync.ts +116 -0
  261. package/src/ui/WordReviewEditor.tsx +496 -2051
  262. package/src/ui/editor-shell-view.tsx +30 -1
  263. package/src/ui/editor-surface-controller.tsx +49 -1
  264. package/src/ui/headless/revision-decoration-model.ts +83 -0
  265. package/src/{ui-tailwind/chrome → ui/headless}/role-action-sets.ts +1 -1
  266. package/src/ui/headless/scoped-chrome-policy.ts +2 -2
  267. package/src/ui/headless/selection-tool-context.ts +1 -1
  268. package/src/ui/headless/selection-tool-resolver.ts +1 -1
  269. package/src/ui/runtime-shortcut-dispatch.ts +46 -1
  270. package/src/ui/ui-controller-factory.ts +221 -0
  271. package/src/ui-tailwind/chart/ChartSurface.tsx +2 -2
  272. package/src/ui-tailwind/chart/layout/legend-layout.ts +1 -1
  273. package/src/ui-tailwind/chart/layout/plot-area.ts +2 -2
  274. package/src/ui-tailwind/chart/layout/title-layout.ts +1 -1
  275. package/src/ui-tailwind/chart/render/area.tsx +3 -3
  276. package/src/ui-tailwind/chart/render/bar-column.tsx +3 -3
  277. package/src/ui-tailwind/chart/render/bubble.tsx +3 -3
  278. package/src/ui-tailwind/chart/render/combo.tsx +2 -2
  279. package/src/ui-tailwind/chart/render/data-labels.tsx +2 -2
  280. package/src/ui-tailwind/chart/render/font-metrics.ts +2 -2
  281. package/src/ui-tailwind/chart/render/line.tsx +3 -3
  282. package/src/ui-tailwind/chart/render/pie.tsx +6 -6
  283. package/src/ui-tailwind/chart/render/scatter.tsx +3 -3
  284. package/src/ui-tailwind/chart/render/svg-primitives.ts +3 -3
  285. package/src/ui-tailwind/chart/render/unsupported.tsx +2 -2
  286. package/src/ui-tailwind/chrome/build-context-menu-entries.ts +88 -0
  287. package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +1 -1
  288. package/src/ui-tailwind/chrome/collab-send-to-supplier-button.tsx +1 -1
  289. package/src/ui-tailwind/chrome/collab-tamper-banner.tsx +1 -1
  290. package/src/ui-tailwind/chrome/collab-top-nav-container.tsx +1 -1
  291. package/src/ui-tailwind/chrome/editor-action-registry.ts +553 -0
  292. package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +182 -0
  293. package/src/ui-tailwind/chrome/local-surface-arbiter.ts +534 -0
  294. package/src/ui-tailwind/chrome/resolve-target-kind.ts +226 -0
  295. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +38 -4
  296. package/src/ui-tailwind/chrome/tw-context-band.tsx +125 -0
  297. package/src/ui-tailwind/chrome/tw-context-menu-portal.tsx +248 -0
  298. package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +42 -1
  299. package/src/ui-tailwind/chrome/tw-selection-anchor-resolver.ts +8 -7
  300. package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +38 -4
  301. package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +104 -6
  302. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +66 -7
  303. package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +54 -8
  304. package/src/ui-tailwind/chrome/tw-shortcut-hint.tsx +7 -1
  305. package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +33 -0
  306. package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +78 -1
  307. package/src/ui-tailwind/chrome/tw-table-grip-layer.tsx +16 -8
  308. package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +276 -0
  309. package/src/ui-tailwind/chrome/use-context-menu-controller.ts +201 -0
  310. package/src/ui-tailwind/chrome-overlay/chrome-overlay-projector.ts +1 -1
  311. package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +22 -4
  312. package/src/ui-tailwind/chrome-overlay/tw-comment-balloon-layer.tsx +1 -1
  313. package/src/ui-tailwind/chrome-overlay/tw-locked-block-layer.tsx +1 -1
  314. package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +11 -5
  315. package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +197 -3
  316. package/src/ui-tailwind/chrome-overlay/tw-revision-margin-bar-layer.tsx +1 -1
  317. package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +35 -6
  318. package/src/ui-tailwind/chrome-overlay/tw-scope-rail-layer.tsx +24 -16
  319. package/src/ui-tailwind/chrome-overlay/tw-table-continuation-header.tsx +1 -1
  320. package/src/ui-tailwind/debug/README.md +57 -0
  321. package/src/ui-tailwind/debug/index.ts +3 -0
  322. package/src/ui-tailwind/debug/tw-debug-overlay.tsx +186 -0
  323. package/src/ui-tailwind/debug/tw-debug-presentation.tsx +80 -0
  324. package/src/ui-tailwind/debug/tw-debug-top-bar.tsx +83 -0
  325. package/src/ui-tailwind/editor-surface/chart-node-view.tsx +2 -2
  326. package/src/ui-tailwind/editor-surface/float-wrap-resolver.ts +1 -1
  327. package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +135 -10
  328. package/src/ui-tailwind/editor-surface/pm-decorations.ts +40 -13
  329. package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +1 -1
  330. package/src/ui-tailwind/editor-surface/pm-schema.ts +1 -1
  331. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +3 -3
  332. package/src/ui-tailwind/editor-surface/predicted-tag-preflight.ts +1 -1
  333. package/src/ui-tailwind/editor-surface/remote-cursor-plugin.ts +2 -2
  334. package/src/ui-tailwind/editor-surface/scroll-anchor.ts +91 -9
  335. package/src/ui-tailwind/editor-surface/shape-renderer.ts +1 -1
  336. package/src/ui-tailwind/editor-surface/surface-layer.ts +1 -1
  337. package/src/ui-tailwind/editor-surface/tw-opaque-block.tsx +1 -1
  338. package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +23 -6
  339. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +132 -22
  340. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +1 -1
  341. package/src/ui-tailwind/index.ts +0 -5
  342. package/src/ui-tailwind/overlay-anchor-bridge-context.tsx +33 -0
  343. package/src/ui-tailwind/page-stack/floating-image-overlay-model.ts +66 -29
  344. package/src/ui-tailwind/page-stack/tw-floating-image-layer.tsx +25 -2
  345. package/src/ui-tailwind/review/comment-markdown-renderer.tsx +15 -0
  346. package/src/ui-tailwind/review/tw-review-rail.tsx +92 -4
  347. package/src/ui-tailwind/review/tw-workflow-tab.tsx +1 -1
  348. package/src/ui-tailwind/review-workspace/page-chrome.ts +210 -0
  349. package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +101 -0
  350. package/src/ui-tailwind/review-workspace/paragraph-layout.ts +115 -0
  351. package/src/ui-tailwind/review-workspace/selection-toolbar-placement.ts +97 -0
  352. package/src/ui-tailwind/review-workspace/tw-review-workspace-navigator.tsx +130 -0
  353. package/src/ui-tailwind/review-workspace/tw-review-workspace-page-toolbar.tsx +240 -0
  354. package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +59 -0
  355. package/src/ui-tailwind/review-workspace/types.ts +408 -0
  356. package/src/ui-tailwind/review-workspace/use-chrome-policy.ts +104 -0
  357. package/src/ui-tailwind/review-workspace/use-derived-view-state.ts +151 -0
  358. package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +70 -0
  359. package/src/ui-tailwind/review-workspace/use-grabbed-segment-offsets.ts +40 -0
  360. package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +55 -0
  361. package/src/ui-tailwind/review-workspace/use-page-markers.ts +130 -0
  362. package/src/ui-tailwind/review-workspace/use-pm-surface-capture.ts +60 -0
  363. package/src/ui-tailwind/review-workspace/use-review-rail-state.ts +63 -0
  364. package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +170 -0
  365. package/src/ui-tailwind/review-workspace/use-scroll-root-capture.ts +28 -0
  366. package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +113 -0
  367. package/src/ui-tailwind/review-workspace/use-shell-selection-anchor-bridge.ts +120 -0
  368. package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +55 -0
  369. package/src/ui-tailwind/review-workspace/use-viewport-dimensions.ts +43 -0
  370. package/src/ui-tailwind/review-workspace/use-workspace-arbiter.ts +25 -0
  371. package/src/ui-tailwind/review-workspace/use-workspace-composition.ts +86 -0
  372. package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +150 -0
  373. package/src/ui-tailwind/theme/editor-theme.css +25 -0
  374. package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +2 -2
  375. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +61 -98
  376. package/src/ui-tailwind/tw-review-workspace.tsx +521 -1802
  377. package/src/ui-tailwind/ui-api-context.tsx +43 -0
  378. package/src/ui-tailwind/ui-shell-channels-context.tsx +49 -0
  379. package/src/validation/compatibility-engine.ts +6 -6
  380. package/src/runtime/styles-cascade.ts +0 -33
  381. package/src/ui-tailwind/chrome/tw-mode-dock.tsx +0 -85
  382. /package/src/runtime/{page-number-format.ts → formatting/field/page-number-format.ts} +0 -0
  383. /package/src/runtime/{ai-action-policy.ts → workflow/ai-action-policy.ts} +0 -0
  384. /package/src/runtime/{scope-tag-registry.ts → workflow/scope-tag-registry.ts} +0 -0
@@ -4,6 +4,7 @@ import type {
4
4
  ActiveListContext,
5
5
  DocumentNavigationSnapshot,
6
6
  EditorError,
7
+ EditorRole,
7
8
  FormattingStateSnapshot,
8
9
  InteractionGuardSnapshot,
9
10
  ReviewQueueSnapshot,
@@ -17,7 +18,7 @@ import type {
17
18
  WorkspaceMode,
18
19
  ZoomLevel,
19
20
  } from "../api/public-types.ts";
20
- import type { SessionCapabilities } from "../runtime/session-capabilities.ts";
21
+ import type { SessionCapabilities } from "../api/public-types.ts";
21
22
  import type { MarkupDisplay } from "./headless/comment-decoration-model.ts";
22
23
  import type {
23
24
  ActiveSelectionToolModel,
@@ -62,9 +63,31 @@ export interface EditorShellViewProps {
62
63
  * document column and the review rail's Workflow tab can read segments.
63
64
  */
64
65
  layoutFacet?: import("../runtime/layout/index.ts").WordReviewEditorLayoutFacet;
66
+ /**
67
+ * Layer-05 geometry facet (`runtime.geometry`). Passed through to
68
+ * `TwReviewWorkspace` which forwards it to the chrome overlay
69
+ * consumers (scope-rail, table-grip, object-selection, page-break
70
+ * decorations) for render-frame + zoom access. Migrated from
71
+ * `layoutFacet.getRenderFrame` / `.getRenderZoom` in refactor/05
72
+ * cross-lane-coord §8.4.
73
+ */
74
+ geometryFacet?: import("../runtime/geometry/index.ts").GeometryFacet;
75
+ /**
76
+ * Layer-06 workflow facet — canonical source of scope rail segments +
77
+ * scope card models. Passed through to `TwReviewWorkspace` which
78
+ * forwards it to the chrome overlay + scope-card hook. Layer-06
79
+ * Slice 4 made this the owning seam; the layout facet no longer
80
+ * exposes rail/card data.
81
+ */
82
+ workflowFacet?: import("../runtime/workflow/rail/types.ts").WorkflowFacet;
65
83
  interactionGuardSnapshot?: InteractionGuardSnapshot;
66
84
  chromePreset?: WordReviewEditorChromePreset;
67
85
  chromeOptions?: Partial<WordReviewEditorChromeOptions>;
86
+ editorActionHost?: import("../ui-tailwind/chrome/editor-action-registry.ts").EditorActionHostCallbacks;
87
+ chromeControllerRef?: React.Ref<
88
+ import("../ui-tailwind/chrome/tw-workspace-chrome-host.tsx").TwWorkspaceChromeHostController
89
+ >;
90
+ commandPaletteDisabled?: boolean;
68
91
  /** P9g — live collab session for the `"collab"` chrome preset's top nav. */
69
92
  collabSession?: import("../runtime/collab-session.ts").CollabSession;
70
93
  collabTransportStatus?: import("../api/awareness-identity-types.ts").TransportStatus;
@@ -84,6 +107,12 @@ export interface EditorShellViewProps {
84
107
  documentNavigation?: DocumentNavigationSnapshot;
85
108
  commands: EditorCommandBag;
86
109
  shellHeader?: ReactNode;
110
+ /**
111
+ * Forwarded to `TwReviewWorkspace` so the default `<TwShellHeader />` wires
112
+ * its mode tabs back to `runtime.setEditorRole`. Without this handler the
113
+ * shell-header mode tabs are decorative (U1 regression).
114
+ */
115
+ onEditorRoleChange?: (role: EditorRole) => void;
87
116
  document: ReactNode;
88
117
  onAddCommentFromSelection?: () => void;
89
118
  onAddCommentFromSuggestion?: () => void;
@@ -2,8 +2,11 @@ import React, { forwardRef } from "react";
2
2
 
3
3
  import type {
4
4
  DocumentNavigationSnapshot,
5
+ EditorStoryTarget,
5
6
  EditorUser,
6
7
  RuntimeRenderSnapshot,
8
+ SearchOptions,
9
+ SearchResultSnapshot,
7
10
  SelectionSnapshot,
8
11
  WorkflowBlockedCommandReason,
9
12
  WorkflowCandidateRange,
@@ -11,7 +14,8 @@ import type {
11
14
  WorkflowMetadataMarkup,
12
15
  WorkflowScope,
13
16
  } from "../api/public-types.ts";
14
- import type { CanonicalDocumentEnvelope } from "../core/state/editor-state.ts";
17
+ import type { TableSelectionDescriptor } from "../api/v3/runtime/table.ts";
18
+ import type { CanonicalDocumentEnvelope } from "../api/public-types.ts";
15
19
  import type { MarkupDisplay } from "./headless/comment-decoration-model.ts";
16
20
  import type { SelectionToolbarAnchor } from "./headless/selection-toolbar-model.ts";
17
21
  import type { ActiveSelectionToolModel } from "./headless/selection-tool-types.ts";
@@ -52,6 +56,34 @@ export interface EditorSurfaceControllerProps {
52
56
  onUndo?: () => void;
53
57
  onRedo?: () => void;
54
58
  onBlockedInput?: (command: "paste" | "drop", message: string) => void;
59
+ /**
60
+ * refactor/11 Slice 5 — forwarded to the PM bridge so rich-paste
61
+ * parsing no longer lives inside `src/ui-tailwind/editor-surface/**`.
62
+ * See `pm-command-bridge.ts` §`PasteFragmentParserAdapter`.
63
+ */
64
+ pasteFragmentParser?: import("../ui-tailwind/editor-surface/pm-command-bridge.ts").PasteFragmentParserAdapter;
65
+ /**
66
+ * §4.8 — forwarded to `TwProseMirrorSurface`. Threaded from the host's
67
+ * `api.runtime.search.searchDocument` at WordReviewEditor so L11
68
+ * presentation no longer imports `src/runtime/document-search.ts`
69
+ * directly.
70
+ */
71
+ runtimeSearchDocument?: (
72
+ document: import("../api/public-types.ts").CanonicalDocumentEnvelope,
73
+ selection: SelectionSnapshot,
74
+ activeStory: EditorStoryTarget,
75
+ navigation: DocumentNavigationSnapshot,
76
+ query: string,
77
+ options?: SearchOptions,
78
+ ) => SearchResultSnapshot[];
79
+ /**
80
+ * §4.8 — forwarded to `TwProseMirrorSurface`. Threaded from
81
+ * `api.runtime.table.getSelectionDescriptor` so L11 presentation no
82
+ * longer imports `src/runtime/table-commands.ts` directly.
83
+ */
84
+ runtimeGetTableSelectionDescriptor?: (
85
+ state: import("prosemirror-state").EditorState,
86
+ ) => TableSelectionDescriptor | null;
55
87
  onPasteApplied?: (meta: {
56
88
  segmentCount: number;
57
89
  charCount: number;
@@ -70,12 +102,28 @@ export interface EditorSurfaceControllerProps {
70
102
  command: import("../ui-tailwind/editor-surface/fast-text-edit-lane.ts").LaneRuntimeCommand,
71
103
  ) => import("../api/public-types.ts").TextCommandAck;
72
104
  layoutFacet?: import("../runtime/layout/index.ts").WordReviewEditorLayoutFacet;
105
+ /**
106
+ * Geometry facet forwarded to `TwProseMirrorSurface` for page-break
107
+ * decoration build path (refactor/05 cross-lane-coord §8.4).
108
+ */
109
+ geometryFacet?: import("../runtime/geometry/index.ts").GeometryFacet;
73
110
  pageChromeHeaderBandPx?: number;
74
111
  pageChromeFooterBandPx?: number;
75
112
  pageChromeInterGapPx?: number;
76
113
  pageBreakRevision?: number;
77
114
  onOpenHeaderStoryForPage?: (pageIndex: number) => void;
78
115
  onOpenFooterStoryForPage?: (pageIndex: number) => void;
116
+ /**
117
+ * Phase C.γ / §3.1 — right-click composition hook. Forwarded verbatim
118
+ * to `TwProseMirrorSurface.onContextMenuRequested`; the PM command
119
+ * bridge suppresses the browser-native menu when wired so the host
120
+ * can mount `TwContextMenu` at the returned coordinates.
121
+ */
122
+ onContextMenuRequested?: (event: {
123
+ clientX: number;
124
+ clientY: number;
125
+ target: EventTarget | null;
126
+ }) => void;
79
127
  }
80
128
 
81
129
  export const EditorSurfaceController = forwardRef<
@@ -146,6 +146,89 @@ export function getRevisionRangeState(
146
146
  };
147
147
  }
148
148
 
149
+ /**
150
+ * Shape of the per-segment `revisionDisplay` authoritative flags
151
+ * shipped by L03 formatting-semantics (see
152
+ * `SurfaceInlineSegment.revisionDisplay` in `src/api/public-types.ts`).
153
+ * Re-declared here to keep this helper a pure consumer of the public
154
+ * surface; the structural identity with the canonical type is enforced
155
+ * by `test/runtime/formatting/production-boundary.test.ts`.
156
+ */
157
+ export interface RevisionDisplayFlags {
158
+ markupMode: "clean" | "simple" | "all";
159
+ hidden?: boolean;
160
+ strikethrough?: boolean;
161
+ insertionUnderline?: boolean;
162
+ deemphasize?: boolean;
163
+ authorColor?: string;
164
+ }
165
+
166
+ /**
167
+ * Track B (cross-layer-coord-11 §3.1 / handoff §4 Track B / §5.2) —
168
+ * derive a revision-decoration CSS class from L03's authoritative
169
+ * `SurfaceInlineSegment.revisionDisplay` flags.
170
+ *
171
+ * Consumers that have access to the live surface-segment stream (e.g.
172
+ * `pm-decorations.ts` when threaded through Task B's integration
173
+ * follow-up) should call this helper instead of
174
+ * `getRevisionHighlightClass` — which reads the review-store
175
+ * `RevisionDecorationModel` + the `markupDisplay` prop as a side
176
+ * channel, re-deriving decisions L03 has already made. When the
177
+ * segment carries `revisionDisplay`, this helper reads the derived
178
+ * flags directly and emits the matching Tailwind class bundle. No
179
+ * markup-mode conditional is re-evaluated here: L03 already encoded
180
+ * the mode-specific derivation in `markupMode` + the visual flags.
181
+ *
182
+ * Returns `""` when no display flags apply (no revision at this
183
+ * segment) or when the caller should suppress rendering (the caller
184
+ * handles `hidden` by not rendering the span at all — this helper
185
+ * does not emit a `hidden` class to avoid double-suppression).
186
+ */
187
+ export function buildClassFromRevisionDisplay(
188
+ display: RevisionDisplayFlags | undefined,
189
+ ): string {
190
+ if (!display) return "";
191
+ if (display.hidden) return "";
192
+
193
+ const parts: string[] = [];
194
+
195
+ // Insertion underline (simple / all markup, insertion kind).
196
+ if (display.insertionUnderline) {
197
+ // Matches the underline visual used in the review-store path for
198
+ // "simple-markup" insertions; keeps the two paths producing the
199
+ // same class bundle so a mid-flight migration does not produce a
200
+ // visual diff.
201
+ parts.push(
202
+ "underline decoration-insert/60 decoration-1 underline-offset-2 text-primary",
203
+ );
204
+ }
205
+
206
+ // Strikethrough (deletion kind, simple or all markup).
207
+ if (display.strikethrough) {
208
+ parts.push("text-danger line-through decoration-danger/80 decoration-1");
209
+ }
210
+
211
+ // De-emphasize (e.g. inactive revision in all-markup; reviewer
212
+ // observer mode). Lighter body tone, no underline/strikethrough on
213
+ // its own — the caller composes them.
214
+ if (display.deemphasize && !display.strikethrough) {
215
+ parts.push("text-secondary");
216
+ }
217
+
218
+ // Surface the author palette color as a CSS variable the renderer
219
+ // can pick up via `var(--wre-revision-author)`. Consumer stylesheet
220
+ // composes this into ring/underline color when the palette slot is
221
+ // known. Absent when the segment has no resolved author color
222
+ // (anonymous revisions or pre-author-color import paths).
223
+ //
224
+ // The inline style path is handled by the caller (Tailwind classes
225
+ // cannot carry runtime-dynamic colors); this helper just emits the
226
+ // class bundle. Callers that need the author color render it
227
+ // separately via `display.authorColor`.
228
+
229
+ return parts.join(" ");
230
+ }
231
+
149
232
  export function getRevisionHighlightClass(
150
233
  model: RevisionDecorationModel | undefined,
151
234
  from: number,
@@ -13,7 +13,7 @@
13
13
  */
14
14
 
15
15
  import type { EditorRole } from "../../api/public-types";
16
- import type { ToolbarChromeItemId } from "../../ui/headless/chrome-registry";
16
+ import type { ToolbarChromeItemId } from "./chrome-registry";
17
17
 
18
18
  /**
19
19
  * Ordered role-action ids. Each array covers the *role-primary* actions
@@ -5,13 +5,13 @@ import type {
5
5
  WorkflowScopeSnapshot,
6
6
  WordReviewEditorChromePreset,
7
7
  } from "../../api/public-types";
8
- import type { SessionCapabilities } from "../../runtime/session-capabilities";
8
+ import type { SessionCapabilities } from "../../api/public-types";
9
9
  import {
10
10
  TOOLBAR_CHROME_REGISTRY,
11
11
  type ToolbarChromeItemId,
12
12
  type ToolbarChromePlacement,
13
13
  } from "./chrome-registry";
14
- import { ROLE_ACTION_SETS } from "../../ui-tailwind/chrome/role-action-sets";
14
+ import { ROLE_ACTION_SETS } from "./role-action-sets";
15
15
  import type { SelectionToolKind } from "./selection-tool-types";
16
16
 
17
17
  export interface ToolbarChromeItemPolicy {
@@ -4,7 +4,7 @@ import type {
4
4
  RuntimeRenderSnapshot,
5
5
  StyleCatalogSnapshot,
6
6
  } from "../../api/public-types";
7
- import type { SessionCapabilities } from "../../runtime/session-capabilities";
7
+ import type { SessionCapabilities } from "../../api/public-types";
8
8
  import type { ScopedChromePolicy } from "./scoped-chrome-policy";
9
9
  import type { SelectionToolResolverContext } from "./selection-tool-types";
10
10
 
@@ -5,7 +5,7 @@ import type {
5
5
  TrackedChangeEntrySnapshot,
6
6
  WorkflowScopeSnapshot,
7
7
  } from "../../api/public-types";
8
- import { storyTargetsEqual } from "../../core/selection/mapping";
8
+ import { storyTargetsEqual } from "../../api/public-types";
9
9
  import type { SelectionToolResolverInput } from "./selection-tool-context";
10
10
  import type {
11
11
  ActiveSelectionToolModel,
@@ -43,7 +43,30 @@ export type ShellShortcutResolution =
43
43
  | { kind: "dismiss-selection-toolbar" }
44
44
  | { kind: "toggle-formatting"; mark: "bold" | "italic" | "underline" }
45
45
  | { kind: "add-comment" }
46
- | { kind: "set-heading-level"; level: 1 | 2 | 3 };
46
+ | { kind: "set-heading-level"; level: 1 | 2 | 3 }
47
+ /**
48
+ * Phase C.γ.5 — composition-level shortcuts.
49
+ * These surface at the shell level because they target
50
+ * composition-owned surfaces (context menu, rail, scope navigation)
51
+ * rather than a document edit.
52
+ * - `open-context-menu` fires on Shift+F10 and delegates to the
53
+ * workspace controller to mount `TwContextMenu` at the caret.
54
+ * `fromKeyboard: true` signals to the consumer that coords must
55
+ * be resolved from the caret position (via the existing
56
+ * `tw-selection-anchor-resolver` helper) rather than from the
57
+ * event — keyboard events don't carry clientX/clientY. Phase
58
+ * D.5 shortcut-gap fix.
59
+ * - `focus-rail` fires on Ctrl/Cmd+Shift+R and routes focus into
60
+ * the active rail tab (DESIGN-EDITOR.md §8).
61
+ * - `navigate-scope` fires on Alt+Up / Alt+Down for workflow
62
+ * scope traversal (DESIGN-EDITOR.md §8, supersedes the
63
+ * currently-planned Ctrl/Cmd+Up/Down pair after review found
64
+ * those bindings already conflict with macOS scroll-to-top/
65
+ * bottom defaults).
66
+ */
67
+ | { kind: "open-context-menu"; fromKeyboard: true }
68
+ | { kind: "focus-rail" }
69
+ | { kind: "navigate-scope"; direction: 1 | -1 };
47
70
 
48
71
  export type SurfaceShortcutResolution =
49
72
  | { kind: "none" }
@@ -159,6 +182,28 @@ export function resolveShellShortcut(
159
182
  return { kind: "delegate", shortcut: "last-edit" };
160
183
  }
161
184
 
185
+ // Phase C.γ.5 — composition shortcuts. These resolve regardless of
186
+ // `selectionToolbarVisible` so keyboard access is consistent across
187
+ // floating-surface states. The Ctrl+K / Cmd+K palette shortcut is
188
+ // owned by TwCommandPaletteMount (a global window listener); it is
189
+ // NOT routed here because the palette needs to intercept the key
190
+ // before any per-surface dispatch.
191
+ if (key === "f10" && input.shiftKey && !input.ctrlKey && !input.metaKey && !input.altKey) {
192
+ return { kind: "open-context-menu", fromKeyboard: true };
193
+ }
194
+ if (
195
+ (input.ctrlKey || input.metaKey) &&
196
+ input.shiftKey &&
197
+ !input.altKey &&
198
+ key === "r"
199
+ ) {
200
+ return { kind: "focus-rail" };
201
+ }
202
+ if (input.altKey && !input.ctrlKey && !input.metaKey && !input.shiftKey) {
203
+ if (key === "arrowup") return { kind: "navigate-scope", direction: -1 };
204
+ if (key === "arrowdown") return { kind: "navigate-scope", direction: 1 };
205
+ }
206
+
162
207
  return { kind: "none" };
163
208
  }
164
209
 
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Shell-side `UiControllerFactory` implementation (refactor/11 Slice 4 consumer
3
+ * wiring — the counterpart to refactor/10 Slice 10's `UiApiProvider`).
4
+ *
5
+ * The factory is what turns `createApiV3(handle, { ui: factory })` into an
6
+ * `api.ui` with real method paths. When no hook is supplied, a UI API method
7
+ * that depends on one throws a configuration-clear error (per `_types.ts`
8
+ * `UiController` docstrings) rather than silently no-oping.
9
+ *
10
+ * Three entry points:
11
+ *
12
+ * 1. `shellUiControllerFactory` — zero-deps default. Used by the lazy
13
+ * `refValue.getApiV3()` path and any non-mounted caller (SSR, harness)
14
+ * that doesn't have shell state available. Produces a controller with
15
+ * an empty bridge + no hooks wired; UI API methods that require a
16
+ * hook throw or return `null`.
17
+ *
18
+ * 2. `createShellUiControllerFactory(bridge)` — narrow builder that wires
19
+ * the DS-C1 selection-anchor bridge only (refactor/11 Slice DS-C1).
20
+ * Back-compat entry for shell code that hasn't adopted the wider
21
+ * deps shape. Equivalent to `makeShellUiControllerFactory({
22
+ * getOverlayAnchor: bridge-backed })`.
23
+ *
24
+ * 3. `makeShellUiControllerFactory(deps)` — full deps builder used by the
25
+ * mounted `WordReviewEditor.tsx` render path. `deps` is a narrow record
26
+ * of shell-side getters + subscribers + an optional overlay-anchor
27
+ * resolver. Only the keys the shell populates land on the controller;
28
+ * everything else stays absent.
29
+ *
30
+ * Design: the shell populates hooks one consumer at a time.
31
+ *
32
+ * - `getHostPosture` + `getPinnedSurfaces` are wired on the mounted path
33
+ * today because `useWorkspaceComposition` + `ui.chrome.getPosture`
34
+ * need them (refactor/10 Task 1).
35
+ *
36
+ * - `getOverlayAnchor` for `kind:"selection"` is wired via the bridge
37
+ * populated by `use-shell-selection-anchor-bridge.ts` (DS-C1).
38
+ * Non-selection kinds already resolve through `handle.geometry.*`
39
+ * inside `src/api/v3/ui/overlays.ts`; the controller hook returns
40
+ * `null` for them so the API keeps delegating to the geometry facet.
41
+ *
42
+ * - `subscribe*` hooks are kept deps-optional — they serve non-React
43
+ * consumers (Playwright, window-debug) and land when those surfaces
44
+ * come online.
45
+ *
46
+ * Per U4 in `docs/architecture/10-ui-api.md`: `getOverlayAnchor` MUST
47
+ * return `null` (never fall back to DOM) when the bridge is unpopulated.
48
+ * `ui.overlays.getAnchor` already encodes this contract.
49
+ */
50
+
51
+ import type {
52
+ ChromeHostPosture,
53
+ ChromeSurface,
54
+ ChromePosture,
55
+ GeometryRect,
56
+ OverlayAnchorQuery,
57
+ UiController,
58
+ UiControllerFactory,
59
+ UiListener,
60
+ UiUnsubscribe,
61
+ ViewportState,
62
+ } from "../api/v3/ui/_types.ts";
63
+ import type {
64
+ WordReviewEditorChromeOptions,
65
+ WordReviewEditorChromePreset,
66
+ } from "../api/public-types.ts";
67
+ import { resolveChromeVisibilityForPreset } from "../api/v3/ui/chrome-preset-model.ts";
68
+ import type { ShellOverlayAnchorBridge } from "../shell/overlay-anchor-bridge.ts";
69
+ import { createShellOverlayAnchorBridge } from "../shell/overlay-anchor-bridge.ts";
70
+
71
+ let nextControllerId = 0;
72
+
73
+ /**
74
+ * Deps the shell provides to `makeShellUiControllerFactory`. Every field
75
+ * is optional — the builder wires only the hooks that are supplied. Missing
76
+ * hooks map to `undefined` on the controller, which lets L10 produce a
77
+ * configuration-clear error when a consumer calls an un-wired method.
78
+ */
79
+ export interface ShellUiControllerDeps {
80
+ /**
81
+ * Current host-provided posture slice — reviewMode / markupDisplay /
82
+ * debugMode / chromePreset. MUST read through a live ref so the factory
83
+ * closure returns current render state, not stale construction-time state.
84
+ */
85
+ readonly getHostPosture?: () => ChromeHostPosture | undefined;
86
+ /**
87
+ * Pinned-surface enumeration. Typically computed from
88
+ * `resolveChromeVisibilityForPreset` against the current preset + options.
89
+ */
90
+ readonly getPinnedSurfaces?: () => readonly ChromeSurface[];
91
+ /**
92
+ * Overlay anchor resolver (DS-C1 selection-anchor bridge). Returns
93
+ * `null` when the bridge is unpopulated or the query kind doesn't map.
94
+ */
95
+ readonly getOverlayAnchor?: (query: OverlayAnchorQuery) => GeometryRect | null;
96
+ /**
97
+ * Posture-change stream. Fires when any of the inputs to `ChromePosture`
98
+ * change — reviewMode / markupDisplay / debugMode / chromePreset (host),
99
+ * effectiveMode / blockedReasons / documentMode / readOnly (runtime).
100
+ * Returns an unsubscribe function.
101
+ *
102
+ * React-based consumers re-read on render and typically don't need this;
103
+ * the hook exists for non-React consumers (Playwright drivers, debug
104
+ * service) that hold an `api.ui` across time.
105
+ */
106
+ readonly subscribeChrome?: (listener: UiListener<ChromePosture>) => UiUnsubscribe;
107
+ /** Container-dim-measured viewport snapshot. */
108
+ readonly getViewport?: () => ViewportState;
109
+ /**
110
+ * Viewport change stream — rAF-coalesced per U7. Fires on scroll / zoom /
111
+ * dpr / container-resize. Returns unsubscribe.
112
+ */
113
+ readonly subscribeViewport?: (listener: UiListener<ViewportState>) => UiUnsubscribe;
114
+ /**
115
+ * Overlay invalidation stream — fires when geometry invalidation overlaps
116
+ * an attached overlay query (U7). Typically delegated to the render
117
+ * kernel's per-frame invalidation bus.
118
+ */
119
+ readonly subscribeOverlays?: (
120
+ listener: UiListener<OverlayAnchorQuery>,
121
+ ) => UiUnsubscribe;
122
+ }
123
+
124
+ /**
125
+ * Build a `UiControllerFactory` closing over `deps`. Each call of the
126
+ * returned factory produces a fresh controller with a unique id — the UI
127
+ * API's session family uses the id to distinguish bindings (useful for
128
+ * debug logs + multi-instance isolation tests).
129
+ *
130
+ * Only the deps that were supplied are forwarded to the controller; `undefined`
131
+ * deps produce an absent controller hook (the documented contract for
132
+ * "not wired").
133
+ */
134
+ export function makeShellUiControllerFactory(
135
+ deps: ShellUiControllerDeps = {},
136
+ ): UiControllerFactory {
137
+ return () => {
138
+ nextControllerId += 1;
139
+ const controller: UiController = {
140
+ kind: "runtime-direct",
141
+ id: `wre-shell-${nextControllerId}`,
142
+ ...(deps.getHostPosture ? { getHostPosture: deps.getHostPosture } : {}),
143
+ ...(deps.getPinnedSurfaces ? { getPinnedSurfaces: deps.getPinnedSurfaces } : {}),
144
+ ...(deps.getOverlayAnchor ? { getOverlayAnchor: deps.getOverlayAnchor } : {}),
145
+ ...(deps.subscribeChrome ? { subscribeChrome: deps.subscribeChrome } : {}),
146
+ ...(deps.getViewport ? { getViewport: deps.getViewport } : {}),
147
+ ...(deps.subscribeViewport ? { subscribeViewport: deps.subscribeViewport } : {}),
148
+ ...(deps.subscribeOverlays ? { subscribeOverlays: deps.subscribeOverlays } : {}),
149
+ };
150
+ return controller;
151
+ };
152
+ }
153
+
154
+ /**
155
+ * Narrow builder — wires the DS-C1 overlay-anchor bridge only (refactor/11
156
+ * Slice 4). Back-compat entry for shell code that hasn't adopted the
157
+ * wider `ShellUiControllerDeps` shape. Equivalent to calling
158
+ * `makeShellUiControllerFactory({ getOverlayAnchor: bridge-backed })`.
159
+ *
160
+ * Identity of the returned factory is stable across renders so long as
161
+ * `bridge` identity is stable (create the bridge with
162
+ * `useRef(createShellOverlayAnchorBridge()).current`).
163
+ */
164
+ export function createShellUiControllerFactory(
165
+ bridge: ShellOverlayAnchorBridge,
166
+ ): UiControllerFactory {
167
+ return makeShellUiControllerFactory({
168
+ getOverlayAnchor: (query: OverlayAnchorQuery) => {
169
+ if (query.kind === "selection") {
170
+ return bridge.getSelectionAnchor?.() ?? null;
171
+ }
172
+ return null;
173
+ },
174
+ });
175
+ }
176
+
177
+ /**
178
+ * Zero-deps default factory. Back-compat with callers that don't have
179
+ * shell state available (the lazy `refValue.getApiV3()` path, SSR, harness
180
+ * constructors). Produces a minimal controller backed by an empty bridge;
181
+ * `ui.overlays.getAnchor({kind:"selection"})` returns `null` honoring U4.
182
+ */
183
+ export const shellUiControllerFactory: UiControllerFactory =
184
+ createShellUiControllerFactory(createShellOverlayAnchorBridge());
185
+
186
+ /**
187
+ * Translate the host-facing preset + options into the `ChromeSurface[]`
188
+ * list `ui.chrome.getPinnedSurfaces()` returns. Pure — suitable for a
189
+ * getter closure inside a `ShellUiControllerDeps`. Uses the L10-owned
190
+ * `resolveChromeVisibilityForPreset` helper (relocated in Slice 8) so
191
+ * the mapping stays inside the UI API layer and nothing has to reimport
192
+ * the L11 shim.
193
+ *
194
+ * Enumeration scope (review M5 2026-04-22): only `toolbar` + `rail`
195
+ * surfaces are emitted today — those are the shell's pinnable workspace
196
+ * surfaces. The `ChromeSurfaceKind` union also includes `sidebar`,
197
+ * `command-palette`, `context-menu`, `top-nav`; those are not
198
+ * preset-driven pinned surfaces in the current shell. When consumer
199
+ * work needs them enumerated (e.g. `command-palette` pinning), extend
200
+ * this helper — the `ChromeSurface` shape already supports it.
201
+ */
202
+ export function deriveShellPinnedSurfaces(
203
+ chromePreset: WordReviewEditorChromePreset,
204
+ chromeOptions: Partial<WordReviewEditorChromeOptions> | undefined,
205
+ ): readonly ChromeSurface[] {
206
+ const visibility = resolveChromeVisibilityForPreset({
207
+ chromePreset,
208
+ chromeOptions,
209
+ });
210
+ const surfaces: ChromeSurface[] = [];
211
+ if (visibility.toolbar) {
212
+ surfaces.push({ kind: "toolbar", id: "workspace-toolbar", visible: true, pinned: true });
213
+ }
214
+ if (visibility.reviewRail) {
215
+ surfaces.push({ kind: "rail", id: "review-rail", visible: true, pinned: true });
216
+ }
217
+ // `pageChrome` is a structural canvas adornment rather than a
218
+ // dismissible surface; it's not enumerated here per §U5.b — page
219
+ // presence is part of ChromeComposition, not ChromeSurface.
220
+ return surfaces;
221
+ }
@@ -22,8 +22,8 @@
22
22
  */
23
23
 
24
24
  import React from "react";
25
- import type { ChartModel } from "../../io/ooxml/chart/types.ts";
26
- import type { ResolvedTheme } from "../../model/canonical-document.ts";
25
+ import type { ChartModel } from "../../api/public-types.ts";
26
+ import type { ResolvedTheme } from "../../api/public-types.ts";
27
27
  import { layoutPlotArea, CHROME_PAINTED_DEFAULT, type PlotAreaLayout } from "./layout/plot-area.ts";
28
28
  import { AreaChart } from "./render/area.tsx";
29
29
  import { BarColumnChart } from "./render/bar-column.tsx";
@@ -26,7 +26,7 @@
26
26
  */
27
27
 
28
28
  import type { Rect } from "./plot-area.ts";
29
- import type { ResolvedTheme } from "../../../model/canonical-document.ts";
29
+ import type { ResolvedTheme } from "../../../api/public-types.ts";
30
30
  import { measureText } from "../render/font-metrics.ts";
31
31
 
32
32
  // ---------------------------------------------------------------------------
@@ -20,8 +20,8 @@
20
20
  * signature is unchanged.
21
21
  */
22
22
 
23
- import type { ChartModel } from "../../../io/ooxml/chart/types.ts";
24
- import type { ResolvedTheme } from "../../../model/canonical-document.ts";
23
+ import type { ChartModel } from "../../../api/public-types.ts";
24
+ import type { ResolvedTheme } from "../../../api/public-types.ts";
25
25
  import { measureText } from "../render/font-metrics.ts";
26
26
  import { formatNumber } from "../render/number-format.ts";
27
27
  import {
@@ -23,7 +23,7 @@
23
23
  */
24
24
 
25
25
  import type { Rect } from "./plot-area.ts";
26
- import type { ResolvedTheme } from "../../../model/canonical-document.ts";
26
+ import type { ResolvedTheme } from "../../../api/public-types.ts";
27
27
  import { measureText } from "../render/font-metrics.ts";
28
28
 
29
29
  // ---------------------------------------------------------------------------
@@ -22,12 +22,12 @@
22
22
  */
23
23
 
24
24
  import React from "react";
25
- import { composeSeriesColor } from "../../../io/ooxml/chart/compose-series-color.ts";
25
+ import { composeSeriesColor } from "../../../api/v3/runtime/chart.ts";
26
26
  import type {
27
27
  AreaChartModel,
28
28
  Series,
29
- } from "../../../io/ooxml/chart/types.ts";
30
- import type { ResolvedTheme } from "../../../model/canonical-document.ts";
29
+ } from "../../../api/public-types.ts";
30
+ import type { ResolvedTheme } from "../../../api/public-types.ts";
31
31
  import type { PlotAreaLayout } from "../layout/plot-area.ts";
32
32
  import { useProgressiveCount } from "./progressive-render.ts";
33
33
 
@@ -26,13 +26,13 @@
26
26
  */
27
27
 
28
28
  import React from "react";
29
- import { composeSeriesColor } from "../../../io/ooxml/chart/compose-series-color.ts";
29
+ import { composeSeriesColor } from "../../../api/v3/runtime/chart.ts";
30
30
  import type {
31
31
  BarChartModel,
32
32
  DataPointOverride,
33
33
  Series,
34
- } from "../../../io/ooxml/chart/types.ts";
35
- import type { ResolvedTheme } from "../../../model/canonical-document.ts";
34
+ } from "../../../api/public-types.ts";
35
+ import type { ResolvedTheme } from "../../../api/public-types.ts";
36
36
  import type { PlotAreaLayout } from "../layout/plot-area.ts";
37
37
  import { resolveFill, DefsRegistry } from "./svg-primitives.ts";
38
38
  import { useProgressiveCount } from "./progressive-render.ts";
@@ -10,12 +10,12 @@
10
10
  */
11
11
 
12
12
  import React from "react";
13
- import { composeSeriesColor } from "../../../io/ooxml/chart/compose-series-color.ts";
13
+ import { composeSeriesColor } from "../../../api/v3/runtime/chart.ts";
14
14
  import type {
15
15
  BubbleChartModel,
16
16
  BubbleSeries,
17
- } from "../../../io/ooxml/chart/types.ts";
18
- import type { ResolvedTheme } from "../../../model/canonical-document.ts";
17
+ } from "../../../api/public-types.ts";
18
+ import type { ResolvedTheme } from "../../../api/public-types.ts";
19
19
  import type { PlotAreaLayout } from "../layout/plot-area.ts";
20
20
 
21
21
  // ---------------------------------------------------------------------------