@beyondwork/docx-react-component 1.0.29 → 1.0.30

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 (381) hide show
  1. package/package.json +65 -96
  2. package/src/README.md +85 -0
  3. package/src/api/README.md +26 -0
  4. package/src/api/public-types.ts +1952 -0
  5. package/src/api/session-state.ts +62 -0
  6. package/src/compare/diff-engine.ts +623 -0
  7. package/src/compare/export-redlines.ts +280 -0
  8. package/src/compare/index.ts +25 -0
  9. package/src/compare/snapshot.ts +97 -0
  10. package/src/component-inventory.md +99 -0
  11. package/src/core/README.md +10 -0
  12. package/src/core/commands/README.md +3 -0
  13. package/{dist/chunk-TJBP2K4T.js → src/core/commands/formatting-commands.ts} +536 -196
  14. package/src/core/commands/image-commands.ts +373 -0
  15. package/src/core/commands/index.ts +1879 -0
  16. package/src/core/commands/list-commands.ts +565 -0
  17. package/src/core/commands/paragraph-layout-commands.ts +339 -0
  18. package/src/core/commands/review-commands.ts +108 -0
  19. package/{dist/core/commands/section-layout-commands.cjs → src/core/commands/section-layout-commands.ts} +340 -137
  20. package/src/core/commands/structural-helpers.ts +309 -0
  21. package/{dist/core/commands/style-commands.cjs → src/core/commands/style-commands.ts} +113 -65
  22. package/src/core/commands/table-structure-commands.ts +854 -0
  23. package/{dist/chunk-UZXBISGO.js → src/core/commands/text-commands.ts} +142 -86
  24. package/src/core/schema/README.md +3 -0
  25. package/src/core/schema/text-schema.ts +516 -0
  26. package/src/core/search/search-text.ts +357 -0
  27. package/src/core/selection/README.md +3 -0
  28. package/src/core/selection/mapping.ts +289 -0
  29. package/src/core/selection/review-anchors.ts +183 -0
  30. package/src/core/state/README.md +3 -0
  31. package/src/core/state/editor-state.ts +892 -0
  32. package/src/core/state/text-transaction.ts +869 -0
  33. package/src/formats/xlsx/io/parse-shared-strings.ts +41 -0
  34. package/src/formats/xlsx/io/parse-sheet.ts +459 -0
  35. package/src/formats/xlsx/io/parse-styles.ts +59 -0
  36. package/src/formats/xlsx/io/parse-workbook.ts +75 -0
  37. package/src/formats/xlsx/io/serialize-shared-strings.ts +72 -0
  38. package/src/formats/xlsx/io/serialize-sheet.ts +333 -0
  39. package/src/formats/xlsx/io/serialize-styles.ts +98 -0
  40. package/src/formats/xlsx/io/serialize-workbook.ts +429 -0
  41. package/src/formats/xlsx/io/xlsx-session.ts +314 -0
  42. package/src/formats/xlsx/model/cell.ts +189 -0
  43. package/src/formats/xlsx/model/sheet.ts +326 -0
  44. package/src/formats/xlsx/model/styles.ts +118 -0
  45. package/src/formats/xlsx/model/workbook.ts +453 -0
  46. package/src/formats/xlsx/runtime/cell-commands.ts +567 -0
  47. package/src/formats/xlsx/runtime/sheet-commands.ts +206 -0
  48. package/src/formats/xlsx/runtime/workbook-runtime.ts +177 -0
  49. package/src/formats/xlsx/runtime/workbook-transaction.ts +822 -0
  50. package/src/index.ts +142 -0
  51. package/src/io/README.md +10 -0
  52. package/src/io/docx-session.ts +3175 -0
  53. package/src/io/export/README.md +3 -0
  54. package/src/io/export/export-session.ts +220 -0
  55. package/src/io/export/minimal-docx.ts +115 -0
  56. package/src/io/export/reattach-preserved-parts.ts +54 -0
  57. package/src/io/export/serialize-comments.ts +947 -0
  58. package/src/io/export/serialize-footnotes.ts +394 -0
  59. package/src/io/export/serialize-headers-footers.ts +368 -0
  60. package/src/io/export/serialize-main-document.ts +1342 -0
  61. package/src/io/export/serialize-numbering.ts +218 -0
  62. package/src/io/export/serialize-revisions.ts +389 -0
  63. package/src/io/export/serialize-runtime-revisions.ts +463 -0
  64. package/src/io/export/serialize-tables.ts +174 -0
  65. package/src/io/export/split-review-boundaries.ts +356 -0
  66. package/src/io/export/split-story-blocks-for-runtime-revisions.ts +252 -0
  67. package/src/io/export/table-properties-xml.ts +318 -0
  68. package/src/io/normalize/README.md +3 -0
  69. package/src/io/normalize/normalize-text.ts +670 -0
  70. package/src/io/ooxml/README.md +3 -0
  71. package/src/io/ooxml/highlight-colors.ts +39 -0
  72. package/src/io/ooxml/numbering-sentinels.ts +44 -0
  73. package/src/io/ooxml/parse-comments.ts +852 -0
  74. package/src/io/ooxml/parse-complex-content.ts +287 -0
  75. package/src/io/ooxml/parse-fields.ts +834 -0
  76. package/src/io/ooxml/parse-footnotes.ts +952 -0
  77. package/src/io/ooxml/parse-headers-footers.ts +1212 -0
  78. package/src/io/ooxml/parse-inline-media.ts +461 -0
  79. package/src/io/ooxml/parse-main-document.ts +2947 -0
  80. package/src/io/ooxml/parse-numbering.ts +747 -0
  81. package/src/io/ooxml/parse-revisions.ts +1045 -0
  82. package/src/io/ooxml/parse-settings.ts +184 -0
  83. package/src/io/ooxml/parse-shapes.ts +296 -0
  84. package/src/io/ooxml/parse-styles.ts +639 -0
  85. package/src/io/ooxml/parse-tables.ts +627 -0
  86. package/src/io/ooxml/parse-theme.ts +346 -0
  87. package/src/io/ooxml/part-manifest.ts +136 -0
  88. package/src/io/ooxml/revision-boundaries.ts +475 -0
  89. package/src/io/ooxml/workflow-payload.ts +544 -0
  90. package/src/io/opc/README.md +3 -0
  91. package/src/io/opc/corrupt-package.ts +166 -0
  92. package/src/io/opc/docx-package.ts +74 -0
  93. package/src/io/opc/package-reader.ts +325 -0
  94. package/src/io/opc/package-writer.ts +273 -0
  95. package/src/io/source-package-provenance.ts +241 -0
  96. package/{dist/chunk-RMH72RZI.js → src/legal/bookmarks.ts} +130 -44
  97. package/src/legal/cross-references.ts +414 -0
  98. package/src/legal/defined-terms.ts +203 -0
  99. package/src/legal/index.ts +32 -0
  100. package/src/legal/signature-blocks.ts +259 -0
  101. package/src/model/README.md +3 -0
  102. package/src/model/canonical-document.ts +2722 -0
  103. package/src/model/cds-1.0.0.ts +212 -0
  104. package/src/model/snapshot.ts +760 -0
  105. package/src/preservation/README.md +3 -0
  106. package/src/preservation/markup-compatibility.ts +48 -0
  107. package/src/preservation/opaque-fragment-store.ts +89 -0
  108. package/src/preservation/opaque-region.ts +233 -0
  109. package/src/preservation/package-preservation.ts +113 -0
  110. package/src/preservation/preserved-part-manifest.ts +56 -0
  111. package/src/preservation/relationship-retention.ts +57 -0
  112. package/src/preservation/store.ts +255 -0
  113. package/src/review/README.md +16 -0
  114. package/src/review/store/README.md +3 -0
  115. package/src/review/store/comment-anchors.ts +70 -0
  116. package/src/review/store/comment-remapping.ts +154 -0
  117. package/src/review/store/comment-store.ts +349 -0
  118. package/src/review/store/comment-thread.ts +109 -0
  119. package/src/review/store/revision-actions.ts +423 -0
  120. package/src/review/store/revision-store.ts +323 -0
  121. package/src/review/store/revision-types.ts +182 -0
  122. package/src/review/store/runtime-comment-store.ts +43 -0
  123. package/src/runtime/README.md +3 -0
  124. package/src/runtime/ai-action-policy.ts +764 -0
  125. package/src/runtime/context-analytics.ts +824 -0
  126. package/src/runtime/document-layout.ts +332 -0
  127. package/src/runtime/document-locations.ts +521 -0
  128. package/src/runtime/document-navigation.ts +616 -0
  129. package/src/runtime/document-outline.ts +440 -0
  130. package/src/runtime/document-runtime.ts +4055 -0
  131. package/src/runtime/document-search.ts +145 -0
  132. package/src/runtime/event-refresh-hints.ts +137 -0
  133. package/src/runtime/numbering-prefix.ts +244 -0
  134. package/src/runtime/page-layout-estimation.ts +305 -0
  135. package/src/runtime/read-only-diagnostics-runtime.ts +241 -0
  136. package/src/runtime/resolved-numbering-geometry.ts +293 -0
  137. package/src/runtime/review-runtime.ts +44 -0
  138. package/src/runtime/revision-runtime.ts +107 -0
  139. package/src/runtime/session-capabilities.ts +192 -0
  140. package/src/runtime/story-context.ts +164 -0
  141. package/src/runtime/story-targeting.ts +162 -0
  142. package/src/runtime/suggestions-snapshot.ts +137 -0
  143. package/src/runtime/surface-projection.ts +1553 -0
  144. package/src/runtime/table-commands.ts +173 -0
  145. package/src/runtime/table-schema.ts +309 -0
  146. package/src/runtime/table-style-resolver.ts +409 -0
  147. package/src/runtime/view-state.ts +493 -0
  148. package/src/runtime/virtualized-rendering.ts +258 -0
  149. package/src/runtime/workflow-markup.ts +393 -0
  150. package/src/ui/README.md +30 -0
  151. package/src/ui/WordReviewEditor.tsx +5268 -0
  152. package/src/ui/browser-export.ts +52 -0
  153. package/src/ui/comments/README.md +3 -0
  154. package/src/ui/compatibility/README.md +3 -0
  155. package/src/ui/editor-command-bag.ts +127 -0
  156. package/src/ui/editor-runtime-boundary.ts +1558 -0
  157. package/src/ui/editor-shell-view.tsx +144 -0
  158. package/src/ui/editor-surface/README.md +3 -0
  159. package/src/ui/editor-surface-controller.tsx +66 -0
  160. package/src/ui/headless/comment-decoration-model.ts +124 -0
  161. package/src/ui/headless/preserve-editor-selection.ts +5 -0
  162. package/src/ui/headless/revision-decoration-model.ts +128 -0
  163. package/src/ui/headless/selection-helpers.ts +54 -0
  164. package/src/ui/headless/selection-tool-context.ts +19 -0
  165. package/src/ui/headless/selection-tool-resolver.ts +752 -0
  166. package/src/ui/headless/selection-tool-types.ts +129 -0
  167. package/src/ui/headless/selection-toolbar-model.ts +11 -0
  168. package/src/ui/headless/use-editor-keyboard.ts +103 -0
  169. package/src/ui/review/README.md +3 -0
  170. package/src/ui/runtime-shortcut-dispatch.ts +365 -0
  171. package/src/ui/runtime-snapshot-selectors.ts +197 -0
  172. package/src/ui/shared/revision-filters.ts +31 -0
  173. package/src/ui/status/README.md +3 -0
  174. package/src/ui/theme/README.md +3 -0
  175. package/src/ui/toolbar/README.md +3 -0
  176. package/src/ui/workflow-surface-blocked-rails.ts +94 -0
  177. package/src/ui-tailwind/chrome/chrome-preset-model.ts +107 -0
  178. package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +15 -0
  179. package/src/ui-tailwind/chrome/review-queue-bar.tsx +97 -0
  180. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +64 -0
  181. package/src/ui-tailwind/chrome/tw-context-analytics-summary.tsx +122 -0
  182. package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +121 -0
  183. package/src/ui-tailwind/chrome/tw-layout-panel.tsx +114 -0
  184. package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +30 -0
  185. package/src/ui-tailwind/chrome/tw-page-ruler.tsx +365 -0
  186. package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +23 -0
  187. package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +35 -0
  188. package/src/ui-tailwind/chrome/tw-selection-tool-formatting.tsx +37 -0
  189. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +298 -0
  190. package/src/ui-tailwind/chrome/tw-selection-tool-structure.tsx +116 -0
  191. package/src/ui-tailwind/chrome/tw-selection-tool-suggestion.tsx +29 -0
  192. package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +27 -0
  193. package/src/ui-tailwind/chrome/tw-selection-toolbar.tsx +186 -0
  194. package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +139 -0
  195. package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +200 -0
  196. package/src/ui-tailwind/chrome/tw-unsaved-modal.tsx +58 -0
  197. package/src/ui-tailwind/chrome/use-before-unload.ts +20 -0
  198. package/src/ui-tailwind/editor-surface/perf-probe.ts +179 -0
  199. package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +189 -0
  200. package/src/ui-tailwind/editor-surface/pm-contextual-ui.ts +31 -0
  201. package/src/ui-tailwind/editor-surface/pm-decorations.ts +411 -0
  202. package/src/ui-tailwind/editor-surface/pm-position-map.ts +123 -0
  203. package/src/ui-tailwind/editor-surface/pm-schema.ts +927 -0
  204. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +567 -0
  205. package/src/ui-tailwind/editor-surface/search-plugin.ts +168 -0
  206. package/src/ui-tailwind/editor-surface/surface-build-keys.ts +65 -0
  207. package/src/ui-tailwind/editor-surface/tw-caret.tsx +12 -0
  208. package/src/ui-tailwind/editor-surface/tw-editor-surface.tsx +150 -0
  209. package/src/ui-tailwind/editor-surface/tw-inline-token.tsx +129 -0
  210. package/src/ui-tailwind/editor-surface/tw-opaque-block.tsx +58 -0
  211. package/src/ui-tailwind/editor-surface/tw-paragraph-block.tsx +151 -0
  212. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +1047 -0
  213. package/src/ui-tailwind/editor-surface/tw-segment-view.tsx +111 -0
  214. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +503 -0
  215. package/src/ui-tailwind/index.ts +62 -0
  216. package/src/ui-tailwind/page-chrome-model.ts +27 -0
  217. package/src/ui-tailwind/review/tw-comment-sidebar.tsx +406 -0
  218. package/src/ui-tailwind/review/tw-health-panel.tsx +149 -0
  219. package/src/ui-tailwind/review/tw-review-rail.tsx +122 -0
  220. package/src/ui-tailwind/review/tw-revision-sidebar.tsx +164 -0
  221. package/src/ui-tailwind/status/tw-status-bar.tsx +65 -0
  222. package/{dist → src}/ui-tailwind/theme/editor-theme.css +58 -40
  223. package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +52 -0
  224. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +1133 -0
  225. package/src/ui-tailwind/tw-review-workspace.tsx +1460 -0
  226. package/src/validation/README.md +3 -0
  227. package/src/validation/compatibility-engine.ts +878 -0
  228. package/src/validation/compatibility-report.ts +161 -0
  229. package/src/validation/diagnostics.ts +204 -0
  230. package/src/validation/docx-comment-proof.ts +720 -0
  231. package/src/validation/import-diagnostics.ts +128 -0
  232. package/src/validation/low-priority-word-surfaces.ts +373 -0
  233. package/dist/canonical-document-BLEbzL2J.d.cts +0 -844
  234. package/dist/canonical-document-BLEbzL2J.d.ts +0 -844
  235. package/dist/chunk-2FJS5GZM.js +0 -763
  236. package/dist/chunk-2FJS5GZM.js.map +0 -1
  237. package/dist/chunk-2OQBZS3F.js +0 -446
  238. package/dist/chunk-2OQBZS3F.js.map +0 -1
  239. package/dist/chunk-2S7W4KFO.js +0 -127
  240. package/dist/chunk-2S7W4KFO.js.map +0 -1
  241. package/dist/chunk-2TG72QSW.js +0 -3874
  242. package/dist/chunk-2TG72QSW.js.map +0 -1
  243. package/dist/chunk-36QNIZBO.js +0 -532
  244. package/dist/chunk-36QNIZBO.js.map +0 -1
  245. package/dist/chunk-4AQOYAW4.js +0 -3069
  246. package/dist/chunk-4AQOYAW4.js.map +0 -1
  247. package/dist/chunk-4D5EWJ3P.js +0 -77
  248. package/dist/chunk-4D5EWJ3P.js.map +0 -1
  249. package/dist/chunk-5FN54NDH.js +0 -2257
  250. package/dist/chunk-5FN54NDH.js.map +0 -1
  251. package/dist/chunk-BOYGQYRQ.js +0 -7306
  252. package/dist/chunk-BOYGQYRQ.js.map +0 -1
  253. package/dist/chunk-CN3XMECL.js +0 -212
  254. package/dist/chunk-CN3XMECL.js.map +0 -1
  255. package/dist/chunk-EBI3BX6U.js +0 -164
  256. package/dist/chunk-EBI3BX6U.js.map +0 -1
  257. package/dist/chunk-EILUG3VB.js +0 -1275
  258. package/dist/chunk-EILUG3VB.js.map +0 -1
  259. package/dist/chunk-FUDY333O.js +0 -70
  260. package/dist/chunk-FUDY333O.js.map +0 -1
  261. package/dist/chunk-GBVOWFIK.js +0 -1237
  262. package/dist/chunk-GBVOWFIK.js.map +0 -1
  263. package/dist/chunk-H4TQ3H3Y.js +0 -262
  264. package/dist/chunk-H4TQ3H3Y.js.map +0 -1
  265. package/dist/chunk-JGB3IXZO.js +0 -189
  266. package/dist/chunk-JGB3IXZO.js.map +0 -1
  267. package/dist/chunk-KD2QRQPY.js +0 -4342
  268. package/dist/chunk-KD2QRQPY.js.map +0 -1
  269. package/dist/chunk-KLMXQVYK.js +0 -369
  270. package/dist/chunk-KLMXQVYK.js.map +0 -1
  271. package/dist/chunk-KZUG5KFQ.js +0 -214
  272. package/dist/chunk-KZUG5KFQ.js.map +0 -1
  273. package/dist/chunk-QDAQ4CJU.js +0 -345
  274. package/dist/chunk-QDAQ4CJU.js.map +0 -1
  275. package/dist/chunk-RMH72RZI.js.map +0 -1
  276. package/dist/chunk-SWKWQZXM.js +0 -117
  277. package/dist/chunk-SWKWQZXM.js.map +0 -1
  278. package/dist/chunk-TJBP2K4T.js.map +0 -1
  279. package/dist/chunk-TLCEAQDQ.js +0 -542
  280. package/dist/chunk-TLCEAQDQ.js.map +0 -1
  281. package/dist/chunk-UZXBISGO.js.map +0 -1
  282. package/dist/chunk-WGBAKP3Q.js +0 -3220
  283. package/dist/chunk-WGBAKP3Q.js.map +0 -1
  284. package/dist/compare/index.cjs +0 -5475
  285. package/dist/compare/index.cjs.map +0 -1
  286. package/dist/compare/index.d.cts +0 -114
  287. package/dist/compare/index.d.ts +0 -114
  288. package/dist/compare/index.js +0 -731
  289. package/dist/compare/index.js.map +0 -1
  290. package/dist/core/commands/formatting-commands.cjs +0 -828
  291. package/dist/core/commands/formatting-commands.cjs.map +0 -1
  292. package/dist/core/commands/formatting-commands.d.cts +0 -63
  293. package/dist/core/commands/formatting-commands.d.ts +0 -63
  294. package/dist/core/commands/formatting-commands.js +0 -37
  295. package/dist/core/commands/formatting-commands.js.map +0 -1
  296. package/dist/core/commands/image-commands.cjs +0 -2023
  297. package/dist/core/commands/image-commands.cjs.map +0 -1
  298. package/dist/core/commands/image-commands.d.cts +0 -58
  299. package/dist/core/commands/image-commands.d.ts +0 -58
  300. package/dist/core/commands/image-commands.js +0 -18
  301. package/dist/core/commands/image-commands.js.map +0 -1
  302. package/dist/core/commands/section-layout-commands.cjs.map +0 -1
  303. package/dist/core/commands/section-layout-commands.d.cts +0 -62
  304. package/dist/core/commands/section-layout-commands.d.ts +0 -62
  305. package/dist/core/commands/section-layout-commands.js +0 -21
  306. package/dist/core/commands/section-layout-commands.js.map +0 -1
  307. package/dist/core/commands/style-commands.cjs.map +0 -1
  308. package/dist/core/commands/style-commands.d.cts +0 -13
  309. package/dist/core/commands/style-commands.d.ts +0 -13
  310. package/dist/core/commands/style-commands.js +0 -9
  311. package/dist/core/commands/style-commands.js.map +0 -1
  312. package/dist/core/commands/table-structure-commands.cjs +0 -1883
  313. package/dist/core/commands/table-structure-commands.cjs.map +0 -1
  314. package/dist/core/commands/table-structure-commands.d.cts +0 -59
  315. package/dist/core/commands/table-structure-commands.d.ts +0 -59
  316. package/dist/core/commands/table-structure-commands.js +0 -12
  317. package/dist/core/commands/table-structure-commands.js.map +0 -1
  318. package/dist/core/commands/text-commands.cjs +0 -2391
  319. package/dist/core/commands/text-commands.cjs.map +0 -1
  320. package/dist/core/commands/text-commands.d.cts +0 -24
  321. package/dist/core/commands/text-commands.d.ts +0 -24
  322. package/dist/core/commands/text-commands.js +0 -28
  323. package/dist/core/commands/text-commands.js.map +0 -1
  324. package/dist/core/selection/mapping.cjs +0 -200
  325. package/dist/core/selection/mapping.cjs.map +0 -1
  326. package/dist/core/selection/mapping.d.cts +0 -2
  327. package/dist/core/selection/mapping.d.ts +0 -2
  328. package/dist/core/selection/mapping.js +0 -31
  329. package/dist/core/selection/mapping.js.map +0 -1
  330. package/dist/core/state/editor-state.cjs +0 -2278
  331. package/dist/core/state/editor-state.cjs.map +0 -1
  332. package/dist/core/state/editor-state.d.cts +0 -2
  333. package/dist/core/state/editor-state.d.ts +0 -2
  334. package/dist/core/state/editor-state.js +0 -26
  335. package/dist/core/state/editor-state.js.map +0 -1
  336. package/dist/index.cjs +0 -38553
  337. package/dist/index.cjs.map +0 -1
  338. package/dist/index.d.cts +0 -15
  339. package/dist/index.d.ts +0 -15
  340. package/dist/index.js +0 -7856
  341. package/dist/index.js.map +0 -1
  342. package/dist/io/docx-session.cjs +0 -16236
  343. package/dist/io/docx-session.cjs.map +0 -1
  344. package/dist/io/docx-session.d.cts +0 -21
  345. package/dist/io/docx-session.d.ts +0 -21
  346. package/dist/io/docx-session.js +0 -18
  347. package/dist/io/docx-session.js.map +0 -1
  348. package/dist/legal/index.cjs +0 -3900
  349. package/dist/legal/index.cjs.map +0 -1
  350. package/dist/legal/index.d.cts +0 -86
  351. package/dist/legal/index.d.ts +0 -86
  352. package/dist/legal/index.js +0 -616
  353. package/dist/legal/index.js.map +0 -1
  354. package/dist/public-types-7ZL_94cz.d.ts +0 -1573
  355. package/dist/public-types-CeMaDueh.d.cts +0 -1573
  356. package/dist/public-types.cjs +0 -19
  357. package/dist/public-types.cjs.map +0 -1
  358. package/dist/public-types.d.cts +0 -2
  359. package/dist/public-types.d.ts +0 -2
  360. package/dist/public-types.js +0 -1
  361. package/dist/public-types.js.map +0 -1
  362. package/dist/runtime/document-runtime.cjs +0 -11140
  363. package/dist/runtime/document-runtime.cjs.map +0 -1
  364. package/dist/runtime/document-runtime.d.cts +0 -231
  365. package/dist/runtime/document-runtime.d.ts +0 -231
  366. package/dist/runtime/document-runtime.js +0 -21
  367. package/dist/runtime/document-runtime.js.map +0 -1
  368. package/dist/structural-helpers-CilgOVhh.d.cts +0 -10
  369. package/dist/structural-helpers-q0Gd-eBN.d.ts +0 -10
  370. package/dist/ui-tailwind/editor-surface/search-plugin.cjs +0 -313
  371. package/dist/ui-tailwind/editor-surface/search-plugin.cjs.map +0 -1
  372. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +0 -67
  373. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +0 -67
  374. package/dist/ui-tailwind/editor-surface/search-plugin.js +0 -23
  375. package/dist/ui-tailwind/editor-surface/search-plugin.js.map +0 -1
  376. package/dist/ui-tailwind/index.cjs +0 -4833
  377. package/dist/ui-tailwind/index.cjs.map +0 -1
  378. package/dist/ui-tailwind/index.d.cts +0 -617
  379. package/dist/ui-tailwind/index.d.ts +0 -617
  380. package/dist/ui-tailwind/index.js +0 -575
  381. package/dist/ui-tailwind/index.js.map +0 -1
