@beyondwork/docx-react-component 1.0.66 → 1.0.69

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 -931
  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 -4795
  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
@@ -0,0 +1,553 @@
1
+ /**
2
+ * editor-action-registry — the single source of truth for what
3
+ * contextual actions exist, keyed by `TargetKind`.
4
+ *
5
+ * Consumed by three access routes so DESIGN-EDITOR.md §6.4 holds by
6
+ * construction ("right-click cannot be richer than the floating surface;
7
+ * cannot duplicate command trees"):
8
+ *
9
+ * 1. Right-click context menu (via `build-context-menu-entries.ts`)
10
+ * 2. Inline "More…" affordance on reduced floating toolbars (Phase D)
11
+ * 3. Command palette groups (Phase C.δ)
12
+ *
13
+ * All three routes produce the same actions from this registry — they
14
+ * cannot diverge. This is the load-bearing decision that makes the
15
+ * floating-menu demotion legal.
16
+ *
17
+ * Perf discipline: pure data + pure filter helpers. No DOM reads, no
18
+ * runtime calls, no observers. Actions are dispatched through host-
19
+ * supplied callbacks so the registry never references the PM view or
20
+ * the document runtime directly.
21
+ */
22
+
23
+ import type { EditorChromeMode } from "../../api/v3/ui/chrome-composition";
24
+ import type { ContextMenuGroupId } from "./tw-context-menu";
25
+ import type { ShortcutKey } from "./tw-shortcut-hint";
26
+
27
+ /**
28
+ * Target kinds roughly mirror DESIGN-EDITOR.md §4 "Local context" cells.
29
+ * A contextmenu event resolves its target to one (or more) of these
30
+ * kinds; the builder then asks the registry for every action whose
31
+ * `targetKinds` set includes at least one of the resolved kinds.
32
+ */
33
+ export type TargetKind =
34
+ | "plain-text" // caret or selection in flowing body text
35
+ | "table-cell" // caret / selection inside a table cell (T1/T2)
36
+ | "table-row" // whole row selected (T3) — Chrome Closure Pass · Task 3
37
+ | "table-column" // whole column selected (T4b) — Chrome Closure Pass · Task 3
38
+ | "table-whole" // whole table selected (T5) — Chrome Closure Pass · Task 3
39
+ | "image" // an anchored image (inline or floating)
40
+ | "object" // preserved shape / textbox / OLE / SmartArt
41
+ | "hyperlink" // caret inside or selection over a hyperlink
42
+ | "comment-anchor" // caret at a comment-anchored range
43
+ | "suggestion" // caret at a tracked-change suggestion
44
+ | "opaque-block" // preserved-for-export placeholder
45
+ | "scope-anchor"; // caret inside a workflow scope
46
+
47
+ /**
48
+ * Dispatch context passed to each action's `run()` function.
49
+ * Host callbacks + composition posture + selection state come through
50
+ * here so the registry's actions never reach into React / PM internals.
51
+ */
52
+ export interface EditorActionDispatchContext {
53
+ readonly composition: { readonly mode: EditorChromeMode };
54
+ readonly host: EditorActionHostCallbacks;
55
+ /** Close the menu / palette after dispatching, if applicable. */
56
+ readonly dismiss: () => void;
57
+ }
58
+
59
+ /**
60
+ * Host callbacks the editor shell passes down to the registry. All
61
+ * fields are optional — the registry's `when()` predicates filter out
62
+ * actions the host hasn't wired yet so the menu never shows a row that
63
+ * can't fire.
64
+ *
65
+ * Phases C/D/E will wire these from the existing ref methods on
66
+ * `WordReviewEditorRef`; the surface is intentionally minimal now.
67
+ */
68
+ export interface EditorActionHostCallbacks {
69
+ // Clipboard (always available — browser-native fallback acceptable)
70
+ readonly onCut?: () => void;
71
+ readonly onCopy?: () => void;
72
+ readonly onPaste?: () => void;
73
+
74
+ // Tracked-change operations (suggestion target)
75
+ readonly onAcceptSuggestion?: () => void;
76
+ readonly onRejectSuggestion?: () => void;
77
+
78
+ // Comment operations (comment-anchor target)
79
+ readonly onResolveComment?: () => void;
80
+ readonly onReplyToComment?: () => void;
81
+ readonly onJumpToCommentInRail?: () => void;
82
+
83
+ // Table operations (table-cell target)
84
+ readonly onInsertRowAbove?: () => void;
85
+ readonly onInsertRowBelow?: () => void;
86
+ readonly onInsertColumnBefore?: () => void;
87
+ readonly onInsertColumnAfter?: () => void;
88
+ readonly onDeleteRow?: () => void;
89
+ readonly onDeleteColumn?: () => void;
90
+ readonly onMergeCells?: () => void;
91
+ readonly onSplitCell?: () => void;
92
+ readonly onOpenTableProperties?: () => void;
93
+ readonly onOpenBorderPicker?: () => void;
94
+
95
+ // Image operations (image target)
96
+ readonly onReplaceImage?: () => void;
97
+ readonly onEditImageAltText?: () => void;
98
+ readonly onSetImageSize?: (preset: "small" | "medium" | "large") => void;
99
+
100
+ // Object operations (object target — read-only info by DESIGN-EDITOR.md §6.10)
101
+ readonly onOpenObjectInfo?: () => void;
102
+
103
+ // Hyperlink operations (hyperlink target)
104
+ readonly onEditHyperlink?: () => void;
105
+ readonly onRemoveHyperlink?: () => void;
106
+ readonly onOpenHyperlink?: () => void;
107
+
108
+ // Workflow (scope-anchor target)
109
+ readonly onJumpToScopeInRail?: () => void;
110
+ readonly onOpenScopeCard?: () => void;
111
+ readonly onMarkScopeResolved?: () => void;
112
+ }
113
+
114
+ export interface EditorAction {
115
+ readonly id: string;
116
+ readonly label: string;
117
+ readonly shortcut?: readonly ShortcutKey[];
118
+ readonly group: ContextMenuGroupId;
119
+ /** Targets for which this action is relevant. */
120
+ readonly targetKinds: ReadonlySet<TargetKind>;
121
+ /**
122
+ * Optional mode filter — some actions only surface in specific modes.
123
+ * Empty / undefined means "always in scope of its target".
124
+ */
125
+ readonly modes?: ReadonlySet<EditorChromeMode>;
126
+ /**
127
+ * Optional availability predicate. Return `false` to hide the row;
128
+ * `true` to show; `"disabled"` to show as a non-interactive disabled
129
+ * row (DESIGN-EDITOR.md §6.4 "disabled items remain visible when
130
+ * explanation matters").
131
+ */
132
+ readonly when?: (
133
+ ctx: EditorActionDispatchContext,
134
+ ) => boolean | "disabled";
135
+ readonly run: (ctx: EditorActionDispatchContext) => void;
136
+ }
137
+
138
+ // ---------------------------------------------------------------------
139
+ // The registry itself — terse, data-driven.
140
+ // ---------------------------------------------------------------------
141
+
142
+ /**
143
+ * Build a zero-argument action. The callback referenced by `opts.callback`
144
+ * is invoked with no arguments at dispatch. Use `mkArg()` below for
145
+ * callbacks that take a payload.
146
+ */
147
+ function mk<K extends keyof EditorActionHostCallbacks>(opts: {
148
+ id: string;
149
+ label: string;
150
+ shortcut?: readonly ShortcutKey[];
151
+ group: ContextMenuGroupId;
152
+ targetKinds: readonly TargetKind[];
153
+ modes?: readonly EditorChromeMode[];
154
+ callback: K;
155
+ /** Optional extra predicate run after the callback-presence check. */
156
+ when?: (ctx: EditorActionDispatchContext) => boolean | "disabled";
157
+ }): EditorAction {
158
+ return {
159
+ id: opts.id,
160
+ label: opts.label,
161
+ ...(opts.shortcut ? { shortcut: opts.shortcut } : {}),
162
+ group: opts.group,
163
+ targetKinds: new Set(opts.targetKinds),
164
+ ...(opts.modes ? { modes: new Set(opts.modes) } : {}),
165
+ when: (ctx) => {
166
+ if (typeof ctx.host[opts.callback] !== "function") return false;
167
+ if (opts.when) return opts.when(ctx);
168
+ return true;
169
+ },
170
+ run: (ctx) => {
171
+ const fn = ctx.host[opts.callback] as (() => void) | undefined;
172
+ fn?.();
173
+ ctx.dismiss();
174
+ },
175
+ };
176
+ }
177
+
178
+ /**
179
+ * Build a one-argument action. `payload` is the value passed to the
180
+ * callback at dispatch. This preserves argument-type discipline for
181
+ * parameterized host callbacks like
182
+ * `onSetImageSize(preset: "small" | "medium" | "large")`.
183
+ *
184
+ * Fixes the pre-fix bug where `mk()` cast every callback to `(() => void)`
185
+ * and invoked with zero arguments, leaving image-size / similar actions
186
+ * firing with `undefined` payloads at runtime. The `A` generic parameter
187
+ * MUST match the callback's argument type — callers supply it explicitly
188
+ * at the call site (TypeScript cannot infer from the narrow payload
189
+ * literal in a way that catches mismatch against the host signature).
190
+ */
191
+ function mkArg<A, K extends keyof EditorActionHostCallbacks>(opts: {
192
+ id: string;
193
+ label: string;
194
+ shortcut?: readonly ShortcutKey[];
195
+ group: ContextMenuGroupId;
196
+ targetKinds: readonly TargetKind[];
197
+ modes?: readonly EditorChromeMode[];
198
+ callback: K;
199
+ payload: A;
200
+ when?: (ctx: EditorActionDispatchContext) => boolean | "disabled";
201
+ }): EditorAction {
202
+ return {
203
+ id: opts.id,
204
+ label: opts.label,
205
+ ...(opts.shortcut ? { shortcut: opts.shortcut } : {}),
206
+ group: opts.group,
207
+ targetKinds: new Set(opts.targetKinds),
208
+ ...(opts.modes ? { modes: new Set(opts.modes) } : {}),
209
+ when: (ctx) => {
210
+ if (typeof ctx.host[opts.callback] !== "function") return false;
211
+ if (opts.when) return opts.when(ctx);
212
+ return true;
213
+ },
214
+ run: (ctx) => {
215
+ const fn = ctx.host[opts.callback] as ((arg: A) => void) | undefined;
216
+ fn?.(opts.payload);
217
+ ctx.dismiss();
218
+ },
219
+ };
220
+ }
221
+
222
+ export const EDITOR_ACTION_REGISTRY: readonly EditorAction[] = [
223
+ // -------- Clipboard (always available across every target kind) --------
224
+ mk({
225
+ id: "cut",
226
+ label: "Cut",
227
+ shortcut: ["Mod", "X"],
228
+ group: "clipboard",
229
+ targetKinds: [
230
+ "plain-text",
231
+ "table-cell",
232
+ "image",
233
+ "hyperlink",
234
+ "suggestion",
235
+ "comment-anchor",
236
+ "opaque-block",
237
+ "scope-anchor",
238
+ ],
239
+ callback: "onCut",
240
+ }),
241
+ mk({
242
+ id: "copy",
243
+ label: "Copy",
244
+ shortcut: ["Mod", "C"],
245
+ group: "clipboard",
246
+ targetKinds: [
247
+ "plain-text",
248
+ "table-cell",
249
+ "image",
250
+ "hyperlink",
251
+ "suggestion",
252
+ "comment-anchor",
253
+ "opaque-block",
254
+ "scope-anchor",
255
+ ],
256
+ callback: "onCopy",
257
+ }),
258
+ mk({
259
+ id: "paste",
260
+ label: "Paste",
261
+ shortcut: ["Mod", "V"],
262
+ group: "clipboard",
263
+ targetKinds: [
264
+ "plain-text",
265
+ "table-cell",
266
+ "hyperlink",
267
+ "suggestion",
268
+ "comment-anchor",
269
+ "scope-anchor",
270
+ ],
271
+ callback: "onPaste",
272
+ }),
273
+
274
+ // -------- Suggestion / tracked change --------
275
+ mk({
276
+ id: "accept-suggestion",
277
+ label: "Accept suggestion",
278
+ group: "suggestion",
279
+ targetKinds: ["suggestion"],
280
+ callback: "onAcceptSuggestion",
281
+ }),
282
+ mk({
283
+ id: "reject-suggestion",
284
+ label: "Reject suggestion",
285
+ group: "suggestion",
286
+ targetKinds: ["suggestion"],
287
+ callback: "onRejectSuggestion",
288
+ }),
289
+
290
+ // -------- Comment --------
291
+ mk({
292
+ id: "resolve-comment",
293
+ label: "Resolve comment",
294
+ group: "comment",
295
+ targetKinds: ["comment-anchor"],
296
+ callback: "onResolveComment",
297
+ }),
298
+ mk({
299
+ id: "reply-to-comment",
300
+ label: "Reply to comment",
301
+ group: "comment",
302
+ targetKinds: ["comment-anchor"],
303
+ callback: "onReplyToComment",
304
+ }),
305
+ mk({
306
+ id: "jump-to-comment-in-rail",
307
+ label: "Open in rail",
308
+ group: "comment",
309
+ targetKinds: ["comment-anchor"],
310
+ callback: "onJumpToCommentInRail",
311
+ }),
312
+
313
+ // -------- Table --------
314
+ // Chrome Closure Pass · Task 3 — table actions are split across the
315
+ // tier ladder per designsystem.md §6.9. The menu builder asks the
316
+ // registry for actions whose `targetKinds` overlap any of the
317
+ // resolved kinds (table-cell ⊂ table-row ⊂ table-column ⊂
318
+ // table-whole — each higher tier inherits the cell-level ops). The
319
+ // cell-level ops carry every table-* kind so they remain visible at
320
+ // every tier; the row-only / column-only / whole-table ops carry
321
+ // only the kinds that should expose them.
322
+
323
+ // ── Cell-level ops — visible at every tier ──
324
+ mk({
325
+ id: "table-insert-row-above",
326
+ label: "Insert row above",
327
+ group: "table",
328
+ targetKinds: ["table-cell", "table-row", "table-column", "table-whole"],
329
+ callback: "onInsertRowAbove",
330
+ }),
331
+ mk({
332
+ id: "table-insert-row-below",
333
+ label: "Insert row below",
334
+ group: "table",
335
+ targetKinds: ["table-cell", "table-row", "table-column", "table-whole"],
336
+ callback: "onInsertRowBelow",
337
+ }),
338
+ mk({
339
+ id: "table-insert-column-before",
340
+ label: "Insert column before",
341
+ group: "table",
342
+ targetKinds: ["table-cell", "table-row", "table-column", "table-whole"],
343
+ callback: "onInsertColumnBefore",
344
+ }),
345
+ mk({
346
+ id: "table-insert-column-after",
347
+ label: "Insert column after",
348
+ group: "table",
349
+ targetKinds: ["table-cell", "table-row", "table-column", "table-whole"],
350
+ callback: "onInsertColumnAfter",
351
+ }),
352
+ mk({
353
+ id: "table-merge-cells",
354
+ label: "Merge cells",
355
+ group: "table",
356
+ targetKinds: ["table-cell", "table-row", "table-column", "table-whole"],
357
+ callback: "onMergeCells",
358
+ }),
359
+ mk({
360
+ id: "table-split-cell",
361
+ label: "Split cell",
362
+ group: "table",
363
+ targetKinds: ["table-cell", "table-row", "table-column", "table-whole"],
364
+ callback: "onSplitCell",
365
+ }),
366
+ // ── Row-only — Delete row only when a row is selected (T3) ──
367
+ mk({
368
+ id: "table-delete-row",
369
+ label: "Delete row",
370
+ group: "table",
371
+ targetKinds: ["table-row", "table-whole"],
372
+ callback: "onDeleteRow",
373
+ }),
374
+ // ── Column-only — Delete column only when a column is selected (T4b) ──
375
+ mk({
376
+ id: "table-delete-column",
377
+ label: "Delete column",
378
+ group: "table",
379
+ targetKinds: ["table-column", "table-whole"],
380
+ callback: "onDeleteColumn",
381
+ }),
382
+ // ── Whole-table — properties / borders surface at any tier so
383
+ // they are reachable from a single right-click in a cell ──
384
+ mk({
385
+ id: "table-properties",
386
+ label: "Table properties…",
387
+ group: "table",
388
+ targetKinds: ["table-cell", "table-row", "table-column", "table-whole"],
389
+ callback: "onOpenTableProperties",
390
+ }),
391
+ mk({
392
+ id: "table-borders",
393
+ label: "Borders…",
394
+ group: "table",
395
+ targetKinds: ["table-cell", "table-row", "table-column", "table-whole"],
396
+ callback: "onOpenBorderPicker",
397
+ }),
398
+
399
+ // -------- Image --------
400
+ mk({
401
+ id: "image-replace",
402
+ label: "Replace image…",
403
+ group: "misc",
404
+ targetKinds: ["image"],
405
+ callback: "onReplaceImage",
406
+ }),
407
+ mk({
408
+ id: "image-alt-text",
409
+ label: "Edit alt text…",
410
+ group: "misc",
411
+ targetKinds: ["image"],
412
+ callback: "onEditImageAltText",
413
+ }),
414
+ mkArg<"small" | "medium" | "large", "onSetImageSize">({
415
+ id: "image-size-small",
416
+ label: "Small",
417
+ group: "misc",
418
+ targetKinds: ["image"],
419
+ callback: "onSetImageSize",
420
+ payload: "small",
421
+ }),
422
+ mkArg<"small" | "medium" | "large", "onSetImageSize">({
423
+ id: "image-size-medium",
424
+ label: "Medium",
425
+ group: "misc",
426
+ targetKinds: ["image"],
427
+ callback: "onSetImageSize",
428
+ payload: "medium",
429
+ }),
430
+ mkArg<"small" | "medium" | "large", "onSetImageSize">({
431
+ id: "image-size-large",
432
+ label: "Large",
433
+ group: "misc",
434
+ targetKinds: ["image"],
435
+ callback: "onSetImageSize",
436
+ payload: "large",
437
+ }),
438
+
439
+ // -------- Object (read-only info per DESIGN-EDITOR.md §6.10) --------
440
+ mk({
441
+ id: "object-info",
442
+ label: "Object info…",
443
+ group: "misc",
444
+ targetKinds: ["object"],
445
+ callback: "onOpenObjectInfo",
446
+ }),
447
+
448
+ // -------- Hyperlink --------
449
+ mk({
450
+ id: "hyperlink-edit",
451
+ label: "Edit link…",
452
+ group: "misc",
453
+ targetKinds: ["hyperlink"],
454
+ callback: "onEditHyperlink",
455
+ }),
456
+ mk({
457
+ id: "hyperlink-remove",
458
+ label: "Remove link",
459
+ group: "misc",
460
+ targetKinds: ["hyperlink"],
461
+ callback: "onRemoveHyperlink",
462
+ }),
463
+ mk({
464
+ id: "hyperlink-open",
465
+ label: "Open link",
466
+ group: "misc",
467
+ targetKinds: ["hyperlink"],
468
+ callback: "onOpenHyperlink",
469
+ }),
470
+
471
+ // -------- Workflow scope --------
472
+ mk({
473
+ id: "scope-open-card",
474
+ label: "Open scope card",
475
+ group: "misc",
476
+ targetKinds: ["scope-anchor"],
477
+ callback: "onOpenScopeCard",
478
+ modes: ["workflow", "review"],
479
+ }),
480
+ mk({
481
+ id: "scope-jump-in-rail",
482
+ label: "Open scope in rail",
483
+ group: "misc",
484
+ targetKinds: ["scope-anchor"],
485
+ callback: "onJumpToScopeInRail",
486
+ modes: ["workflow", "review"],
487
+ }),
488
+ mk({
489
+ id: "scope-mark-resolved",
490
+ label: "Mark scope resolved",
491
+ group: "misc",
492
+ targetKinds: ["scope-anchor"],
493
+ callback: "onMarkScopeResolved",
494
+ // Workflow-only — review posture inspects, doesn't mutate scope state.
495
+ modes: ["workflow"],
496
+ }),
497
+ ];
498
+
499
+ /**
500
+ * Result row from `resolveActionsForTarget`. Carries the evaluated
501
+ * `when()` verdict alongside the action so callers (e.g. the context-
502
+ * menu builder) don't re-evaluate the predicate a second time just to
503
+ * detect the `"disabled"` state.
504
+ */
505
+ export interface ResolvedEditorAction {
506
+ readonly action: EditorAction;
507
+ readonly disabled: boolean;
508
+ }
509
+
510
+ /**
511
+ * Query the registry for every action whose target set includes `kind`
512
+ * and whose mode filter (if any) matches the current composition mode.
513
+ * Each `when()` predicate runs once per resolution; the result includes
514
+ * a `disabled` flag so callers render disabled rows without a second
515
+ * evaluation.
516
+ *
517
+ * Pure — no side effects. The overload below preserves the legacy
518
+ * `readonly EditorAction[]` return shape for tests that don't need the
519
+ * disabled flag.
520
+ */
521
+ export function resolveActionsForTarget(
522
+ kind: TargetKind,
523
+ mode: EditorChromeMode,
524
+ host: EditorActionHostCallbacks,
525
+ ): readonly EditorAction[];
526
+ export function resolveActionsForTarget(
527
+ kind: TargetKind,
528
+ mode: EditorChromeMode,
529
+ host: EditorActionHostCallbacks,
530
+ options: { includeDisabled: true },
531
+ ): readonly ResolvedEditorAction[];
532
+ export function resolveActionsForTarget(
533
+ kind: TargetKind,
534
+ mode: EditorChromeMode,
535
+ host: EditorActionHostCallbacks,
536
+ options?: { includeDisabled?: boolean },
537
+ ): readonly EditorAction[] | readonly ResolvedEditorAction[] {
538
+ const ctx: EditorActionDispatchContext = {
539
+ composition: { mode },
540
+ host,
541
+ dismiss: () => {},
542
+ };
543
+ const resolved: ResolvedEditorAction[] = [];
544
+ for (const action of EDITOR_ACTION_REGISTRY) {
545
+ if (!action.targetKinds.has(kind)) continue;
546
+ if (action.modes && !action.modes.has(mode)) continue;
547
+ const verdict = action.when ? action.when(ctx) : true;
548
+ if (verdict === false) continue;
549
+ resolved.push({ action, disabled: verdict === "disabled" });
550
+ }
551
+ if (options?.includeDisabled) return resolved;
552
+ return resolved.map((r) => r.action);
553
+ }