@@ -0,0 +1,197 @@
1
+ import { useRef, useSyncExternalStore } from "react";
2
+ import type {
3
+ DocumentNavigationSnapshot,
4
+ RuntimeRenderSnapshot,
5
+ } from "../api/public-types.ts";
6
+
7
+ export interface RuntimeSnapshotSource {
8
+ subscribe(listener: () => void): () => void;
9
+ getRenderSnapshot(): RuntimeRenderSnapshot;
10
+ }
11
+
12
+ export interface RuntimeValueSource<T> {
13
+ subscribe(listener: () => void): () => void;
14
+ getValue(): T;
15
+ }
16
+
17
+ export interface ToolbarSlice {
18
+ commandState: RuntimeRenderSnapshot["commandState"];
19
+ isDirty: RuntimeRenderSnapshot["isDirty"];
20
+ isReady: RuntimeRenderSnapshot["isReady"];
21
+ readOnly: RuntimeRenderSnapshot["readOnly"];
22
+ fatalError: RuntimeRenderSnapshot["fatalError"];
23
+ }
24
+
25
+ export interface SurfaceSlice {
26
+ revisionToken: RuntimeRenderSnapshot["revisionToken"];
27
+ selection: RuntimeRenderSnapshot["selection"];
28
+ activeStory: RuntimeRenderSnapshot["activeStory"];
29
+ surface: RuntimeRenderSnapshot["surface"];
30
+ }
31
+
32
+ export interface ReviewSlice {
33
+ comments: RuntimeRenderSnapshot["comments"];
34
+ trackedChanges: RuntimeRenderSnapshot["trackedChanges"];
35
+ compatibility: RuntimeRenderSnapshot["compatibility"];
36
+ }
37
+
38
+ export interface ViewSlice {
39
+ documentMode: RuntimeRenderSnapshot["documentMode"];
40
+ activeStory: RuntimeRenderSnapshot["activeStory"];
41
+ pageLayout: RuntimeRenderSnapshot["pageLayout"];
42
+ }
43
+
44
+ export interface StatusSlice {
45
+ warnings: RuntimeRenderSnapshot["warnings"];
46
+ fatalError: RuntimeRenderSnapshot["fatalError"];
47
+ isDirty: RuntimeRenderSnapshot["isDirty"];
48
+ documentStats: RuntimeRenderSnapshot["documentStats"];
49
+ protectionSnapshot: RuntimeRenderSnapshot["protectionSnapshot"];
50
+ }
51
+
52
+ export interface NavigationSlice {
53
+ documentNavigation: DocumentNavigationSnapshot | undefined;
54
+ }
55
+
56
+ export interface MetaSlice {
57
+ documentId: RuntimeRenderSnapshot["documentId"];
58
+ sessionId: RuntimeRenderSnapshot["sessionId"];
59
+ sourceLabel: RuntimeRenderSnapshot["sourceLabel"];
60
+ }
61
+
62
+ export function selectToolbarSlice(snapshot: RuntimeRenderSnapshot): ToolbarSlice {
63
+ return {
64
+ commandState: snapshot.commandState,
65
+ isDirty: snapshot.isDirty,
66
+ isReady: snapshot.isReady,
67
+ readOnly: snapshot.readOnly,
68
+ fatalError: snapshot.fatalError,
69
+ };
70
+ }
71
+
72
+ export function selectSurfaceSlice(snapshot: RuntimeRenderSnapshot): SurfaceSlice {
73
+ return {
74
+ revisionToken: snapshot.revisionToken,
75
+ selection: snapshot.selection,
76
+ activeStory: snapshot.activeStory,
77
+ surface: snapshot.surface,
78
+ };
79
+ }
80
+
81
+ export function selectReviewSlice(snapshot: RuntimeRenderSnapshot): ReviewSlice {
82
+ return {
83
+ comments: snapshot.comments,
84
+ trackedChanges: snapshot.trackedChanges,
85
+ compatibility: snapshot.compatibility,
86
+ };
87
+ }
88
+
89
+ export function selectViewSlice(snapshot: RuntimeRenderSnapshot): ViewSlice {
90
+ return {
91
+ documentMode: snapshot.documentMode,
92
+ activeStory: snapshot.activeStory,
93
+ pageLayout: snapshot.pageLayout,
94
+ };
95
+ }
96
+
97
+ export function selectStatusSlice(snapshot: RuntimeRenderSnapshot): StatusSlice {
98
+ return {
99
+ warnings: snapshot.warnings,
100
+ fatalError: snapshot.fatalError,
101
+ isDirty: snapshot.isDirty,
102
+ documentStats: snapshot.documentStats,
103
+ protectionSnapshot: snapshot.protectionSnapshot,
104
+ };
105
+ }
106
+
107
+ export function selectNavigationSlice(
108
+ documentNavigation?: DocumentNavigationSnapshot,
109
+ ): NavigationSlice {
110
+ return {
111
+ documentNavigation,
112
+ };
113
+ }
114
+
115
+ export function selectMetaSlice(snapshot: RuntimeRenderSnapshot): MetaSlice {
116
+ return {
117
+ documentId: snapshot.documentId,
118
+ sessionId: snapshot.sessionId,
119
+ sourceLabel: snapshot.sourceLabel,
120
+ };
121
+ }
122
+
123
+ export function shallowEqualRecord<T extends object>(
124
+ left: T,
125
+ right: T,
126
+ ): boolean {
127
+ const leftRecord = left as Record<string, unknown>;
128
+ const rightRecord = right as Record<string, unknown>;
129
+ const leftKeys = Object.keys(left);
130
+ const rightKeys = Object.keys(right);
131
+ if (leftKeys.length !== rightKeys.length) {
132
+ return false;
133
+ }
134
+
135
+ for (const key of leftKeys) {
136
+ if (leftRecord[key] !== rightRecord[key]) {
137
+ return false;
138
+ }
139
+ }
140
+
141
+ return true;
142
+ }
143
+
144
+ export function useRuntimeSnapshotSlice<T>(
145
+ runtime: RuntimeSnapshotSource | null,
146
+ fallbackSnapshot: RuntimeRenderSnapshot,
147
+ selector: (snapshot: RuntimeRenderSnapshot) => T,
148
+ isEqual: (left: T, right: T) => boolean = Object.is,
149
+ ): T {
150
+ const cachedSelectionRef = useRef<T>(selector(fallbackSnapshot));
151
+ return useSyncExternalStore(
152
+ (listener) => runtime?.subscribe(listener) ?? (() => undefined),
153
+ () => {
154
+ const next = selector(runtime?.getRenderSnapshot() ?? fallbackSnapshot);
155
+ if (isEqual(cachedSelectionRef.current, next)) {
156
+ return cachedSelectionRef.current;
157
+ }
158
+ cachedSelectionRef.current = next;
159
+ return next;
160
+ },
161
+ () => {
162
+ const next = selector(runtime?.getRenderSnapshot() ?? fallbackSnapshot);
163
+ if (isEqual(cachedSelectionRef.current, next)) {
164
+ return cachedSelectionRef.current;
165
+ }
166
+ cachedSelectionRef.current = next;
167
+ return next;
168
+ },
169
+ );
170
+ }
171
+
172
+ export function useRuntimeValue<T>(
173
+ source: RuntimeValueSource<T> | null,
174
+ fallbackValue: T,
175
+ isEqual: (left: T, right: T) => boolean = Object.is,
176
+ ): T {
177
+ const cachedValueRef = useRef<T>(fallbackValue);
178
+ return useSyncExternalStore(
179
+ (listener) => source?.subscribe(listener) ?? (() => undefined),
180
+ () => {
181
+ const next = source?.getValue() ?? fallbackValue;
182
+ if (isEqual(cachedValueRef.current, next)) {
183
+ return cachedValueRef.current;
184
+ }
185
+ cachedValueRef.current = next;
186
+ return next;
187
+ },
188
+ () => {
189
+ const next = source?.getValue() ?? fallbackValue;
190
+ if (isEqual(cachedValueRef.current, next)) {
191
+ return cachedValueRef.current;
192
+ }
193
+ cachedValueRef.current = next;
194
+ return next;
195
+ },
196
+ );
197
+ }
@@ -0,0 +1,31 @@
1
+ import type { RuntimeRenderSnapshot } from "../../api/public-types";
2
+
3
+ type Revision = RuntimeRenderSnapshot["trackedChanges"]["revisions"][number];
4
+ type MarkupDisplay = "clean" | "simple" | "all";
5
+
6
+ export function selectVisibleRevisions(
7
+ revisions: readonly Revision[],
8
+ markupDisplay: MarkupDisplay,
9
+ ): Revision[] {
10
+ switch (markupDisplay) {
11
+ case "clean":
12
+ case "simple":
13
+ return revisions.filter(
14
+ (revision) =>
15
+ revision.status === "active" && revision.actionability === "actionable",
16
+ );
17
+ case "all":
18
+ return [...revisions];
19
+ }
20
+ }
21
+
22
+ export function describeEmptyRevisionState(
23
+ markupDisplay: MarkupDisplay,
24
+ totalCount: number,
25
+ ): string {
26
+ if ((markupDisplay === "clean" || markupDisplay === "simple") && totalCount > 0) {
27
+ return "Simple markup keeps the rail focused on actionable live changes. Switch to All to inspect preserve-only or historical revision records.";
28
+ }
29
+
30
+ return "Runtime-backed change cards will appear here when tracked changes are present.";
31
+ }
@@ -0,0 +1,3 @@
1
+ # Status UI
2
+
3
+ Dirty state, autosave state, import/export progress, and validation status surfaces belong here.
@@ -0,0 +1,3 @@
1
+ # Theme
2
+
3
+ Design tokens, CSS variable mapping, and host-theme integration belong here.
@@ -0,0 +1,3 @@
1
+ # Toolbar
2
+
3
+ The compact command toolbar and contextual editor controls belong here.
@@ -0,0 +1,94 @@
1
+ import type {
2
+ EditorStoryTarget,
3
+ RuntimeRenderSnapshot,
4
+ SurfaceBlockSnapshot,
5
+ WorkflowBlockedCommandReason,
6
+ WorkflowMarkupSnapshot,
7
+ } from "../api/public-types";
8
+
9
+ export function deriveVisibleWorkflowBlockedRails(
10
+ surface: RuntimeRenderSnapshot["surface"] | undefined,
11
+ markupSnapshot: WorkflowMarkupSnapshot | null,
12
+ ): WorkflowBlockedCommandReason[] {
13
+ if (!surface || !markupSnapshot) {
14
+ return [];
15
+ }
16
+
17
+ const visibleFragments = collectVisibleOpaqueFragmentStoryKeys(surface);
18
+ return markupSnapshot.opaqueFragments
19
+ .filter((fragment) =>
20
+ visibleFragments.has(
21
+ createOpaqueFragmentStoryKey(fragment.fragmentId, fragment.storyTarget ?? { kind: "main" }),
22
+ ),
23
+ )
24
+ .map((fragment) => ({
25
+ code: fragment.blockedReasonCode,
26
+ message: fragment.detail,
27
+ anchor: fragment.anchor,
28
+ storyTarget: fragment.storyTarget,
29
+ }));
30
+ }
31
+
32
+ function collectVisibleOpaqueFragmentStoryKeys(
33
+ surface: NonNullable<RuntimeRenderSnapshot["surface"]>,
34
+ ): Set<string> {
35
+ const keys = new Set<string>();
36
+ collectVisibleOpaqueFragmentStoryKeysInBlocks(surface.blocks, { kind: "main" }, keys);
37
+ for (const story of surface.secondaryStories) {
38
+ collectVisibleOpaqueFragmentStoryKeysInBlocks(story.blocks, story.target, keys);
39
+ }
40
+ return keys;
41
+ }
42
+
43
+ function collectVisibleOpaqueFragmentStoryKeysInBlocks(
44
+ blocks: readonly SurfaceBlockSnapshot[],
45
+ storyTarget: EditorStoryTarget,
46
+ keys: Set<string>,
47
+ ): void {
48
+ for (const block of blocks) {
49
+ if (block.kind === "paragraph") {
50
+ for (const segment of block.segments) {
51
+ if (segment.kind === "opaque_inline") {
52
+ keys.add(createOpaqueFragmentStoryKey(segment.fragmentId, storyTarget));
53
+ }
54
+ }
55
+ continue;
56
+ }
57
+
58
+ if (block.kind === "table") {
59
+ for (const row of block.rows) {
60
+ for (const cell of row.cells) {
61
+ collectVisibleOpaqueFragmentStoryKeysInBlocks(cell.content, storyTarget, keys);
62
+ }
63
+ }
64
+ continue;
65
+ }
66
+
67
+ if (block.kind === "sdt_block") {
68
+ collectVisibleOpaqueFragmentStoryKeysInBlocks(block.children, storyTarget, keys);
69
+ continue;
70
+ }
71
+
72
+ keys.add(createOpaqueFragmentStoryKey(block.fragmentId, storyTarget));
73
+ }
74
+ }
75
+
76
+ function createOpaqueFragmentStoryKey(
77
+ fragmentId: string,
78
+ storyTarget: EditorStoryTarget,
79
+ ): string {
80
+ return `${fragmentId}:${serializeStoryTargetKey(storyTarget)}`;
81
+ }
82
+
83
+ function serializeStoryTargetKey(storyTarget: EditorStoryTarget): string {
84
+ switch (storyTarget.kind) {
85
+ case "main":
86
+ return "main";
87
+ case "header":
88
+ case "footer":
89
+ return `${storyTarget.kind}:${storyTarget.relationshipId}:${storyTarget.variant}:${storyTarget.sectionIndex ?? "none"}`;
90
+ case "footnote":
91
+ case "endnote":
92
+ return `${storyTarget.kind}:${storyTarget.noteId}`;
93
+ }
94
+ }
@@ -0,0 +1,107 @@
1
+ import type {
2
+ WordReviewEditorChromeOptions,
3
+ WordReviewEditorChromePreset,
4
+ WordReviewEditorChromeVisibility,
5
+ WordReviewEditorProps,
6
+ } from "../../api/public-types";
7
+
8
+ export function resolveChromePreset(
9
+ chromePreset: WordReviewEditorProps["chromePreset"],
10
+ _reviewMode: WordReviewEditorProps["reviewMode"] = "review",
11
+ ): WordReviewEditorChromePreset {
12
+ if (chromePreset) {
13
+ return chromePreset;
14
+ }
15
+ return "advanced";
16
+ }
17
+
18
+ export function resolveChromePresetOptions(
19
+ chromePreset: WordReviewEditorChromePreset,
20
+ overrides?: Partial<WordReviewEditorChromeOptions>,
21
+ ): WordReviewEditorChromeOptions {
22
+ const defaults: Record<WordReviewEditorChromePreset, WordReviewEditorChromeOptions> = {
23
+ selection: {
24
+ showReviewQueueBar: false,
25
+ showSectionTagAction: false,
26
+ showReviewRail: false,
27
+ },
28
+ simple: {
29
+ showReviewQueueBar: false,
30
+ showSectionTagAction: false,
31
+ showReviewRail: false,
32
+ },
33
+ advanced: {
34
+ showReviewQueueBar: false,
35
+ showSectionTagAction: false,
36
+ showReviewRail: true,
37
+ },
38
+ review: {
39
+ showReviewQueueBar: true,
40
+ showSectionTagAction: true,
41
+ showReviewRail: true,
42
+ },
43
+ };
44
+
45
+ return {
46
+ ...defaults[chromePreset],
47
+ ...overrides,
48
+ };
49
+ }
50
+
51
+ export function resolveChromeVisibilityForPreset(input: {
52
+ chromePreset: WordReviewEditorChromePreset;
53
+ chromeOptions?: Partial<WordReviewEditorChromeOptions>;
54
+ chromeVisibility?: Partial<WordReviewEditorChromeVisibility>;
55
+ }): WordReviewEditorChromeVisibility {
56
+ const options = resolveChromePresetOptions(input.chromePreset, input.chromeOptions);
57
+ const defaults: Record<WordReviewEditorChromePreset, WordReviewEditorChromeVisibility> = {
58
+ selection: {
59
+ toolbar: false,
60
+ alerts: true,
61
+ selectionOverlay: true,
62
+ contextToolbars: true,
63
+ contextAnalytics: true,
64
+ pageChrome: true,
65
+ statusBar: true,
66
+ reviewRail: false,
67
+ },
68
+ simple: {
69
+ toolbar: true,
70
+ alerts: true,
71
+ selectionOverlay: true,
72
+ contextToolbars: true,
73
+ contextAnalytics: true,
74
+ pageChrome: true,
75
+ statusBar: true,
76
+ reviewRail: false,
77
+ },
78
+ advanced: {
79
+ toolbar: true,
80
+ alerts: true,
81
+ selectionOverlay: true,
82
+ contextToolbars: true,
83
+ contextAnalytics: true,
84
+ pageChrome: true,
85
+ statusBar: true,
86
+ reviewRail: true,
87
+ },
88
+ review: {
89
+ toolbar: true,
90
+ alerts: true,
91
+ selectionOverlay: true,
92
+ contextToolbars: true,
93
+ contextAnalytics: true,
94
+ pageChrome: true,
95
+ statusBar: true,
96
+ reviewRail: options.showReviewRail,
97
+ },
98
+ };
99
+
100
+ return {
101
+ ...defaults[input.chromePreset],
102
+ ...(input.chromeOptions?.showReviewRail === undefined
103
+ ? {}
104
+ : { reviewRail: input.chromeOptions.showReviewRail }),
105
+ ...input.chromeVisibility,
106
+ };
107
+ }
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+
3
+ import type { WordReviewEditorChromePreset } from "../../api/public-types";
4
+ import {
5
+ TwToolbar,
6
+ type TwToolbarProps,
7
+ } from "../toolbar/tw-toolbar";
8
+
9
+ export interface ChromePresetToolbarProps extends TwToolbarProps {
10
+ chromePreset: WordReviewEditorChromePreset;
11
+ }
12
+
13
+ export function ChromePresetToolbar(props: ChromePresetToolbarProps) {
14
+ return <TwToolbar {...props} preset={props.chromePreset} />;
15
+ }
@@ -0,0 +1,97 @@
1
+ import React from "react";
2
+
3
+ import { BookmarkPlus, ChevronLeft, ChevronRight, MessageSquareText, Rows3 } from "lucide-react";
4
+
5
+ import type { ReviewQueueSnapshot } from "../../api/public-types";
6
+ import { preserveEditorSelectionMouseDown } from "../../ui/headless/preserve-editor-selection";
7
+
8
+ export interface TwReviewQueueBarProps {
9
+ queue: ReviewQueueSnapshot;
10
+ onPrevious?: () => void;
11
+ onNext?: () => void;
12
+ onMarkSection?: () => void;
13
+ }
14
+
15
+ const buttonClass =
16
+ "inline-flex h-8 items-center gap-1 rounded-lg border border-border/80 bg-canvas px-2.5 text-xs font-medium text-secondary transition-colors hover:bg-surface-raised focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-canvas disabled:cursor-not-allowed disabled:opacity-40";
17
+
18
+ export function TwReviewQueueBar(props: TwReviewQueueBarProps) {
19
+ const activeItem = props.queue.items[props.queue.activeIndex] ?? null;
20
+ const activeLabel =
21
+ activeItem?.label ??
22
+ (props.queue.totalCount > 0 ? "Review queue" : "No review items");
23
+ const activeKindLabel = activeItem ? formatReviewQueueItemKind(activeItem.kind) : null;
24
+
25
+ return (
26
+ <div className="border-b border-border/80 bg-surface/80 px-3 py-2.5 backdrop-blur-sm">
27
+ <div className="flex flex-wrap items-center gap-2">
28
+ <button
29
+ type="button"
30
+ aria-label="Previous review item"
31
+ className={buttonClass}
32
+ disabled={props.queue.totalCount === 0}
33
+ onMouseDown={preserveEditorSelectionMouseDown}
34
+ onClick={props.onPrevious}
35
+ >
36
+ <ChevronLeft className="h-3.5 w-3.5" />
37
+ Prev
38
+ </button>
39
+ <button
40
+ type="button"
41
+ aria-label="Next review item"
42
+ className={buttonClass}
43
+ disabled={props.queue.totalCount === 0}
44
+ onMouseDown={preserveEditorSelectionMouseDown}
45
+ onClick={props.onNext}
46
+ >
47
+ Next
48
+ <ChevronRight className="h-3.5 w-3.5" />
49
+ </button>
50
+ {props.onMarkSection ? (
51
+ <button
52
+ type="button"
53
+ aria-label="Mark section for review"
54
+ className={buttonClass}
55
+ onMouseDown={preserveEditorSelectionMouseDown}
56
+ onClick={props.onMarkSection}
57
+ >
58
+ <BookmarkPlus className="h-3.5 w-3.5" />
59
+ Mark section
60
+ </button>
61
+ ) : null}
62
+ <div className="ml-auto flex flex-wrap items-center gap-2 text-xs text-secondary">
63
+ <span className="inline-flex items-center gap-1 rounded-full bg-canvas px-2.5 py-1 font-medium text-primary">
64
+ <MessageSquareText className="h-3.5 w-3.5 text-comment" />
65
+ {props.queue.openCount} open
66
+ </span>
67
+ <span className="inline-flex items-center gap-1 rounded-full bg-canvas px-2.5 py-1 font-medium text-primary">
68
+ <Rows3 className="h-3.5 w-3.5 text-accent" />
69
+ {props.queue.totalCount} total
70
+ </span>
71
+ </div>
72
+ </div>
73
+ <div className="mt-2 flex items-center gap-2 min-w-0">
74
+ {activeKindLabel ? (
75
+ <span
76
+ className="inline-flex shrink-0 rounded-full bg-canvas px-2 py-0.5 text-[11px] font-medium text-secondary"
77
+ data-testid="review-queue-item-kind"
78
+ >
79
+ {activeKindLabel}
80
+ </span>
81
+ ) : null}
82
+ <div className="min-w-0 truncate text-sm font-medium text-primary">{activeLabel}</div>
83
+ </div>
84
+ </div>
85
+ );
86
+ }
87
+
88
+ function formatReviewQueueItemKind(kind: ReviewQueueSnapshot["items"][number]["kind"]): string {
89
+ switch (kind) {
90
+ case "comment":
91
+ return "Comment";
92
+ case "change":
93
+ return "Redline";
94
+ case "section_mark":
95
+ return "Tag";
96
+ }
97
+ }
@@ -0,0 +1,64 @@
1
+ import React from "react";
2
+ import { AlertTriangle, XCircle } from "lucide-react";
3
+
4
+ import type { RuntimeRenderSnapshot, WorkflowBlockedCommandReason } from "../../api/public-types";
5
+
6
+ export interface TwAlertBannerProps {
7
+ snapshot: RuntimeRenderSnapshot;
8
+ preserveOnlyCount: number;
9
+ workflowBlockedReasons?: WorkflowBlockedCommandReason[];
10
+ }
11
+
12
+ export function TwAlertBanner(props: TwAlertBannerProps) {
13
+ const { snapshot, preserveOnlyCount, workflowBlockedReasons = [] } = props;
14
+
15
+ if (snapshot.fatalError) {
16
+ return (
17
+ <div className="flex items-center gap-2 px-3 py-1.5 bg-danger-soft text-danger text-xs">
18
+ <XCircle className="h-3.5 w-3.5 shrink-0" />
19
+ <span>{snapshot.fatalError.message}</span>
20
+ </div>
21
+ );
22
+ }
23
+
24
+ if (snapshot.compatibility.blockExport) {
25
+ return (
26
+ <div className="flex items-center gap-2 px-3 py-1.5 bg-danger-soft text-danger text-xs">
27
+ <XCircle className="h-3.5 w-3.5 shrink-0" />
28
+ <span>
29
+ Export blocked &mdash;{" "}
30
+ {snapshot.compatibility.blockExportReasons[0] ?? "unsupported content"}
31
+ </span>
32
+ </div>
33
+ );
34
+ }
35
+
36
+ if (preserveOnlyCount > 0) {
37
+ return (
38
+ <div className="flex items-center gap-2 px-3 py-1.5 bg-warning-soft text-comment text-xs">
39
+ <AlertTriangle className="h-3.5 w-3.5 shrink-0" />
40
+ <span>
41
+ {preserveOnlyCount} preserve-only feature
42
+ {preserveOnlyCount !== 1 ? "s" : ""} detected
43
+ </span>
44
+ </div>
45
+ );
46
+ }
47
+
48
+ if (workflowBlockedReasons.length > 0) {
49
+ const firstReason = workflowBlockedReasons[0];
50
+ return (
51
+ <div className="flex items-center gap-2 px-3 py-1.5 bg-amber-50 text-amber-700 text-xs">
52
+ <AlertTriangle className="h-3.5 w-3.5 shrink-0" />
53
+ <span>
54
+ {firstReason.message}
55
+ {workflowBlockedReasons.length > 1
56
+ ? ` (+${workflowBlockedReasons.length - 1} more)`
57
+ : ""}
58
+ </span>
59
+ </div>
60
+ );
61
+ }
62
+
63
+ return null;
64
+ }