@ecsplico/editor 2.1.1 → 3.0.0

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 (701) hide show
  1. package/CHANGELOG.md +74 -1
  2. package/README.md +39 -156
  3. package/dist/adapters/comments/drizzle.d.ts +1 -1
  4. package/dist/adapters/comments/{client.js → rest-model.js} +3 -3
  5. package/dist/adapters/comments/rest-model.js.map +1 -0
  6. package/dist/adapters/comments/types.d.ts +2 -2
  7. package/dist/adapters/document-state.d.ts +23 -0
  8. package/dist/adapters/document-state.js +66 -0
  9. package/dist/adapters/document-state.js.map +1 -0
  10. package/dist/adapters/documents.js +14 -11
  11. package/dist/adapters/documents.js.map +1 -1
  12. package/dist/adapters/drizzle.d.ts +2 -2
  13. package/dist/adapters/drizzle.js +97 -88
  14. package/dist/adapters/drizzle.js.map +1 -1
  15. package/dist/adapters/forge.d.ts +12 -7
  16. package/dist/adapters/forge.js +38 -45
  17. package/dist/adapters/forge.js.map +1 -1
  18. package/dist/adapters/http.d.ts +20 -0
  19. package/dist/adapters/http.js +68 -0
  20. package/dist/adapters/http.js.map +1 -0
  21. package/dist/adapters/index.d.ts +5 -5
  22. package/dist/adapters/json.d.ts +3 -3
  23. package/dist/adapters/json.js +58 -49
  24. package/dist/adapters/json.js.map +1 -1
  25. package/dist/adapters/memory.d.ts +21 -0
  26. package/dist/adapters/memory.js +53 -0
  27. package/dist/adapters/memory.js.map +1 -0
  28. package/dist/adapters/nitro.d.ts +23 -20
  29. package/dist/adapters/nitro.js +58 -163
  30. package/dist/adapters/nitro.js.map +1 -1
  31. package/dist/adapters/react.d.ts +55 -0
  32. package/dist/adapters/react.js +209 -0
  33. package/dist/adapters/react.js.map +1 -0
  34. package/dist/adapters/shared.d.ts +15 -21
  35. package/dist/adapters/shared.js +10 -8
  36. package/dist/adapters/shared.js.map +1 -1
  37. package/dist/adapters/vue.d.ts +15 -30
  38. package/dist/adapters/vue.js +36 -87
  39. package/dist/adapters/vue.js.map +1 -1
  40. package/dist/code/CodeSurface.vue.d.ts +3 -3
  41. package/dist/config/index.d.ts +105 -0
  42. package/dist/config/index.js +95 -0
  43. package/dist/config/index.js.map +1 -0
  44. package/dist/core/abilities.js +1 -0
  45. package/dist/core/abilities.js.map +1 -1
  46. package/dist/{adapters/routes.js → core/api-routes.js} +5 -3
  47. package/dist/core/api-routes.js.map +1 -0
  48. package/dist/core/backend-capability.d.ts +7 -0
  49. package/dist/core/backend-capability.js +17 -0
  50. package/dist/core/backend-capability.js.map +1 -0
  51. package/dist/core/backend-types.d.ts +245 -0
  52. package/dist/core/backend-types.js +17 -0
  53. package/dist/core/backend-types.js.map +1 -0
  54. package/dist/core/backend.d.ts +108 -0
  55. package/dist/core/backend.js +14 -0
  56. package/dist/core/backend.js.map +1 -0
  57. package/dist/core/block-convert.d.ts +7 -5
  58. package/dist/core/block-convert.js +28 -5
  59. package/dist/core/block-convert.js.map +1 -1
  60. package/dist/core/command-types.d.ts +89 -0
  61. package/dist/core/commands.d.ts +40 -0
  62. package/dist/core/commands.js +151 -0
  63. package/dist/core/commands.js.map +1 -0
  64. package/dist/core/context.d.ts +17 -20
  65. package/dist/core/context.js +24 -21
  66. package/dist/core/context.js.map +1 -1
  67. package/dist/core/core-feature.d.ts +22 -7
  68. package/dist/core/core-feature.js +51 -18
  69. package/dist/core/core-feature.js.map +1 -1
  70. package/dist/core/define-editor.d.ts +4 -3
  71. package/dist/core/define-editor.js +14 -7
  72. package/dist/core/define-editor.js.map +1 -1
  73. package/dist/core/document-markdown.js +12 -3
  74. package/dist/core/document-markdown.js.map +1 -1
  75. package/dist/core/editor-ui.d.ts +8 -1
  76. package/dist/core/editor-ui.js +9 -8
  77. package/dist/core/editor-ui.js.map +1 -1
  78. package/dist/core/extension-points.d.ts +3 -15
  79. package/dist/core/feature-context.d.ts +8 -7
  80. package/dist/core/feature-context.js +12 -11
  81. package/dist/core/feature-context.js.map +1 -1
  82. package/dist/core/feature.d.ts +35 -19
  83. package/dist/core/feature.js.map +1 -1
  84. package/dist/core/fences.d.ts +2 -1
  85. package/dist/core/fences.js +3 -2
  86. package/dist/core/fences.js.map +1 -1
  87. package/dist/core/fetch-error.d.ts +1 -1
  88. package/dist/core/fetch-error.js +3 -1
  89. package/dist/core/fetch-error.js.map +1 -1
  90. package/dist/core/hash.d.ts +5 -0
  91. package/dist/core/hash.js +11 -0
  92. package/dist/core/hash.js.map +1 -0
  93. package/dist/core/http-backend.d.ts +11 -0
  94. package/dist/core/http-backend.js +195 -0
  95. package/dist/core/http-backend.js.map +1 -0
  96. package/dist/core/index.d.ts +14 -9
  97. package/dist/core/index.js +12 -9
  98. package/dist/core/palette.d.ts +48 -0
  99. package/dist/core/palette.js +95 -0
  100. package/dist/core/palette.js.map +1 -0
  101. package/dist/core/schema/abilities.d.ts +2 -1
  102. package/dist/core/schema/abilities.js +5 -1
  103. package/dist/core/schema/abilities.js.map +1 -1
  104. package/dist/core/schema/index.d.ts +11 -5
  105. package/dist/core/schema/index.js +13 -8
  106. package/dist/core/schema/index.js.map +1 -1
  107. package/dist/core/schema/mark-flags.d.ts +8 -1
  108. package/dist/core/schema/of-features.d.ts +13 -0
  109. package/dist/core/schema/of-features.js +14 -0
  110. package/dist/core/schema/of-features.js.map +1 -0
  111. package/dist/core/slash.d.ts +8 -6
  112. package/dist/core/slash.js +24 -16
  113. package/dist/core/slash.js.map +1 -1
  114. package/dist/core/surface-session.js +13 -5
  115. package/dist/core/surface-session.js.map +1 -1
  116. package/dist/core/toolbar-items.d.ts +10 -4
  117. package/dist/core/toolbar-items.js +269 -195
  118. package/dist/core/toolbar-items.js.map +1 -1
  119. package/dist/core/util.js +11 -0
  120. package/dist/core/util.js.map +1 -0
  121. package/dist/document/DocumentSurface.d.ts +1 -1
  122. package/dist/document/DocumentSurface.vue.d.ts +3 -3
  123. package/dist/features/ai/agent-op-review.d.ts +1 -1
  124. package/dist/features/ai/agent-op-review.js +1 -1
  125. package/dist/features/ai/agent-ops.js +1 -1
  126. package/dist/features/ai/ai-apply.d.ts +2 -2
  127. package/dist/features/ai/ai-apply.js +1 -1
  128. package/dist/features/ai/ai-review.js +1 -1
  129. package/dist/features/ai/ai-sse.d.ts +6 -6
  130. package/dist/features/ai/ai-sse.js +20 -63
  131. package/dist/features/ai/ai-sse.js.map +1 -1
  132. package/dist/features/ai/assistant.d.ts +8 -7
  133. package/dist/features/ai/assistant.js +3 -3
  134. package/dist/features/ai/assistant.js.map +1 -1
  135. package/dist/features/ai/block-actions.d.ts +3 -2
  136. package/dist/features/ai/block-actions.js +3 -2
  137. package/dist/features/ai/block-actions.js.map +1 -1
  138. package/dist/features/ai/components/AiSelectionMenu.js +1 -1
  139. package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
  140. package/dist/features/ai/components/DocumentChatOps.vue.d.ts +1 -1
  141. package/dist/features/ai/components/SettingsModelProfiles.js +8 -8
  142. package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
  143. package/dist/features/ai/document-chat-model.d.ts +8 -7
  144. package/dist/features/ai/document-chat-model.js +5 -5
  145. package/dist/features/ai/document-chat-model.js.map +1 -1
  146. package/dist/features/ai/document-chat.js +1 -1
  147. package/dist/features/ai/feature.js +27 -14
  148. package/dist/features/ai/feature.js.map +1 -1
  149. package/dist/features/ai/ghost-autocomplete.d.ts +7 -6
  150. package/dist/features/ai/ghost-autocomplete.js +6 -9
  151. package/dist/features/ai/ghost-autocomplete.js.map +1 -1
  152. package/dist/features/ai/index.d.ts +4 -3
  153. package/dist/features/ai/index.js +10 -10
  154. package/dist/features/ai/model-profiles.d.ts +5 -4
  155. package/dist/features/ai/model-profiles.js +2 -2
  156. package/dist/features/ai/model-profiles.js.map +1 -1
  157. package/dist/features/ai/protocol/block-lines.js +1 -1
  158. package/dist/features/ai/protocol/block-lines.js.map +1 -1
  159. package/dist/features/ai/protocol/chat.js +4 -1
  160. package/dist/features/ai/protocol/chat.js.map +1 -1
  161. package/dist/features/ai/protocol/index.d.ts +3 -2
  162. package/dist/features/ai/protocol/models.d.ts +2 -16
  163. package/dist/features/ai/protocol/models.js.map +1 -1
  164. package/dist/features/ai/rate-limit.d.ts +1 -1
  165. package/dist/features/ai/rate-limit.js +3 -1
  166. package/dist/features/ai/rate-limit.js.map +1 -1
  167. package/dist/features/ai/react/AiSelectionMenu.js +2 -2
  168. package/dist/features/ai/react/AiSidebar.js +4 -4
  169. package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
  170. package/dist/features/ai/react/DocumentChatOps.d.ts +1 -1
  171. package/dist/features/ai/react/DocumentChatOps.js +1 -1
  172. package/dist/features/ai/react/SettingsModelProfiles.js +8 -10
  173. package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
  174. package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
  175. package/dist/features/ai/react/use-ai-assistant.js +3 -3
  176. package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
  177. package/dist/features/ai/react/use-document-chat.js +2 -2
  178. package/dist/features/ai/react/use-document-chat.js.map +1 -1
  179. package/dist/features/ai/react/use-model-profiles.d.ts +2 -1
  180. package/dist/features/ai/selection-flow.d.ts +1 -1
  181. package/dist/features/ai/selection-flow.js +1 -1
  182. package/dist/features/ai/sidebar-flow.d.ts +1 -1
  183. package/dist/features/ai/sidebar-flow.js +1 -1
  184. package/dist/features/ai/use-ai-assistant.d.ts +1 -1
  185. package/dist/features/ai/use-ai-assistant.js +3 -3
  186. package/dist/features/ai/use-ai-assistant.js.map +1 -1
  187. package/dist/features/ai/use-document-chat.js +2 -2
  188. package/dist/features/ai/use-document-chat.js.map +1 -1
  189. package/dist/features/ai/use-model-profiles.d.ts +2 -1
  190. package/dist/features/authors/attribution.d.ts +1 -1
  191. package/dist/features/authors/feature.js +12 -11
  192. package/dist/features/authors/feature.js.map +1 -1
  193. package/dist/features/block-ui/block-actions.d.ts +22 -1
  194. package/dist/features/block-ui/block-actions.js +26 -2
  195. package/dist/features/block-ui/block-actions.js.map +1 -1
  196. package/dist/features/block-ui/components/BlockActionsOverlay.js +33 -4
  197. package/dist/features/block-ui/components/BlockActionsOverlay.js.map +1 -1
  198. package/dist/features/block-ui/components/BlockActionsOverlay.vue.d.ts +4 -0
  199. package/dist/features/block-ui/components/BlockUi.js +1 -1
  200. package/dist/features/block-ui/feature.js +1 -0
  201. package/dist/features/block-ui/feature.js.map +1 -1
  202. package/dist/features/block-ui/index.d.ts +2 -2
  203. package/dist/features/block-ui/index.js +2 -2
  204. package/dist/features/block-ui/react/BlockActionsOverlay.d.ts +4 -0
  205. package/dist/features/block-ui/react/BlockActionsOverlay.js +38 -12
  206. package/dist/features/block-ui/react/BlockActionsOverlay.js.map +1 -1
  207. package/dist/features/block-ui/react/BlockUi.js +1 -1
  208. package/dist/features/collab/anchor-resolver.js +1 -1
  209. package/dist/features/collab/feature.js +2 -0
  210. package/dist/features/collab/feature.js.map +1 -1
  211. package/dist/features/comments/components/CommentThreadView.vue.d.ts +2 -1
  212. package/dist/features/comments/feature.js +12 -11
  213. package/dist/features/comments/feature.js.map +1 -1
  214. package/dist/features/comments/index.d.ts +3 -2
  215. package/dist/features/comments/index.js +1 -1
  216. package/dist/features/comments/margin-layout.d.ts +3 -2
  217. package/dist/features/comments/model.d.ts +3 -67
  218. package/dist/features/comments/model.js +2 -2
  219. package/dist/features/comments/model.js.map +1 -1
  220. package/dist/features/comments/react/CommentThreadView.d.ts +3 -2
  221. package/dist/features/comments/react/use-comments.d.ts +2 -1
  222. package/dist/features/comments/react.d.ts +1 -1
  223. package/dist/features/comments/schema.d.ts +2 -52
  224. package/dist/features/comments/schema.js.map +1 -1
  225. package/dist/features/comments/snapshot-equality.js.map +1 -1
  226. package/dist/features/comments/use-comments.d.ts +3 -2
  227. package/dist/features/comments/vue.d.ts +1 -1
  228. package/dist/features/composites/accepted-children.d.ts +1 -0
  229. package/dist/features/composites/accepted-children.js +16 -1
  230. package/dist/features/composites/accepted-children.js.map +1 -1
  231. package/dist/features/composites/ai-brief.js +31 -0
  232. package/dist/features/composites/ai-brief.js.map +1 -1
  233. package/dist/features/composites/bibliography-command.d.ts +11 -0
  234. package/dist/features/composites/bibliography-form.js +90 -0
  235. package/dist/features/composites/bibliography-form.js.map +1 -0
  236. package/dist/features/composites/bibliography.d.ts +33 -0
  237. package/dist/features/composites/bibliography.js +120 -0
  238. package/dist/features/composites/bibliography.js.map +1 -0
  239. package/dist/features/composites/components/BibliographyEditor.js +261 -0
  240. package/dist/features/composites/components/BibliographyEditor.js.map +1 -0
  241. package/dist/features/composites/components/CompositeChrome.js +75 -26
  242. package/dist/features/composites/components/CompositeChrome.js.map +1 -1
  243. package/dist/features/composites/components/CompositeDetails.js +46 -11
  244. package/dist/features/composites/components/CompositeDetails.js.map +1 -1
  245. package/dist/features/composites/components/CompositeDetails.vue.d.ts +2 -1
  246. package/dist/features/composites/components/CompositeFieldEditor.js +37 -4
  247. package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
  248. package/dist/features/composites/components/CompositeInspector.js +17 -5
  249. package/dist/features/composites/components/CompositeInspector.js.map +1 -1
  250. package/dist/features/composites/components/CompositeTable.js +13 -4
  251. package/dist/features/composites/components/CompositeTable.js.map +1 -1
  252. package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
  253. package/dist/features/composites/components/CompositeView.js +11 -1
  254. package/dist/features/composites/components/CompositeView.js.map +1 -1
  255. package/dist/features/composites/components/DerivationBadge.js +103 -0
  256. package/dist/features/composites/components/DerivationBadge.js.map +1 -0
  257. package/dist/features/composites/components/ReferenceFieldSelect.js +60 -0
  258. package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -0
  259. package/dist/features/composites/components/ReferenceView.js +122 -0
  260. package/dist/features/composites/components/ReferenceView.js.map +1 -0
  261. package/dist/features/composites/components/ReferenceView.vue.d.ts +96 -0
  262. package/dist/features/composites/components/SettingsEditingTab.js +1 -1
  263. package/dist/features/composites/convert.js +2 -2
  264. package/dist/features/composites/convert.js.map +1 -1
  265. package/dist/features/composites/derivation.d.ts +61 -0
  266. package/dist/features/composites/derivation.js +98 -0
  267. package/dist/features/composites/derivation.js.map +1 -0
  268. package/dist/features/composites/derived-chrome.js +69 -0
  269. package/dist/features/composites/derived-chrome.js.map +1 -0
  270. package/dist/features/composites/feature.js +159 -109
  271. package/dist/features/composites/feature.js.map +1 -1
  272. package/dist/features/composites/fences.d.ts +4 -3
  273. package/dist/features/composites/fences.js +51 -7
  274. package/dist/features/composites/fences.js.map +1 -1
  275. package/dist/features/composites/index.d.ts +12 -3
  276. package/dist/features/composites/index.js +15 -6
  277. package/dist/features/composites/inspector-model.d.ts +4 -1
  278. package/dist/features/composites/inspector-model.js +8 -4
  279. package/dist/features/composites/inspector-model.js.map +1 -1
  280. package/dist/features/composites/kinds.d.ts +8 -1
  281. package/dist/features/composites/kinds.js +145 -6
  282. package/dist/features/composites/kinds.js.map +1 -1
  283. package/dist/features/composites/legacy.d.ts +4 -1
  284. package/dist/features/composites/legacy.js +56 -1
  285. package/dist/features/composites/legacy.js.map +1 -1
  286. package/dist/features/composites/meta-display.js +40 -1
  287. package/dist/features/composites/meta-display.js.map +1 -1
  288. package/dist/features/composites/meta-keys.d.ts +7 -0
  289. package/dist/features/composites/meta-keys.js +21 -0
  290. package/dist/features/composites/meta-keys.js.map +1 -0
  291. package/dist/features/composites/node-views.d.ts +6 -3
  292. package/dist/features/composites/node-views.js +7 -3
  293. package/dist/features/composites/node-views.js.map +1 -1
  294. package/dist/features/composites/nodes.d.ts +6 -1
  295. package/dist/features/composites/nodes.js +33 -7
  296. package/dist/features/composites/nodes.js.map +1 -1
  297. package/dist/features/composites/react/BibliographyEditor.js +229 -0
  298. package/dist/features/composites/react/BibliographyEditor.js.map +1 -0
  299. package/dist/features/composites/react/CompositeChrome.js +65 -17
  300. package/dist/features/composites/react/CompositeChrome.js.map +1 -1
  301. package/dist/features/composites/react/CompositeDetails.d.ts +2 -1
  302. package/dist/features/composites/react/CompositeDetails.js +45 -6
  303. package/dist/features/composites/react/CompositeDetails.js.map +1 -1
  304. package/dist/features/composites/react/CompositeFieldEditor.d.ts +1 -1
  305. package/dist/features/composites/react/CompositeFieldEditor.js +24 -1
  306. package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
  307. package/dist/features/composites/react/CompositeInspector.js +11 -5
  308. package/dist/features/composites/react/CompositeInspector.js.map +1 -1
  309. package/dist/features/composites/react/CompositeStatusMenu.js +1 -1
  310. package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
  311. package/dist/features/composites/react/CompositeTable.js +16 -2
  312. package/dist/features/composites/react/CompositeTable.js.map +1 -1
  313. package/dist/features/composites/react/CompositeTagsEditor.js +2 -2
  314. package/dist/features/composites/react/CompositeView.js +6 -1
  315. package/dist/features/composites/react/CompositeView.js.map +1 -1
  316. package/dist/features/composites/react/DerivationBadge.js +116 -0
  317. package/dist/features/composites/react/DerivationBadge.js.map +1 -0
  318. package/dist/features/composites/react/ReferenceFieldSelect.js +52 -0
  319. package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -0
  320. package/dist/features/composites/react/ReferenceView.d.ts +11 -0
  321. package/dist/features/composites/react/ReferenceView.js +115 -0
  322. package/dist/features/composites/react/ReferenceView.js.map +1 -0
  323. package/dist/features/composites/react/SettingsEditingTab.js +2 -2
  324. package/dist/features/composites/react.d.ts +2 -1
  325. package/dist/features/composites/react.js +7 -3
  326. package/dist/features/composites/react.js.map +1 -1
  327. package/dist/features/composites/reference-ai.js +16 -0
  328. package/dist/features/composites/reference-ai.js.map +1 -0
  329. package/dist/features/composites/reference-label.d.ts +19 -0
  330. package/dist/features/composites/reference-label.js +58 -0
  331. package/dist/features/composites/reference-label.js.map +1 -0
  332. package/dist/features/composites/reference-suggestion.d.ts +10 -0
  333. package/dist/features/composites/reference-suggestion.js +41 -0
  334. package/dist/features/composites/reference-suggestion.js.map +1 -0
  335. package/dist/features/composites/reference-text.d.ts +18 -0
  336. package/dist/features/composites/reference-text.js +89 -0
  337. package/dist/features/composites/reference-text.js.map +1 -0
  338. package/dist/features/composites/reference.d.ts +44 -0
  339. package/dist/features/composites/reference.js +148 -0
  340. package/dist/features/composites/reference.js.map +1 -0
  341. package/dist/features/composites/reveal-source.d.ts +32 -0
  342. package/dist/features/composites/reveal-source.js +89 -0
  343. package/dist/features/composites/reveal-source.js.map +1 -0
  344. package/dist/features/composites/rows.d.ts +21 -2
  345. package/dist/features/composites/rows.js +63 -9
  346. package/dist/features/composites/rows.js.map +1 -1
  347. package/dist/features/composites/schema.d.ts +9 -3
  348. package/dist/features/composites/schema.js +11 -4
  349. package/dist/features/composites/schema.js.map +1 -1
  350. package/dist/features/composites/table-model.js +12 -21
  351. package/dist/features/composites/table-model.js.map +1 -1
  352. package/dist/features/composites/vue.d.ts +3 -2
  353. package/dist/features/composites/vue.js +8 -4
  354. package/dist/features/composites/vue.js.map +1 -1
  355. package/dist/features/media/assets.d.ts +2 -0
  356. package/dist/features/media/assets.js +3 -2
  357. package/dist/features/media/assets.js.map +1 -1
  358. package/dist/features/media/components/FileView.js +13 -4
  359. package/dist/features/media/components/FileView.js.map +1 -1
  360. package/dist/features/media/feature.d.ts +3 -3
  361. package/dist/features/media/feature.js +21 -28
  362. package/dist/features/media/feature.js.map +1 -1
  363. package/dist/features/media/file-import.js +2 -2
  364. package/dist/features/media/file-import.js.map +1 -1
  365. package/dist/features/media/index.d.ts +2 -2
  366. package/dist/features/media/index.js +2 -2
  367. package/dist/features/media/react/FileView.js +19 -2
  368. package/dist/features/media/react/FileView.js.map +1 -1
  369. package/dist/features/media/schema.d.ts +8 -0
  370. package/dist/features/media/schema.js +126 -11
  371. package/dist/features/media/schema.js.map +1 -1
  372. package/dist/features/media/upload.d.ts +16 -14
  373. package/dist/features/media/upload.js +13 -19
  374. package/dist/features/media/upload.js.map +1 -1
  375. package/dist/features/mentions/index.d.ts +4 -3
  376. package/dist/features/mentions/index.js +4 -1
  377. package/dist/features/mentions/index.js.map +1 -1
  378. package/dist/features/mentions/mention-text.d.ts +1 -1
  379. package/dist/features/mentions/mention-text.js.map +1 -1
  380. package/dist/features/mentions/mention.d.ts +0 -6
  381. package/dist/features/mentions/mention.js.map +1 -1
  382. package/dist/features/mentions/metadata-defaults.d.ts +2 -2
  383. package/dist/features/mentions/metadata-defaults.js +3 -9
  384. package/dist/features/mentions/metadata-defaults.js.map +1 -1
  385. package/dist/features/mentions/schema.d.ts +2 -1
  386. package/dist/features/mentions/schema.js.map +1 -1
  387. package/dist/features/tables/feature.d.ts +2 -1
  388. package/dist/features/tables/feature.js +90 -70
  389. package/dist/features/tables/feature.js.map +1 -1
  390. package/dist/features/themes/components/SettingsAppearanceTab.js +6 -9
  391. package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
  392. package/dist/features/themes/feature.js +2 -0
  393. package/dist/features/themes/feature.js.map +1 -1
  394. package/dist/features/themes/index.d.ts +2 -1
  395. package/dist/features/themes/react/SettingsAppearanceTab.js +7 -10
  396. package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
  397. package/dist/features/themes/schema.d.ts +2 -6
  398. package/dist/features/themes/schema.js.map +1 -1
  399. package/dist/features/themes/theme-runtime.d.ts +1 -1
  400. package/dist/features/themes/theme-runtime.js +4 -2
  401. package/dist/features/themes/theme-runtime.js.map +1 -1
  402. package/dist/features/transcript/TranscriptSegmentView.js +48 -28
  403. package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
  404. package/dist/features/transcript/feature.js +21 -19
  405. package/dist/features/transcript/feature.js.map +1 -1
  406. package/dist/features/transcript/react/TranscriptSegmentView.js +55 -36
  407. package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
  408. package/dist/features/transcript/segment-node.d.ts +2 -0
  409. package/dist/features/transcript/segment-node.js +35 -7
  410. package/dist/features/transcript/segment-node.js.map +1 -1
  411. package/dist/i18n/de/composites.js +91 -1
  412. package/dist/i18n/de/composites.js.map +1 -1
  413. package/dist/i18n/de/integrations.js +49 -8
  414. package/dist/i18n/de/integrations.js.map +1 -1
  415. package/dist/i18n/de/media.js +0 -1
  416. package/dist/i18n/de/media.js.map +1 -1
  417. package/dist/i18n/de/palette.js +22 -0
  418. package/dist/i18n/de/palette.js.map +1 -0
  419. package/dist/i18n/de/tables.js +0 -1
  420. package/dist/i18n/de/tables.js.map +1 -1
  421. package/dist/i18n/de/transcript.js +2 -1
  422. package/dist/i18n/de/transcript.js.map +1 -1
  423. package/dist/i18n/de/tree.js +3 -0
  424. package/dist/i18n/de/tree.js.map +1 -1
  425. package/dist/i18n/de.d.ts +157 -11
  426. package/dist/i18n/de.js +3 -1
  427. package/dist/i18n/de.js.map +1 -1
  428. package/dist/i18n/en/composites.js +89 -1
  429. package/dist/i18n/en/composites.js.map +1 -1
  430. package/dist/i18n/en/integrations.js +49 -8
  431. package/dist/i18n/en/integrations.js.map +1 -1
  432. package/dist/i18n/en/media.js +0 -1
  433. package/dist/i18n/en/media.js.map +1 -1
  434. package/dist/i18n/en/palette.js +22 -0
  435. package/dist/i18n/en/palette.js.map +1 -0
  436. package/dist/i18n/en/tables.js +0 -1
  437. package/dist/i18n/en/tables.js.map +1 -1
  438. package/dist/i18n/en/transcript.js +2 -1
  439. package/dist/i18n/en/transcript.js.map +1 -1
  440. package/dist/i18n/en/tree.js +3 -0
  441. package/dist/i18n/en/tree.js.map +1 -1
  442. package/dist/i18n/en.js +3 -1
  443. package/dist/i18n/en.js.map +1 -1
  444. package/dist/index.d.ts +4 -3
  445. package/dist/integrations/composite-ai/bibliography-fetch.d.ts +31 -0
  446. package/dist/integrations/composite-ai/bibliography-fetch.js +159 -0
  447. package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -0
  448. package/dist/integrations/composite-ai/composite-fill.d.ts +30 -8
  449. package/dist/integrations/composite-ai/composite-fill.js +97 -56
  450. package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
  451. package/dist/integrations/composite-ai/composite-summary.d.ts +4 -12
  452. package/dist/integrations/composite-ai/composite-summary.js +7 -26
  453. package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
  454. package/dist/integrations/composite-ai/derive.d.ts +29 -0
  455. package/dist/integrations/composite-ai/derive.js +173 -0
  456. package/dist/integrations/composite-ai/derive.js.map +1 -0
  457. package/dist/integrations/composite-ai/index.d.ts +11 -7
  458. package/dist/integrations/composite-ai/index.js +72 -14
  459. package/dist/integrations/composite-ai/index.js.map +1 -1
  460. package/dist/integrations/composite-ai/rendition.d.ts +45 -0
  461. package/dist/integrations/composite-ai/rendition.js +314 -0
  462. package/dist/integrations/composite-ai/rendition.js.map +1 -0
  463. package/dist/integrations/composite-media/index.d.ts +7 -5
  464. package/dist/integrations/composite-media/index.js +86 -13
  465. package/dist/integrations/composite-media/index.js.map +1 -1
  466. package/dist/integrations/transcript-ai/index.d.ts +1 -1
  467. package/dist/integrations/transcript-ai/index.js +5 -2
  468. package/dist/integrations/transcript-ai/index.js.map +1 -1
  469. package/dist/integrations/transcript-ai/protocol.d.ts +2 -12
  470. package/dist/integrations/transcript-ai/protocol.js +0 -2
  471. package/dist/integrations/transcript-ai/protocol.js.map +1 -1
  472. package/dist/integrations/transcript-ai/transcript-cleanup.d.ts +5 -5
  473. package/dist/integrations/transcript-ai/transcript-cleanup.js +7 -10
  474. package/dist/integrations/transcript-ai/transcript-cleanup.js.map +1 -1
  475. package/dist/markdown/MarkdownSurface.vue.d.ts +10 -9
  476. package/dist/markdown/MarkdownSurface2.js +3 -6
  477. package/dist/markdown/MarkdownSurface2.js.map +1 -1
  478. package/dist/markdown/document.js +1 -1
  479. package/dist/markdown/source-mode.d.ts +1 -1
  480. package/dist/nuxt/module.d.ts +1402 -54
  481. package/dist/nuxt/module.js +6 -49
  482. package/dist/nuxt/module.js.map +1 -1
  483. package/dist/nuxt/runtime/install-context.d.ts +7 -3
  484. package/dist/nuxt/runtime/install-context.js +14 -8
  485. package/dist/nuxt/runtime/install-context.js.map +1 -1
  486. package/dist/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts +2 -2
  487. package/dist/nuxt/runtime/server/plugins/editor-server.js +20 -12
  488. package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
  489. package/dist/presets/compose.d.ts +94 -0
  490. package/dist/presets/compose.js +164 -0
  491. package/dist/presets/compose.js.map +1 -0
  492. package/dist/react/AdvancedEditor.d.ts +15 -15
  493. package/dist/react/AdvancedEditor.js +15 -13
  494. package/dist/react/AdvancedEditor.js.map +1 -1
  495. package/dist/react/EditorCommandPalette.d.ts +13 -0
  496. package/dist/react/EditorCommandPalette.js +118 -0
  497. package/dist/react/EditorCommandPalette.js.map +1 -0
  498. package/dist/react/EditorSettingsModal.d.ts +5 -5
  499. package/dist/react/EditorSettingsModal.js +7 -4
  500. package/dist/react/EditorSettingsModal.js.map +1 -1
  501. package/dist/react/EditorSettingsPanel.d.ts +7 -7
  502. package/dist/react/EditorSettingsPanel.js +8 -5
  503. package/dist/react/EditorSettingsPanel.js.map +1 -1
  504. package/dist/react/EditorSurface.d.ts +7 -7
  505. package/dist/react/EditorSurface.js +10 -6
  506. package/dist/react/EditorSurface.js.map +1 -1
  507. package/dist/react/EditorToolbar.d.ts +4 -6
  508. package/dist/react/EditorToolbar.js +29 -37
  509. package/dist/react/EditorToolbar.js.map +1 -1
  510. package/dist/react/SimpleEditor.d.ts +22 -23
  511. package/dist/react/SimpleEditor.js +21 -7
  512. package/dist/react/SimpleEditor.js.map +1 -1
  513. package/dist/react/advanced.d.ts +4 -3
  514. package/dist/react/advanced.js +2 -2
  515. package/dist/react/compose.d.ts +20 -0
  516. package/dist/react/compose.js +49 -0
  517. package/dist/react/compose.js.map +1 -0
  518. package/dist/react/composed-surface.d.ts +39 -0
  519. package/dist/react/composed-surface.js +71 -0
  520. package/dist/react/composed-surface.js.map +1 -0
  521. package/dist/react/context.js +6 -2
  522. package/dist/react/context.js.map +1 -1
  523. package/dist/react/index.d.ts +2 -1
  524. package/dist/react/index.js +2 -1
  525. package/dist/react/key-labels.js +15 -0
  526. package/dist/react/key-labels.js.map +1 -0
  527. package/dist/react/settings.d.ts +1 -1
  528. package/dist/react/simple.d.ts +2 -2
  529. package/dist/react/ui/command.js +36 -1
  530. package/dist/react/ui/command.js.map +1 -1
  531. package/dist/schema/advanced.d.ts +6 -6
  532. package/dist/schema/advanced.js +26 -29
  533. package/dist/schema/advanced.js.map +1 -1
  534. package/dist/server/ai.d.ts +5 -16
  535. package/dist/server/ai.js.map +1 -1
  536. package/dist/server/auth.d.ts +9 -0
  537. package/dist/server/collab-state.d.ts +1 -1
  538. package/dist/server/collab-state.js.map +1 -1
  539. package/dist/server/collab.d.ts +13 -13
  540. package/dist/server/collab.js +34 -18
  541. package/dist/server/collab.js.map +1 -1
  542. package/dist/server/crossref.js +78 -0
  543. package/dist/server/crossref.js.map +1 -0
  544. package/dist/server/errors.d.ts +1 -1
  545. package/dist/server/errors.js +1 -1
  546. package/dist/server/errors.js.map +1 -1
  547. package/dist/server/extract.js +308 -0
  548. package/dist/server/extract.js.map +1 -0
  549. package/dist/{nuxt/runtime/server/utils/editor-route.js → server/h3.js} +8 -16
  550. package/dist/server/h3.js.map +1 -0
  551. package/dist/server/handlers/ai.d.ts +30 -9
  552. package/dist/server/handlers/ai.js +170 -36
  553. package/dist/server/handlers/ai.js.map +1 -1
  554. package/dist/server/handlers/context.d.ts +12 -5
  555. package/dist/server/handlers/context.js +10 -4
  556. package/dist/server/handlers/context.js.map +1 -1
  557. package/dist/server/handlers/editor.d.ts +19 -13
  558. package/dist/server/handlers/editor.js +49 -38
  559. package/dist/server/handlers/editor.js.map +1 -1
  560. package/dist/server/handlers/index.d.ts +4 -4
  561. package/dist/server/handlers/index.js +4 -4
  562. package/dist/server/host.d.ts +16 -25
  563. package/dist/server/host.js +58 -41
  564. package/dist/server/host.js.map +1 -1
  565. package/dist/server/index.d.ts +6 -4
  566. package/dist/server/index.js +3 -2
  567. package/dist/server/pdf.js +97 -0
  568. package/dist/server/pdf.js.map +1 -0
  569. package/dist/server/{adapter.d.ts → ports.d.ts} +81 -30
  570. package/dist/server/ports.js +29 -0
  571. package/dist/server/ports.js.map +1 -0
  572. package/dist/server/routes.js +144 -0
  573. package/dist/server/routes.js.map +1 -0
  574. package/dist/settings/index.d.ts +1 -1
  575. package/dist/settings/index.js.map +1 -1
  576. package/dist/styles/composites.css +25 -0
  577. package/dist/tree/DocumentTree.js +56 -29
  578. package/dist/tree/DocumentTree.js.map +1 -1
  579. package/dist/tree/react/DocumentTree.js +23 -0
  580. package/dist/tree/react/DocumentTree.js.map +1 -1
  581. package/dist/tree/tree-host.js +1 -1
  582. package/dist/vue/AdvancedEditor.js +30 -9
  583. package/dist/vue/AdvancedEditor.js.map +1 -1
  584. package/dist/vue/AdvancedEditor.vue.d.ts +32 -12
  585. package/dist/vue/SimpleEditor.js +62 -16
  586. package/dist/vue/SimpleEditor.js.map +1 -1
  587. package/dist/vue/SimpleEditor.vue.d.ts +37 -7
  588. package/dist/vue/advanced.d.ts +3 -2
  589. package/dist/vue/advanced.js +2 -2
  590. package/dist/vue/components/EditorCommandPalette.js +91 -0
  591. package/dist/vue/components/EditorCommandPalette.js.map +1 -0
  592. package/dist/vue/components/EditorCommandPalette.vue.d.ts +15 -0
  593. package/dist/vue/components/EditorSettingsModal.js +10 -6
  594. package/dist/vue/components/EditorSettingsModal.js.map +1 -1
  595. package/dist/vue/components/EditorSettingsModal.vue.d.ts +4 -4
  596. package/dist/vue/components/EditorSettingsPanel.js +10 -6
  597. package/dist/vue/components/EditorSettingsPanel.js.map +1 -1
  598. package/dist/vue/components/EditorSettingsPanel.vue.d.ts +6 -6
  599. package/dist/vue/components/EditorSurface.js +11 -6
  600. package/dist/vue/components/EditorSurface.js.map +1 -1
  601. package/dist/vue/components/EditorSurface.vue.d.ts +11 -11
  602. package/dist/vue/components/EditorToolbar.js +41 -49
  603. package/dist/vue/components/EditorToolbar.js.map +1 -1
  604. package/dist/vue/components/EditorToolbar.vue.d.ts +2 -4
  605. package/dist/vue/compose.d.ts +17 -0
  606. package/dist/vue/compose.js +51 -0
  607. package/dist/vue/compose.js.map +1 -0
  608. package/dist/vue/context-key.d.ts +6 -0
  609. package/dist/vue/context-key.js +6 -0
  610. package/dist/vue/context-key.js.map +1 -0
  611. package/dist/vue/context.d.ts +8 -6
  612. package/dist/vue/context.js +6 -5
  613. package/dist/vue/context.js.map +1 -1
  614. package/dist/vue/index.d.ts +10 -8
  615. package/dist/vue/index.js +10 -8
  616. package/dist/vue/kit/index.d.ts +2 -2
  617. package/dist/vue/kit/nuxt-ui.js +23 -0
  618. package/dist/vue/kit/nuxt-ui.js.map +1 -1
  619. package/dist/vue/kit/types.d.ts +40 -1
  620. package/package.json +30 -16
  621. package/dist/adapters/comments/client.d.ts +0 -64
  622. package/dist/adapters/comments/client.js.map +0 -1
  623. package/dist/adapters/routes.js.map +0 -1
  624. package/dist/core/toolbar.d.ts +0 -74
  625. package/dist/core/toolbar.js +0 -45
  626. package/dist/core/toolbar.js.map +0 -1
  627. package/dist/integrations/composite-ai/document-transcribe.d.ts +0 -14
  628. package/dist/integrations/composite-ai/document-transcribe.js +0 -89
  629. package/dist/integrations/composite-ai/document-transcribe.js.map +0 -1
  630. package/dist/nuxt/runtime/server/api/ai/chat.post.d.ts +0 -5
  631. package/dist/nuxt/runtime/server/api/ai/chat.post.js +0 -8
  632. package/dist/nuxt/runtime/server/api/ai/chat.post.js.map +0 -1
  633. package/dist/nuxt/runtime/server/api/ai/complete.post.d.ts +0 -5
  634. package/dist/nuxt/runtime/server/api/ai/complete.post.js +0 -8
  635. package/dist/nuxt/runtime/server/api/ai/complete.post.js.map +0 -1
  636. package/dist/nuxt/runtime/server/api/ai/generate.post.d.ts +0 -5
  637. package/dist/nuxt/runtime/server/api/ai/generate.post.js +0 -8
  638. package/dist/nuxt/runtime/server/api/ai/generate.post.js.map +0 -1
  639. package/dist/nuxt/runtime/server/api/ai/models.get.d.ts +0 -5
  640. package/dist/nuxt/runtime/server/api/ai/models.get.js +0 -8
  641. package/dist/nuxt/runtime/server/api/ai/models.get.js.map +0 -1
  642. package/dist/nuxt/runtime/server/api/ai/transcribe.post.d.ts +0 -5
  643. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js +0 -8
  644. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js.map +0 -1
  645. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.d.ts +0 -5
  646. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js +0 -8
  647. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js.map +0 -1
  648. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.d.ts +0 -5
  649. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js +0 -8
  650. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js.map +0 -1
  651. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.d.ts +0 -5
  652. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js +0 -8
  653. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js.map +0 -1
  654. package/dist/nuxt/runtime/server/api/editor/settings.get.d.ts +0 -5
  655. package/dist/nuxt/runtime/server/api/editor/settings.get.js +0 -8
  656. package/dist/nuxt/runtime/server/api/editor/settings.get.js.map +0 -1
  657. package/dist/nuxt/runtime/server/api/editor/settings.put.d.ts +0 -5
  658. package/dist/nuxt/runtime/server/api/editor/settings.put.js +0 -8
  659. package/dist/nuxt/runtime/server/api/editor/settings.put.js.map +0 -1
  660. package/dist/nuxt/runtime/server/api/editor/tags.get.d.ts +0 -5
  661. package/dist/nuxt/runtime/server/api/editor/tags.get.js +0 -8
  662. package/dist/nuxt/runtime/server/api/editor/tags.get.js.map +0 -1
  663. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.d.ts +0 -5
  664. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js +0 -8
  665. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js.map +0 -1
  666. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.d.ts +0 -5
  667. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js +0 -8
  668. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js.map +0 -1
  669. package/dist/nuxt/runtime/server/api/editor/themes/index.get.d.ts +0 -5
  670. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js +0 -8
  671. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js.map +0 -1
  672. package/dist/nuxt/runtime/server/api/editor/themes/index.post.d.ts +0 -5
  673. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js +0 -8
  674. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js.map +0 -1
  675. package/dist/nuxt/runtime/server/api/editor/users.get.d.ts +0 -5
  676. package/dist/nuxt/runtime/server/api/editor/users.get.js +0 -8
  677. package/dist/nuxt/runtime/server/api/editor/users.get.js.map +0 -1
  678. package/dist/nuxt/runtime/server/plugins/collab.d.ts +0 -5
  679. package/dist/nuxt/runtime/server/plugins/collab.js +0 -10
  680. package/dist/nuxt/runtime/server/plugins/collab.js.map +0 -1
  681. package/dist/nuxt/runtime/server/routes/collab/[id].d.ts +0 -5
  682. package/dist/nuxt/runtime/server/routes/collab/[id].js +0 -35
  683. package/dist/nuxt/runtime/server/routes/collab/[id].js.map +0 -1
  684. package/dist/nuxt/runtime/server/utils/editor-route.d.ts +0 -11
  685. package/dist/nuxt/runtime/server/utils/editor-route.js.map +0 -1
  686. package/dist/presets/advanced.d.ts +0 -33
  687. package/dist/presets/advanced.js +0 -50
  688. package/dist/presets/advanced.js.map +0 -1
  689. package/dist/presets/simple.d.ts +0 -9
  690. package/dist/presets/simple.js +0 -12
  691. package/dist/presets/simple.js.map +0 -1
  692. package/dist/react/advanced-preset.d.ts +0 -11
  693. package/dist/react/advanced-preset.js +0 -31
  694. package/dist/react/advanced-preset.js.map +0 -1
  695. package/dist/vue/advanced-preset.d.ts +0 -13
  696. package/dist/vue/advanced-preset.js +0 -33
  697. package/dist/vue/advanced-preset.js.map +0 -1
  698. package/docs/extending.md +0 -538
  699. package/docs/integration.md +0 -630
  700. package/docs/llms.md +0 -383
  701. package/docs/usage.md +0 -1076
@@ -1 +1 @@
1
- {"version":3,"file":"CompositeTable.js","names":[],"sources":["../../../../src/features/composites/react/CompositeTable.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useMemo, useState } from 'react'\nimport { Icon } from '../../../react/Icon'\nimport { Badge } from '../../../react/ui/badge'\nimport { Button } from '../../../react/ui/button'\nimport { Input } from '../../../react/ui/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../../react/ui/select'\nimport { TableBody, TableCell, TableHead, TableHeader, TableRow } from '../../../react/ui/table'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport type { CompositeRow } from '../rows'\nimport { columnSpecsOf, FILTER_ALL, fieldColumnsOf, fieldOf, fieldText, hasText, isLongText, sortRows, toggled } from '../table-model'\nimport { useCompositeRows } from './use-composite-rows'\n\n// All Bausteine of an editor's document as a sortable, filterable table. Columns beyond the fixed ones derive from the\n// meta fields of the kinds present in the document, so a host kind with fields gets its columns without code changes.\n// The column specs, cell text and sorting are the framework-free `table-model`, shared with the Vue table.\n\n/** The table of an editor's Bausteine: sortable columns, filters by kind, tag and select fields, a text search; `onSelect` receives the clicked row. */\nexport function CompositeTable({ editor, onSelect, className }: {\n editor?: Editor\n onSelect?: (row: CompositeRow) => void\n className?: string\n}) {\n const { rows, tags, kinds } = useCompositeRows(editor)\n\n const { t } = useEditorI18n()\n const fieldColumns = useMemo(() => fieldColumnsOf(rows, kinds), [rows, kinds])\n const specs = useMemo(() => columnSpecsOf(fieldColumns, t), [fieldColumns, t])\n\n const [search, setSearch] = useState('')\n const [pickedKinds, setPickedKinds] = useState<string[]>([])\n const [pickedTags, setPickedTags] = useState<string[]>([])\n const [pickedOptions, setPickedOptions] = useState<Record<string, string>>({})\n\n /** One select per `select` field in use; its choices are the union of the options of all kinds that have the key. */\n const selectFilters = useMemo(() => fieldColumns.flatMap((column) => {\n if (column.field.type !== 'select') return []\n const options = new Map<string, string>()\n for (const row of rows) {\n for (const option of fieldOf(row, column.field.key)?.options ?? []) if (!options.has(option.value)) options.set(option.value, option.label)\n }\n return [{\n key: column.field.key,\n label: column.field.label,\n items: [{ label: t('composites.table.filter.all'), value: FILTER_ALL }, ...[...options].map(([value, label]) => ({ label, value }))],\n }]\n }), [fieldColumns, rows, t])\n\n // A kind, tag or option that vanished from the document can no longer be unpicked in the UI, so it must not filter either.\n const activeKinds = useMemo(() => pickedKinds.filter(id => kinds.some(kind => kind.id === id)), [pickedKinds, kinds])\n const activeTags = useMemo(() => pickedTags.filter(tag => tags.includes(tag)), [pickedTags, tags])\n const activeOptions = useMemo(() => selectFilters.flatMap((filter) => {\n const value = pickedOptions[filter.key]\n return value && filter.items.some(item => item.value === value && value !== FILTER_ALL) ? [[filter.key, value] as const] : []\n }), [selectFilters, pickedOptions])\n const needle = search.trim().toLowerCase()\n const filterActive = activeKinds.length > 0 || activeTags.length > 0 || activeOptions.length > 0 || needle !== ''\n\n function resetFilters() {\n setSearch('')\n setPickedKinds([])\n setPickedTags([])\n setPickedOptions({})\n }\n\n const filtered = useMemo(() => rows.filter((row) => {\n if (activeKinds.length && !activeKinds.includes(row.kind)) return false\n if (activeTags.length && !activeTags.every(tag => row.tags.includes(tag))) return false\n if (activeOptions.some(([key, value]) => row.meta[key] !== value)) return false\n if (needle) {\n const haystack = `${row.title}\\n${row.description}\\n${row.tags.map(tag => `#${tag}`).join(' ')}`.toLowerCase()\n if (!haystack.includes(needle)) return false\n }\n return true\n }), [rows, activeKinds, activeTags, activeOptions, needle])\n\n // --- Sorting (client side, over the filtered rows) ---\n\n const [sorting, setSorting] = useState<{ id: string, desc: boolean } | null>(null)\n const activeSort = useMemo(() => {\n const spec = sorting && specs.find(item => item.id === sorting.id)\n return sorting && spec ? { id: sorting.id, desc: sorting.desc, sort: spec.sort } : null\n }, [sorting, specs])\n\n /** Header click cycles ascending → descending → unsorted. */\n function cycleSort(id: string) {\n setSorting(current => current?.id !== id ? { id, desc: false } : current.desc ? null : { id, desc: true })\n }\n const sortIcon = (id: string) => {\n if (sorting?.id !== id) return 'i-lucide-chevrons-up-down'\n return sorting.desc ? 'i-lucide-arrow-down' : 'i-lucide-arrow-up'\n }\n\n const sorted = useMemo(() => activeSort ? sortRows(filtered, activeSort.sort, activeSort.desc) : filtered, [filtered, activeSort])\n\n const countLabel = t(rows.length === 1 ? 'composites.table.count.one' : 'composites.table.count.other', { n: sorted.length, total: rows.length })\n const columnCount = specs.length\n\n return (\n <section className={cn('flex min-h-0 flex-col gap-3', className)} aria-label={t('composites.table.label')}>\n {!rows.length\n ? (\n <div className=\"mx-auto flex max-w-sm flex-1 flex-col items-center justify-center gap-2 py-16 text-center\">\n <Icon name=\"i-lucide-table-2\" className=\"size-8 text-muted-foreground/70\" />\n <p className=\"text-sm font-medium text-foreground\">\n {t('composites.table.emptyTitle')}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {t('composites.table.emptyText')}\n </p>\n </div>\n )\n : (\n <>\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <div className=\"relative w-64\">\n <Icon name=\"i-lucide-search\" className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n value={search}\n onChange={event => setSearch(event.target.value)}\n className={cn('h-7 pl-8 text-sm', search && 'pr-8')}\n placeholder={t('composites.table.search.placeholder')}\n aria-label={t('composites.table.search.label')}\n />\n {search && (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n className=\"absolute top-1/2 right-1 -translate-y-1/2\"\n aria-label={t('composites.table.search.clear')}\n onClick={() => setSearch('')}\n >\n <Icon name=\"i-lucide-x\" />\n </Button>\n )}\n </div>\n\n {selectFilters.map(filter => (\n <div key={filter.key} className=\"flex items-center gap-1.5\">\n <span className=\"text-sm text-muted-foreground\" aria-hidden=\"true\">{filter.label}</span>\n <Select\n value={pickedOptions[filter.key] ?? FILTER_ALL}\n onValueChange={value => setPickedOptions({ ...pickedOptions, [filter.key]: String(value) })}\n >\n <SelectTrigger size=\"sm\" className=\"w-36\" aria-label={filter.label}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {filter.items.map(item => <SelectItem key={item.value} value={item.value}>{item.label}</SelectItem>)}\n </SelectContent>\n </Select>\n </div>\n ))}\n\n {filterActive && (\n <Button size=\"sm\" variant=\"ghost\" onClick={resetFilters}>\n <Icon name=\"i-lucide-filter-x\" />\n {t('composites.table.filter.reset')}\n </Button>\n )}\n <span className=\"ml-auto text-xs text-muted-foreground tabular-nums\" role=\"status\">{countLabel}</span>\n </div>\n\n {kinds.length > 1 && (\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label={t('composites.table.filter.byKind')}>\n {kinds.map(kind => (\n <Button\n key={kind.id}\n size=\"xs\"\n variant={activeKinds.includes(kind.id) ? 'default' : 'outline'}\n aria-pressed={activeKinds.includes(kind.id)}\n onClick={() => setPickedKinds(toggled(pickedKinds, kind.id))}\n >\n <Icon name={kind.icon} />\n {kind.label}\n </Button>\n ))}\n </div>\n )}\n\n {tags.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label={t('composites.table.filter.byTag')}>\n {tags.map(tag => (\n <Button\n key={tag}\n size=\"xs\"\n variant={activeTags.includes(tag) ? 'default' : 'outline'}\n aria-pressed={activeTags.includes(tag)}\n onClick={() => setPickedTags(toggled(pickedTags, tag))}\n >\n {`#${tag}`}\n </Button>\n ))}\n </div>\n )}\n </div>\n\n {/* Own scroll container instead of `<Table>`'s: the sticky header needs the element that scrolls vertically. */}\n <div className=\"min-h-0 flex-1 overflow-auto rounded-md border border-border\">\n <table data-slot=\"table\" className=\"w-full caption-bottom text-sm\">\n <TableHeader className=\"sticky top-0 z-10 bg-background\">\n <TableRow className=\"hover:bg-transparent\">\n {specs.map(spec => (\n <TableHead\n key={spec.id}\n className={cn('h-auto px-3 py-2 text-sm', spec.id === 'title' && 'min-w-56', spec.align === 'end' && 'text-right')}\n aria-sort={activeSort?.id === spec.id ? (activeSort.desc ? 'descending' : 'ascending') : 'none'}\n >\n <button\n type=\"button\"\n className=\"-mx-1.5 inline-flex cursor-pointer items-center gap-1 rounded px-1.5 py-0.5 font-semibold hover:bg-muted focus-visible:outline-2 focus-visible:outline-primary\"\n onClick={() => cycleSort(spec.id)}\n >\n {spec.label}\n <Icon name={sortIcon(spec.id)} className={cn('size-3.5', activeSort?.id === spec.id ? 'text-foreground' : 'text-muted-foreground/70')} />\n </button>\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {sorted.length === 0\n ? (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell colSpan={columnCount} className=\"px-3 py-2 text-muted-foreground\">\n <div className=\"flex flex-col items-center gap-2 py-6\">\n <p className=\"text-sm text-muted-foreground\">\n {t('composites.table.filter.noMatch')}\n </p>\n <Button size=\"sm\" variant=\"outline\" onClick={resetFilters}>\n <Icon name=\"i-lucide-filter-x\" />\n {t('composites.table.filter.reset')}\n </Button>\n </div>\n </TableCell>\n </TableRow>\n )\n : sorted.map(row => (\n <TableRow key={row.key} className=\"cursor-pointer\" onClick={() => onSelect?.(row)}>\n {specs.map((spec) => {\n const cellClass = cn('px-3 py-2 text-muted-foreground', spec.align === 'end' && 'text-right')\n if (spec.id === 'title') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n <div className=\"flex min-w-0 items-center gap-1.5\" style={{ paddingLeft: `${row.depth * 1.25}rem` }}>\n <Icon name={row.icon} className=\"size-4 shrink-0 text-muted-foreground\" />\n {hasText(row.title)\n ? <span className=\"truncate font-medium text-foreground\">{row.title}</span>\n : <span className=\"truncate text-muted-foreground\">{t('composites.untitled')}</span>}\n </div>\n </TableCell>\n )\n }\n if (spec.id === 'kind') return <TableCell key={spec.id} className={cellClass}>{row.kindLabel}</TableCell>\n if (spec.id === 'tags') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n {row.tags.length\n ? (\n <div className=\"flex flex-wrap gap-1\">\n {row.tags.map(tag => <Badge key={tag} variant=\"secondary\">{`#${tag}`}</Badge>)}\n </div>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.table.noTags')}</span>\n </>\n )}\n </TableCell>\n )\n }\n if (spec.id === 'summary') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n {hasText(row.description)\n ? (\n <>\n <span className=\"inline-block size-2 rounded-full bg-primary\" aria-hidden=\"true\" title={row.description} />\n <span className=\"sr-only\">{t('composites.table.summaryPresent')}</span>\n </>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.summary.none')}</span>\n </>\n )}\n </TableCell>\n )\n }\n const column = fieldColumns.find(item => item.id === spec.id)\n if (!column) return <TableCell key={spec.id} className={cellClass} />\n const text = fieldText(row, column.field.key)\n return (\n <TableCell key={spec.id} className={cellClass}>\n {text\n ? (\n <span\n className={cn('block', (column.field.type === 'number' || column.field.type === 'date') && 'tabular-nums', isLongText(column.field) && 'max-w-64 truncate')}\n title={isLongText(column.field) ? text : undefined}\n >\n {text}\n </span>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.table.noValue')}</span>\n </>\n )}\n </TableCell>\n )\n })}\n </TableRow>\n ))}\n </TableBody>\n </table>\n </div>\n </>\n )}\n </section>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CompositeTable.js","names":[],"sources":["../../../../src/features/composites/react/CompositeTable.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useMemo, useState } from 'react'\nimport { Icon } from '../../../react/Icon'\nimport { Badge } from '../../../react/ui/badge'\nimport { Button } from '../../../react/ui/button'\nimport { Input } from '../../../react/ui/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../../react/ui/select'\nimport { TableBody, TableCell, TableHead, TableHeader, TableRow } from '../../../react/ui/table'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { compositeKindsOf } from '../nodes'\nimport type { CompositeRow } from '../rows'\nimport { columnSpecsOf, type FieldContext, FILTER_ALL, fieldColumnsOf, fieldOf, fieldText, hasText, isLongText, sortRows, toggled } from '../table-model'\nimport { useCompositeRows } from './use-composite-rows'\n\n// All Bausteine of an editor's document as a sortable, filterable table. Columns beyond the fixed ones derive from the\n// meta fields of the kinds present in the document, so a host kind with fields gets its columns without code changes.\n// The column specs, cell text and sorting are the framework-free `table-model`, shared with the Vue table.\n\n/** The table of an editor's Bausteine: sortable columns, filters by kind, tag and select fields, a text search; `onSelect` receives the clicked row. */\nexport function CompositeTable({ editor, onSelect, className }: {\n editor?: Editor\n onSelect?: (row: CompositeRow) => void\n className?: string\n}) {\n const { rows, tags, kinds } = useCompositeRows(editor)\n\n const { t } = useEditorI18n()\n // `reference` cells resolve their target in the document; re-read whenever the rows change.\n const fieldContext = useMemo<FieldContext | undefined>(() => (editor ? { doc: editor.state.doc, kinds: compositeKindsOf(editor), t } : undefined), [editor, rows, t])\n const fieldColumns = useMemo(() => fieldColumnsOf(rows, kinds, fieldContext), [rows, kinds, fieldContext])\n const specs = useMemo(() => columnSpecsOf(fieldColumns, t), [fieldColumns, t])\n\n const [search, setSearch] = useState('')\n const [pickedKinds, setPickedKinds] = useState<string[]>([])\n const [pickedTags, setPickedTags] = useState<string[]>([])\n const [pickedOptions, setPickedOptions] = useState<Record<string, string>>({})\n\n /** One select per `select` field in use; its choices are the union of the options of all kinds that have the key. */\n const selectFilters = useMemo(() => fieldColumns.flatMap((column) => {\n if (column.field.type !== 'select') return []\n const options = new Map<string, string>()\n for (const row of rows) {\n for (const option of fieldOf(row, column.field.key)?.options ?? []) if (!options.has(option.value)) options.set(option.value, option.label)\n }\n return [{\n key: column.field.key,\n label: column.field.label,\n items: [{ label: t('composites.table.filter.all'), value: FILTER_ALL }, ...[...options].map(([value, label]) => ({ label, value }))],\n }]\n }), [fieldColumns, rows, t])\n\n // A kind, tag or option that vanished from the document can no longer be unpicked in the UI, so it must not filter either.\n const activeKinds = useMemo(() => pickedKinds.filter(id => kinds.some(kind => kind.id === id)), [pickedKinds, kinds])\n const activeTags = useMemo(() => pickedTags.filter(tag => tags.includes(tag)), [pickedTags, tags])\n const activeOptions = useMemo(() => selectFilters.flatMap((filter) => {\n const value = pickedOptions[filter.key]\n return value && filter.items.some(item => item.value === value && value !== FILTER_ALL) ? [[filter.key, value] as const] : []\n }), [selectFilters, pickedOptions])\n const needle = search.trim().toLowerCase()\n const filterActive = activeKinds.length > 0 || activeTags.length > 0 || activeOptions.length > 0 || needle !== ''\n\n function resetFilters() {\n setSearch('')\n setPickedKinds([])\n setPickedTags([])\n setPickedOptions({})\n }\n\n const filtered = useMemo(() => rows.filter((row) => {\n if (activeKinds.length && !activeKinds.includes(row.kind)) return false\n if (activeTags.length && !activeTags.every(tag => row.tags.includes(tag))) return false\n if (activeOptions.some(([key, value]) => row.meta[key] !== value)) return false\n if (needle) {\n const haystack = `${row.title}\\n${row.description}\\n${row.tags.map(tag => `#${tag}`).join(' ')}`.toLowerCase()\n if (!haystack.includes(needle)) return false\n }\n return true\n }), [rows, activeKinds, activeTags, activeOptions, needle])\n\n // --- Sorting (client side, over the filtered rows) ---\n\n const [sorting, setSorting] = useState<{ id: string, desc: boolean } | null>(null)\n const activeSort = useMemo(() => {\n const spec = sorting && specs.find(item => item.id === sorting.id)\n return sorting && spec ? { id: sorting.id, desc: sorting.desc, sort: spec.sort } : null\n }, [sorting, specs])\n\n /** Header click cycles ascending → descending → unsorted. */\n function cycleSort(id: string) {\n setSorting(current => current?.id !== id ? { id, desc: false } : current.desc ? null : { id, desc: true })\n }\n const sortIcon = (id: string) => {\n if (sorting?.id !== id) return 'i-lucide-chevrons-up-down'\n return sorting.desc ? 'i-lucide-arrow-down' : 'i-lucide-arrow-up'\n }\n\n const sorted = useMemo(() => activeSort ? sortRows(filtered, activeSort.sort, activeSort.desc) : filtered, [filtered, activeSort])\n\n const countLabel = t(rows.length === 1 ? 'composites.table.count.one' : 'composites.table.count.other', { n: sorted.length, total: rows.length })\n const columnCount = specs.length\n\n return (\n <section className={cn('flex min-h-0 flex-col gap-3', className)} aria-label={t('composites.table.label')}>\n {!rows.length\n ? (\n <div className=\"mx-auto flex max-w-sm flex-1 flex-col items-center justify-center gap-2 py-16 text-center\">\n <Icon name=\"i-lucide-table-2\" className=\"size-8 text-muted-foreground/70\" />\n <p className=\"text-sm font-medium text-foreground\">\n {t('composites.table.emptyTitle')}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {t('composites.table.emptyText')}\n </p>\n </div>\n )\n : (\n <>\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <div className=\"relative w-64\">\n <Icon name=\"i-lucide-search\" className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n value={search}\n onChange={event => setSearch(event.target.value)}\n className={cn('h-7 pl-8 text-sm', search && 'pr-8')}\n placeholder={t('composites.table.search.placeholder')}\n aria-label={t('composites.table.search.label')}\n />\n {search && (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n className=\"absolute top-1/2 right-1 -translate-y-1/2\"\n aria-label={t('composites.table.search.clear')}\n onClick={() => setSearch('')}\n >\n <Icon name=\"i-lucide-x\" />\n </Button>\n )}\n </div>\n\n {selectFilters.map(filter => (\n <div key={filter.key} className=\"flex items-center gap-1.5\">\n <span className=\"text-sm text-muted-foreground\" aria-hidden=\"true\">{filter.label}</span>\n <Select\n value={pickedOptions[filter.key] ?? FILTER_ALL}\n onValueChange={value => setPickedOptions({ ...pickedOptions, [filter.key]: String(value) })}\n >\n <SelectTrigger size=\"sm\" className=\"w-36\" aria-label={filter.label}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {filter.items.map(item => <SelectItem key={item.value} value={item.value}>{item.label}</SelectItem>)}\n </SelectContent>\n </Select>\n </div>\n ))}\n\n {filterActive && (\n <Button size=\"sm\" variant=\"ghost\" onClick={resetFilters}>\n <Icon name=\"i-lucide-filter-x\" />\n {t('composites.table.filter.reset')}\n </Button>\n )}\n <span className=\"ml-auto text-xs text-muted-foreground tabular-nums\" role=\"status\">{countLabel}</span>\n </div>\n\n {kinds.length > 1 && (\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label={t('composites.table.filter.byKind')}>\n {kinds.map(kind => (\n <Button\n key={kind.id}\n size=\"xs\"\n variant={activeKinds.includes(kind.id) ? 'default' : 'outline'}\n aria-pressed={activeKinds.includes(kind.id)}\n onClick={() => setPickedKinds(toggled(pickedKinds, kind.id))}\n >\n <Icon name={kind.icon} />\n {kind.label}\n </Button>\n ))}\n </div>\n )}\n\n {tags.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label={t('composites.table.filter.byTag')}>\n {tags.map(tag => (\n <Button\n key={tag}\n size=\"xs\"\n variant={activeTags.includes(tag) ? 'default' : 'outline'}\n aria-pressed={activeTags.includes(tag)}\n onClick={() => setPickedTags(toggled(pickedTags, tag))}\n >\n {`#${tag}`}\n </Button>\n ))}\n </div>\n )}\n </div>\n\n {/* Own scroll container instead of `<Table>`'s: the sticky header needs the element that scrolls vertically. */}\n <div className=\"min-h-0 flex-1 overflow-auto rounded-md border border-border\">\n <table data-slot=\"table\" className=\"w-full caption-bottom text-sm\">\n <TableHeader className=\"sticky top-0 z-10 bg-background\">\n <TableRow className=\"hover:bg-transparent\">\n {specs.map(spec => (\n <TableHead\n key={spec.id}\n className={cn('h-auto px-3 py-2 text-sm', spec.id === 'title' && 'min-w-56', spec.align === 'end' && 'text-right')}\n aria-sort={activeSort?.id === spec.id ? (activeSort.desc ? 'descending' : 'ascending') : 'none'}\n >\n <button\n type=\"button\"\n className=\"-mx-1.5 inline-flex cursor-pointer items-center gap-1 rounded px-1.5 py-0.5 font-semibold hover:bg-muted focus-visible:outline-2 focus-visible:outline-primary\"\n onClick={() => cycleSort(spec.id)}\n >\n {spec.label}\n <Icon name={sortIcon(spec.id)} className={cn('size-3.5', activeSort?.id === spec.id ? 'text-foreground' : 'text-muted-foreground/70')} />\n </button>\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {sorted.length === 0\n ? (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell colSpan={columnCount} className=\"px-3 py-2 text-muted-foreground\">\n <div className=\"flex flex-col items-center gap-2 py-6\">\n <p className=\"text-sm text-muted-foreground\">\n {t('composites.table.filter.noMatch')}\n </p>\n <Button size=\"sm\" variant=\"outline\" onClick={resetFilters}>\n <Icon name=\"i-lucide-filter-x\" />\n {t('composites.table.filter.reset')}\n </Button>\n </div>\n </TableCell>\n </TableRow>\n )\n : sorted.map(row => (\n <TableRow key={row.key} className=\"cursor-pointer\" onClick={() => onSelect?.(row)}>\n {specs.map((spec) => {\n const cellClass = cn('px-3 py-2 text-muted-foreground', spec.align === 'end' && 'text-right')\n if (spec.id === 'title') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n <div className=\"flex min-w-0 items-center gap-1.5\" style={{ paddingLeft: `${row.depth * 1.25}rem` }}>\n <Icon name={row.icon} className=\"size-4 shrink-0 text-muted-foreground\" />\n {hasText(row.title)\n ? <span className=\"truncate font-medium text-foreground\">{row.title}</span>\n : <span className=\"truncate text-muted-foreground\">{t('composites.untitled')}</span>}\n </div>\n </TableCell>\n )\n }\n if (spec.id === 'kind') return <TableCell key={spec.id} className={cellClass}>{row.kindLabel}</TableCell>\n if (spec.id === 'tags') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n {row.tags.length\n ? (\n <div className=\"flex flex-wrap gap-1\">\n {row.tags.map(tag => <Badge key={tag} variant=\"secondary\">{`#${tag}`}</Badge>)}\n </div>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.table.noTags')}</span>\n </>\n )}\n </TableCell>\n )\n }\n if (spec.id === 'summary') {\n return (\n <TableCell key={spec.id} className={cellClass}>\n {hasText(row.description)\n ? (\n <>\n <span className=\"inline-block size-2 rounded-full bg-primary\" aria-hidden=\"true\" title={row.description} />\n <span className=\"sr-only\">{t('composites.table.summaryPresent')}</span>\n </>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.summary.none')}</span>\n </>\n )}\n </TableCell>\n )\n }\n const column = fieldColumns.find(item => item.id === spec.id)\n if (!column) return <TableCell key={spec.id} className={cellClass} />\n const text = fieldText(row, column.field.key, fieldContext)\n return (\n <TableCell key={spec.id} className={cellClass}>\n {text\n ? (\n <span\n className={cn('block', (column.field.type === 'number' || column.field.type === 'date') && 'tabular-nums', isLongText(column.field) && 'max-w-64 truncate')}\n title={isLongText(column.field) ? text : undefined}\n >\n {text}\n </span>\n )\n : (\n <>\n <span className=\"text-muted-foreground/70\" aria-hidden=\"true\">–</span>\n <span className=\"sr-only\">{t('composites.table.noValue')}</span>\n </>\n )}\n </TableCell>\n )\n })}\n </TableRow>\n ))}\n </TableBody>\n </table>\n </div>\n </>\n )}\n </section>\n )\n}\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { metadataOf } from "../../../core/metadata.js";
2
2
  import { METADATA_LIST } from "../../../core/metadata-types.js";
3
+ import { normalizeTagName } from "../../../core/tag-name.js";
3
4
  import { useEditorI18n } from "../../../react/use-editor-i18n.js";
4
5
  import { Icon } from "../../../react/Icon.js";
5
- import { setCompositeTags } from "../rows.js";
6
- import { normalizeTagName } from "../../../core/tag-name.js";
7
6
  import { Command, CommandInput, CommandItem, CommandList } from "../../../react/ui/command.js";
7
+ import { setCompositeTags } from "../rows.js";
8
8
  import { useEffect, useRef, useState } from "react";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
10
  //#region src/features/composites/react/CompositeTagsEditor.tsx
@@ -1,6 +1,8 @@
1
1
  import { compositeKind } from "../kinds.js";
2
+ import { derivationOf } from "../derivation.js";
2
3
  import { compositeKindsOf } from "../nodes.js";
3
4
  import { cn } from "../../../react/ui/utils.js";
5
+ import { useStore } from "../../../react/use-store.js";
4
6
  import { jsx, jsxs } from "react/jsx-runtime";
5
7
  import { NodeViewContent, NodeViewWrapper } from "@tiptap/react";
6
8
  //#region src/features/composites/react/CompositeView.tsx
@@ -9,10 +11,13 @@ const cssString = (text) => `"${text.replace(/["\\]/g, "\\$&").replace(/\n/g, "\
9
11
  /** The composite block: the section with its content. The kind icon is drawn by the composite chrome overlay. */
10
12
  function CompositeView({ editor, node, selected }) {
11
13
  const kind = compositeKind(compositeKindsOf(editor), String(node.attrs.kind));
14
+ const expanded = useStore(editor.storage.composite.expanded);
15
+ const id = node.attrs.id;
16
+ const collapsed = typeof id === "string" && id !== "" && derivationOf(node) !== null && !expanded.has(id);
12
17
  const placeholderVars = { "--composite-title-placeholder": cssString(kind.titlePlaceholder) };
13
18
  return /* @__PURE__ */ jsxs(NodeViewWrapper, {
14
19
  as: "section",
15
- className: cn("composite", selected && "is-selected rounded-md ring-1 ring-primary"),
20
+ className: cn("composite", collapsed && "is-collapsed", selected && "is-selected rounded-md ring-1 ring-primary"),
16
21
  "data-type": "composite",
17
22
  "data-kind": node.attrs.kind,
18
23
  "data-id": node.attrs.id || void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"CompositeView.js","names":[],"sources":["../../../../src/features/composites/react/CompositeView.tsx"],"sourcesContent":["import { NodeViewContent, NodeViewWrapper, type NodeViewProps } from '@tiptap/react'\nimport type { CSSProperties } from 'react'\nimport { cn } from '../../../react/ui/utils'\nimport { compositeKind } from '../kinds'\nimport { compositeKindsOf } from '../nodes'\n\n/** `text` as a CSS string literal (for `content:`). */\nconst cssString = (text: string) => `\"${text.replace(/[\"\\\\]/g, '\\\\$&').replace(/\\n/g, '\\\\a ')}\"`\n\n/** The composite block: the section with its content. The kind icon is drawn by the composite chrome overlay. */\nexport function CompositeView({ editor, node, selected }: NodeViewProps) {\n const kind = compositeKind(compositeKindsOf(editor), String(node.attrs.kind))\n // Placeholder of the empty title (composites.css `content: var(…)`); a nested composite sets its own.\n const placeholderVars = { '--composite-title-placeholder': cssString(kind.titlePlaceholder) } as CSSProperties\n return (\n <NodeViewWrapper\n as=\"section\"\n className={cn('composite', selected && 'is-selected rounded-md ring-1 ring-primary')}\n data-type=\"composite\"\n data-kind={node.attrs.kind}\n data-id={node.attrs.id || undefined}\n style={placeholderVars}\n >\n {/* Anchor of the kind icon on the left border: it only takes the icon's place and size. The composite chrome overlay\n measures it and draws the icon as the button that opens the details popover and drags the composite. */}\n <span className=\"composite__toggle\" contentEditable={false} aria-hidden=\"true\" />\n <NodeViewContent className=\"composite__content\" />\n </NodeViewWrapper>\n )\n}\n"],"mappings":";;;;;;;AAOA,MAAM,aAAa,SAAiB,IAAI,KAAK,QAAQ,UAAU,MAAM,CAAC,CAAC,QAAQ,OAAO,MAAM,EAAE;;AAG9F,SAAgB,cAAc,EAAE,QAAQ,MAAM,YAA2B;CACvE,MAAM,OAAO,cAAc,iBAAiB,MAAM,GAAG,OAAO,KAAK,MAAM,IAAI,CAAC;CAE5E,MAAM,kBAAkB,EAAE,iCAAiC,UAAU,KAAK,gBAAgB,EAAE;CAC5F,OACE,qBAAC,iBAAD;EACE,IAAG;EACH,WAAW,GAAG,aAAa,YAAY,4CAA4C;EACnF,aAAU;EACV,aAAW,KAAK,MAAM;EACtB,WAAS,KAAK,MAAM,MAAM,KAAA;EAC1B,OAAO;EANT,UAAA,CAUE,oBAAC,QAAD;GAAM,WAAU;GAAoB,iBAAiB;GAAO,eAAY;EAAQ,CAAA,GAChF,oBAAC,iBAAD,EAAiB,WAAU,qBAAsB,CAAA,CAClC;;AAErB"}
1
+ {"version":3,"file":"CompositeView.js","names":[],"sources":["../../../../src/features/composites/react/CompositeView.tsx"],"sourcesContent":["import { NodeViewContent, NodeViewWrapper, type NodeViewProps } from '@tiptap/react'\nimport type { CSSProperties } from 'react'\nimport { cn } from '../../../react/ui/utils'\nimport { compositeKind } from '../kinds'\nimport { useStore } from '../../../react/use-store'\nimport { derivationOf } from '../derivation'\nimport { compositeKindsOf } from '../nodes'\n\n/** `text` as a CSS string literal (for `content:`). */\nconst cssString = (text: string) => `\"${text.replace(/[\"\\\\]/g, '\\\\$&').replace(/\\n/g, '\\\\a ')}\"`\n\n/** The composite block: the section with its content. The kind icon is drawn by the composite chrome overlay. */\nexport function CompositeView({ editor, node, selected }: NodeViewProps) {\n const kind = compositeKind(compositeKindsOf(editor), String(node.attrs.kind))\n // A derived Baustein (one with a `meta.derivation`) shows collapsed to a faded preview until it is opened; the content\n // stays laid out (CSS clips it), so editing positions are unaffected. The chrome's chevron and a caret inside open it.\n const expanded = useStore(editor.storage.composite.expanded)\n const id: unknown = node.attrs.id\n const collapsed = typeof id === 'string' && id !== '' && derivationOf(node) !== null && !expanded.has(id)\n // Placeholder of the empty title (composites.css `content: var(…)`); a nested composite sets its own.\n const placeholderVars = { '--composite-title-placeholder': cssString(kind.titlePlaceholder) } as CSSProperties\n return (\n <NodeViewWrapper\n as=\"section\"\n className={cn('composite', collapsed && 'is-collapsed', selected && 'is-selected rounded-md ring-1 ring-primary')}\n data-type=\"composite\"\n data-kind={node.attrs.kind}\n data-id={node.attrs.id || undefined}\n style={placeholderVars}\n >\n {/* Anchor of the kind icon on the left border: it only takes the icon's place and size. The composite chrome overlay\n measures it and draws the icon as the button that opens the details popover and drags the composite. */}\n <span className=\"composite__toggle\" contentEditable={false} aria-hidden=\"true\" />\n <NodeViewContent className=\"composite__content\" />\n </NodeViewWrapper>\n )\n}\n"],"mappings":";;;;;;;;;AASA,MAAM,aAAa,SAAiB,IAAI,KAAK,QAAQ,UAAU,MAAM,CAAC,CAAC,QAAQ,OAAO,MAAM,EAAE;;AAG9F,SAAgB,cAAc,EAAE,QAAQ,MAAM,YAA2B;CACvE,MAAM,OAAO,cAAc,iBAAiB,MAAM,GAAG,OAAO,KAAK,MAAM,IAAI,CAAC;CAG5E,MAAM,WAAW,SAAS,OAAO,QAAQ,UAAU,QAAQ;CAC3D,MAAM,KAAc,KAAK,MAAM;CAC/B,MAAM,YAAY,OAAO,OAAO,YAAY,OAAO,MAAM,aAAa,IAAI,MAAM,QAAQ,CAAC,SAAS,IAAI,EAAE;CAExG,MAAM,kBAAkB,EAAE,iCAAiC,UAAU,KAAK,gBAAgB,EAAE;CAC5F,OACE,qBAAC,iBAAD;EACE,IAAG;EACH,WAAW,GAAG,aAAa,aAAa,gBAAgB,YAAY,4CAA4C;EAChH,aAAU;EACV,aAAW,KAAK,MAAM;EACtB,WAAS,KAAK,MAAM,MAAM,KAAA;EAC1B,OAAO;EANT,UAAA,CAUE,oBAAC,QAAD;GAAM,WAAU;GAAoB,iBAAiB;GAAO,eAAY;EAAQ,CAAA,GAChF,oBAAC,iBAAD,EAAiB,WAAU,qBAAsB,CAAA,CAClC;;AAErB"}
@@ -0,0 +1,116 @@
1
+ import { derivationOf } from "../derivation.js";
2
+ import { useEditorI18n } from "../../../react/use-editor-i18n.js";
3
+ import { cn } from "../../../react/ui/utils.js";
4
+ import { Icon } from "../../../react/Icon.js";
5
+ import { derivationDetailsOf, derivationMethodLabel } from "../derived-chrome.js";
6
+ import { formatDate } from "../meta-display.js";
7
+ import { useMemo } from "react";
8
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
+ //#region src/features/composites/react/DerivationBadge.tsx
10
+ const CHIP = "inline-flex h-5 shrink-0 items-center gap-1 rounded-sm px-1.5 text-xs leading-none whitespace-nowrap";
11
+ /**
12
+ * Where a derived Baustein comes from. Compact (the `derivation` field type): the „abgeleitet“ badge with method and
13
+ * date. `detailed` (the details card): also the model, whether the source changed („Quelle geändert“), whether the body
14
+ * was edited since it was generated („bearbeitet“) and a link to the stored raw output. The detailed variant hashes
15
+ * the body, so it belongs only where one Baustein is shown.
16
+ */
17
+ function DerivationBadge({ editor, node, detailed }) {
18
+ const { t } = useEditorI18n();
19
+ const derivation = derivationOf(node);
20
+ const details = useMemo(() => detailed ? derivationDetailsOf(editor, node) : null, [
21
+ detailed,
22
+ editor,
23
+ node
24
+ ]);
25
+ if (!derivation) return null;
26
+ const method = derivationMethodLabel(t, derivation.method);
27
+ const created = derivation.createdAt ? formatDate(derivation.createdAt) : "";
28
+ if (!detailed) return /* @__PURE__ */ jsxs("div", {
29
+ className: "flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground",
30
+ children: [/* @__PURE__ */ jsx(Icon, {
31
+ name: "i-lucide-git-branch",
32
+ className: "size-3.5 shrink-0"
33
+ }), /* @__PURE__ */ jsx("span", {
34
+ className: "truncate",
35
+ children: [
36
+ t("composites.derivation.badge"),
37
+ method,
38
+ created
39
+ ].filter(Boolean).join(" · ")
40
+ })]
41
+ });
42
+ if (!details) return null;
43
+ return /* @__PURE__ */ jsxs("div", {
44
+ className: "flex flex-col gap-1.5 rounded-md p-2 text-xs ring-1 ring-border",
45
+ children: [
46
+ /* @__PURE__ */ jsxs("div", {
47
+ className: "flex flex-wrap items-center gap-1",
48
+ children: [
49
+ /* @__PURE__ */ jsxs("span", {
50
+ className: cn(CHIP, "text-muted-foreground"),
51
+ children: [/* @__PURE__ */ jsx(Icon, {
52
+ name: "i-lucide-git-branch",
53
+ className: "size-3.5"
54
+ }), t("composites.derivation.badge")]
55
+ }),
56
+ details.stale && /* @__PURE__ */ jsxs("span", {
57
+ className: cn(CHIP, "text-(--sk-warning)"),
58
+ children: [/* @__PURE__ */ jsx(Icon, {
59
+ name: "i-lucide-triangle-alert",
60
+ className: "size-3.5"
61
+ }), t("composites.derivation.stale")]
62
+ }),
63
+ details.edited && /* @__PURE__ */ jsxs("span", {
64
+ className: cn(CHIP, "text-muted-foreground"),
65
+ children: [/* @__PURE__ */ jsx(Icon, {
66
+ name: "i-lucide-pencil",
67
+ className: "size-3.5"
68
+ }), t("composites.derivation.edited")]
69
+ })
70
+ ]
71
+ }),
72
+ /* @__PURE__ */ jsxs("dl", {
73
+ className: "grid grid-cols-[auto_1fr] gap-x-2 gap-y-0.5",
74
+ children: [
75
+ /* @__PURE__ */ jsx("dt", {
76
+ className: "text-muted-foreground",
77
+ children: t("composites.derivation.method")
78
+ }),
79
+ /* @__PURE__ */ jsx("dd", {
80
+ className: "truncate text-foreground",
81
+ children: method
82
+ }),
83
+ derivation.model && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("dt", {
84
+ className: "text-muted-foreground",
85
+ children: t("composites.derivation.model")
86
+ }), /* @__PURE__ */ jsx("dd", {
87
+ className: "truncate text-foreground",
88
+ title: derivation.model,
89
+ children: derivation.model
90
+ })] }),
91
+ created && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("dt", {
92
+ className: "text-muted-foreground",
93
+ children: t("composites.derivation.createdAt")
94
+ }), /* @__PURE__ */ jsx("dd", {
95
+ className: "text-foreground",
96
+ children: created
97
+ })] })
98
+ ]
99
+ }),
100
+ details.outputUrl && /* @__PURE__ */ jsxs("a", {
101
+ href: details.outputUrl,
102
+ target: "_blank",
103
+ rel: "noopener",
104
+ className: "inline-flex w-fit items-center gap-1 text-primary hover:underline",
105
+ children: [/* @__PURE__ */ jsx(Icon, {
106
+ name: "i-lucide-external-link",
107
+ className: "size-3.5"
108
+ }), t("composites.derivation.openOutput")]
109
+ })
110
+ ]
111
+ });
112
+ }
113
+ //#endregion
114
+ export { DerivationBadge };
115
+
116
+ //# sourceMappingURL=DerivationBadge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DerivationBadge.js","names":[],"sources":["../../../../src/features/composites/react/DerivationBadge.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { useMemo } from 'react'\nimport { Icon } from '../../../react/Icon'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { derivationOf } from '../derivation'\nimport { derivationDetailsOf, derivationMethodLabel } from '../derived-chrome'\nimport { formatDate } from '../meta-display'\n\nconst CHIP = 'inline-flex h-5 shrink-0 items-center gap-1 rounded-sm px-1.5 text-xs leading-none whitespace-nowrap'\n\n/**\n * Where a derived Baustein comes from. Compact (the `derivation` field type): the „abgeleitet“ badge with method and\n * date. `detailed` (the details card): also the model, whether the source changed („Quelle geändert“), whether the body\n * was edited since it was generated („bearbeitet“) and a link to the stored raw output. The detailed variant hashes\n * the body, so it belongs only where one Baustein is shown.\n */\nexport function DerivationBadge({ editor, node, detailed }: { editor: Editor, node: ProseMirrorNode, detailed?: boolean }) {\n const { t } = useEditorI18n()\n const derivation = derivationOf(node)\n const details = useMemo(() => detailed ? derivationDetailsOf(editor, node) : null, [detailed, editor, node])\n if (!derivation) return null\n const method = derivationMethodLabel(t, derivation.method)\n const created = derivation.createdAt ? formatDate(derivation.createdAt) : ''\n\n if (!detailed) {\n return (\n <div className=\"flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground\">\n <Icon name=\"i-lucide-git-branch\" className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\">{[t('composites.derivation.badge'), method, created].filter(Boolean).join(' · ')}</span>\n </div>\n )\n }\n if (!details) return null\n\n return (\n <div className=\"flex flex-col gap-1.5 rounded-md p-2 text-xs ring-1 ring-border\">\n <div className=\"flex flex-wrap items-center gap-1\">\n <span className={cn(CHIP, 'text-muted-foreground')}>\n <Icon name=\"i-lucide-git-branch\" className=\"size-3.5\" />{t('composites.derivation.badge')}\n </span>\n {details.stale && (\n <span className={cn(CHIP, 'text-(--sk-warning)')}>\n <Icon name=\"i-lucide-triangle-alert\" className=\"size-3.5\" />{t('composites.derivation.stale')}\n </span>\n )}\n {details.edited && (\n <span className={cn(CHIP, 'text-muted-foreground')}>\n <Icon name=\"i-lucide-pencil\" className=\"size-3.5\" />{t('composites.derivation.edited')}\n </span>\n )}\n </div>\n <dl className=\"grid grid-cols-[auto_1fr] gap-x-2 gap-y-0.5\">\n <dt className=\"text-muted-foreground\">{t('composites.derivation.method')}</dt>\n <dd className=\"truncate text-foreground\">{method}</dd>\n {derivation.model && (\n <>\n <dt className=\"text-muted-foreground\">{t('composites.derivation.model')}</dt>\n <dd className=\"truncate text-foreground\" title={derivation.model}>{derivation.model}</dd>\n </>\n )}\n {created && (\n <>\n <dt className=\"text-muted-foreground\">{t('composites.derivation.createdAt')}</dt>\n <dd className=\"text-foreground\">{created}</dd>\n </>\n )}\n </dl>\n {details.outputUrl && (\n <a href={details.outputUrl} target=\"_blank\" rel=\"noopener\" className=\"inline-flex w-fit items-center gap-1 text-primary hover:underline\">\n <Icon name=\"i-lucide-external-link\" className=\"size-3.5\" />{t('composites.derivation.openOutput')}\n </a>\n )}\n </div>\n )\n}\n"],"mappings":";;;;;;;;;AAUA,MAAM,OAAO;;;;;;;AAQb,SAAgB,gBAAgB,EAAE,QAAQ,MAAM,YAA2E;CACzH,MAAM,EAAE,MAAM,cAAc;CAC5B,MAAM,aAAa,aAAa,IAAI;CACpC,MAAM,UAAU,cAAc,WAAW,oBAAoB,QAAQ,IAAI,IAAI,MAAM;EAAC;EAAU;EAAQ;CAAI,CAAC;CAC3G,IAAI,CAAC,YAAY,OAAO;CACxB,MAAM,SAAS,sBAAsB,GAAG,WAAW,MAAM;CACzD,MAAM,UAAU,WAAW,YAAY,WAAW,WAAW,SAAS,IAAI;CAE1E,IAAI,CAAC,UACH,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,MAAD;GAAM,MAAK;GAAsB,WAAU;EAAqB,CAAA,GAChE,oBAAC,QAAD;GAAM,WAAU;GAAY,UAAA;IAAC,EAAE,6BAA6B;IAAG;IAAQ;GAAO,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK;EAAQ,CAAA,CAC/G;;CAGT,IAAI,CAAC,SAAS,OAAO;CAErB,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,qBAAC,QAAD;MAAM,WAAW,GAAG,MAAM,uBAAuB;MAAjD,UAAA,CACE,oBAAC,MAAD;OAAM,MAAK;OAAsB,WAAU;MAAY,CAAA,GAAE,EAAE,6BAA6B,CACpF;;KACL,QAAQ,SACP,qBAAC,QAAD;MAAM,WAAW,GAAG,MAAM,qBAAqB;MAA/C,UAAA,CACE,oBAAC,MAAD;OAAM,MAAK;OAA0B,WAAU;MAAY,CAAA,GAAE,EAAE,6BAA6B,CACxF;;KAEP,QAAQ,UACP,qBAAC,QAAD;MAAM,WAAW,GAAG,MAAM,uBAAuB;MAAjD,UAAA,CACE,oBAAC,MAAD;OAAM,MAAK;OAAkB,WAAU;MAAY,CAAA,GAAE,EAAE,8BAA8B,CACjF;;IAEL;;GACL,qBAAC,MAAD;IAAI,WAAU;IAAd,UAAA;KACE,oBAAC,MAAD;MAAI,WAAU;MAAyB,UAAA,EAAE,8BAA8B;KAAM,CAAA;KAC7E,oBAAC,MAAD;MAAI,WAAU;MAA4B,UAAA;KAAW,CAAA;KACpD,WAAW,SACV,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,MAAD;MAAI,WAAU;MAAyB,UAAA,EAAE,6BAA6B;KAAM,CAAA,GAC5E,oBAAC,MAAD;MAAI,WAAU;MAA2B,OAAO,WAAW;MAAQ,UAAA,WAAW;KAAU,CAAA,CACxF,EAAA,CAAA;KAEH,WACC,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,MAAD;MAAI,WAAU;MAAyB,UAAA,EAAE,iCAAiC;KAAM,CAAA,GAChF,oBAAC,MAAD;MAAI,WAAU;MAAmB,UAAA;KAAY,CAAA,CAC7C,EAAA,CAAA;IAEF;;GACH,QAAQ,aACP,qBAAC,KAAD;IAAG,MAAM,QAAQ;IAAW,QAAO;IAAS,KAAI;IAAW,WAAU;IAArE,UAAA,CACE,oBAAC,MAAD;KAAM,MAAK;KAAyB,WAAU;IAAY,CAAA,GAAE,EAAE,kCAAkC,CAC/F;;EAEF;;AAET"}
@@ -0,0 +1,52 @@
1
+ import { useEditorI18n } from "../../../react/use-editor-i18n.js";
2
+ import { cn } from "../../../react/ui/utils.js";
3
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../../react/ui/select.js";
4
+ import { setCompositeMetaField } from "../rows.js";
5
+ import { metaText } from "../meta-display.js";
6
+ import { useCompositeRows } from "./use-composite-rows.js";
7
+ import { useMemo } from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ //#region src/features/composites/react/ReferenceFieldSelect.tsx
10
+ /** Radix Select has no empty-string value: the "no reference" item travels as this sentinel. */
11
+ const NONE = "__none__";
12
+ const SELECT_SIZE = {
13
+ xs: "data-[size=sm]:h-6 text-xs",
14
+ sm: "data-[size=sm]:h-7",
15
+ md: ""
16
+ };
17
+ /** The select of a `reference` field: the other Bausteine of the document (with a block ID, of the field's target kinds) by title. */
18
+ function ReferenceFieldSelect({ editor, row, field, disabled, size = "sm" }) {
19
+ const { t } = useEditorI18n();
20
+ const { rows } = useCompositeRows(editor);
21
+ const stored = metaText(row, field);
22
+ const options = useMemo(() => rows.filter((candidate) => candidate.id !== null && candidate.id !== row.id && (!field.targets || field.targets.includes(candidate.kind))).map((candidate) => ({
23
+ label: `${candidate.title.trim() || t("composites.inspector.untitled")} · ${candidate.kindLabel}`,
24
+ value: candidate.id
25
+ })), [
26
+ rows,
27
+ row.id,
28
+ field.targets,
29
+ t
30
+ ]);
31
+ return /* @__PURE__ */ jsxs(Select, {
32
+ value: stored,
33
+ onValueChange: (value) => setCompositeMetaField(editor, row, field.key, value === NONE ? "" : value),
34
+ disabled,
35
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
36
+ size: "sm",
37
+ className: cn("w-full", SELECT_SIZE[size]),
38
+ "aria-label": field.label,
39
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("composites.field.choose", { field: field.label }) })
40
+ }), /* @__PURE__ */ jsxs(SelectContent, { children: [/* @__PURE__ */ jsx(SelectItem, {
41
+ value: NONE,
42
+ children: t("composites.field.none")
43
+ }), options.map((option) => /* @__PURE__ */ jsx(SelectItem, {
44
+ value: option.value,
45
+ children: option.label
46
+ }, option.value))] })]
47
+ });
48
+ }
49
+ //#endregion
50
+ export { ReferenceFieldSelect };
51
+
52
+ //# sourceMappingURL=ReferenceFieldSelect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReferenceFieldSelect.js","names":[],"sources":["../../../../src/features/composites/react/ReferenceFieldSelect.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { useMemo } from 'react'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../../react/ui/select'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport type { CompositeMetaField } from '../kinds'\nimport { metaText } from '../meta-display'\nimport { type CompositeRow, setCompositeMetaField } from '../rows'\nimport { useCompositeRows } from './use-composite-rows'\n\n/** Radix Select has no empty-string value: the \"no reference\" item travels as this sentinel. */\nconst NONE = '__none__'\n\nconst SELECT_SIZE = {\n xs: 'data-[size=sm]:h-6 text-xs',\n sm: 'data-[size=sm]:h-7',\n md: '',\n}\n\n/** The select of a `reference` field: the other Bausteine of the document (with a block ID, of the field's target kinds) by title. */\nexport function ReferenceFieldSelect({ editor, row, field, disabled, size = 'sm' }: {\n editor: Editor\n row: CompositeRow\n field: CompositeMetaField\n disabled?: boolean\n size?: 'xs' | 'sm' | 'md'\n}) {\n const { t } = useEditorI18n()\n const { rows } = useCompositeRows(editor)\n const stored = metaText(row, field)\n const options = useMemo(() => rows\n .filter(candidate => candidate.id !== null && candidate.id !== row.id && (!field.targets || field.targets.includes(candidate.kind)))\n .map(candidate => ({ label: `${candidate.title.trim() || t('composites.inspector.untitled')} · ${candidate.kindLabel}`, value: candidate.id as string })), [rows, row.id, field.targets, t])\n\n return (\n <Select value={stored} onValueChange={value => setCompositeMetaField(editor, row, field.key, value === NONE ? '' : value)} disabled={disabled}>\n <SelectTrigger size=\"sm\" className={cn('w-full', SELECT_SIZE[size])} aria-label={field.label}>\n <SelectValue placeholder={t('composites.field.choose', { field: field.label })} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>{t('composites.field.none')}</SelectItem>\n {options.map(option => (\n <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n"],"mappings":";;;;;;;;;;AAWA,MAAM,OAAO;AAEb,MAAM,cAAc;CAClB,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,SAAgB,qBAAqB,EAAE,QAAQ,KAAK,OAAO,UAAU,OAAO,QAMzE;CACD,MAAM,EAAE,MAAM,cAAc;CAC5B,MAAM,EAAE,SAAS,iBAAiB,MAAM;CACxC,MAAM,SAAS,SAAS,KAAK,KAAK;CAClC,MAAM,UAAU,cAAc,KAC3B,QAAO,cAAa,UAAU,OAAO,QAAQ,UAAU,OAAO,IAAI,OAAO,CAAC,MAAM,WAAW,MAAM,QAAQ,SAAS,UAAU,IAAI,EAAE,CAAC,CACnI,KAAI,eAAc;EAAE,OAAO,GAAG,UAAU,MAAM,KAAK,KAAK,EAAE,+BAA+B,EAAE,KAAK,UAAU;EAAa,OAAO,UAAU;CAAa,EAAE,GAAG;EAAC;EAAM,IAAI;EAAI,MAAM;EAAS;CAAC,CAAC;CAE7L,OACE,qBAAC,QAAD;EAAQ,OAAO;EAAQ,gBAAe,UAAS,sBAAsB,QAAQ,KAAK,MAAM,KAAK,UAAU,OAAO,KAAK,KAAK;EAAa;EAArI,UAAA,CACE,oBAAC,eAAD;GAAe,MAAK;GAAK,WAAW,GAAG,UAAU,YAAY,KAAK;GAAG,cAAY,MAAM;GACrF,UAAA,oBAAC,aAAD,EAAa,aAAa,EAAE,2BAA2B,EAAE,OAAO,MAAM,MAAM,CAAC,EAAI,CAAA;EACpE,CAAA,GACf,qBAAC,eAAD,EAAA,UAAA,CACE,oBAAC,YAAD;GAAY,OAAO;GAAO,UAAA,EAAE,uBAAuB;EAAc,CAAA,GAChE,QAAQ,KAAI,WACX,oBAAC,YAAD;GAA+B,OAAO,OAAO;GAAQ,UAAA,OAAO;EAAkB,GAA7D,OAAO,KAAsD,CAC/E,CACY,EAAA,CAAA,CACT;;AAEZ"}
@@ -0,0 +1,11 @@
1
+ import { NodeViewProps } from "@tiptap/react";
2
+ //#region src/features/composites/react/ReferenceView.d.ts
3
+ /**
4
+ * The `reference` chip: the live short citation (or title) of the Baustein it points at, followed by its locator.
5
+ * A click reveals the target and, with a locator, opens its source there (page of a PDF, time of a recording); a
6
+ * target that no longer exists shows a greyed „gone“ label. Double click or right click opens a popover to set the
7
+ * locator („Stelle“) in an editable editor.
8
+ */
9
+ export declare function ReferenceView({ editor, node, selected, getPos }: NodeViewProps): import("react").JSX.Element;
10
+ //#endregion
11
+ //# sourceMappingURL=ReferenceView.d.ts.map
@@ -0,0 +1,115 @@
1
+ import { useEditorI18n } from "../../../react/use-editor-i18n.js";
2
+ import { cn } from "../../../react/ui/utils.js";
3
+ import { Input } from "../../../react/ui/input.js";
4
+ import { Popover, PopoverAnchor, PopoverContent } from "../../../react/ui/popover.js";
5
+ import { referenceAttrsOf, resolveReference } from "../reference-label.js";
6
+ import { revealSource } from "../reveal-source.js";
7
+ import { useEffect, useState } from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { NodeViewWrapper } from "@tiptap/react";
10
+ //#region src/features/composites/react/ReferenceView.tsx
11
+ /**
12
+ * The `reference` chip: the live short citation (or title) of the Baustein it points at, followed by its locator.
13
+ * A click reveals the target and, with a locator, opens its source there (page of a PDF, time of a recording); a
14
+ * target that no longer exists shows a greyed „gone“ label. Double click or right click opens a popover to set the
15
+ * locator („Stelle“) in an editable editor.
16
+ */
17
+ function ReferenceView({ editor, node, selected, getPos }) {
18
+ const { t } = useEditorI18n();
19
+ const [resolved, setResolved] = useState(() => resolveReference(editor, referenceAttrsOf(node)));
20
+ const [open, setOpen] = useState(false);
21
+ const [draft, setDraft] = useState("");
22
+ const target = String(node.attrs.target);
23
+ const locator = typeof node.attrs.locator === "string" ? node.attrs.locator : "";
24
+ useEffect(() => {
25
+ let frame = 0;
26
+ const resolve = () => {
27
+ if (editor.isDestroyed) return;
28
+ const next = resolveReference(editor, {
29
+ target,
30
+ label: String(node.attrs.label ?? "")
31
+ });
32
+ setResolved((current) => next.label === current.label && next.title === current.title && next.gone === current.gone ? current : next);
33
+ };
34
+ const schedule = () => {
35
+ cancelAnimationFrame(frame);
36
+ frame = requestAnimationFrame(resolve);
37
+ };
38
+ resolve();
39
+ editor.on("update", schedule);
40
+ return () => {
41
+ cancelAnimationFrame(frame);
42
+ editor.off("update", schedule);
43
+ };
44
+ }, [
45
+ editor,
46
+ target,
47
+ node.attrs.label
48
+ ]);
49
+ const label = resolved.gone ? t("composites.reference.gone") : resolved.label;
50
+ const text = locator && !resolved.gone ? `${label}, ${locator}` : label;
51
+ function onClick() {
52
+ if (!editor.commands.revealBlock(target)) return;
53
+ if (locator) revealSource(editor, target, locator);
54
+ }
55
+ function openLocator() {
56
+ if (!editor.isEditable) return;
57
+ setDraft(locator);
58
+ setOpen(true);
59
+ }
60
+ function commit() {
61
+ setOpen(false);
62
+ const pos = getPos();
63
+ if (typeof pos !== "number" || draft.trim() === locator) return;
64
+ editor.commands.setReferenceLocator(pos, draft);
65
+ }
66
+ return /* @__PURE__ */ jsx(NodeViewWrapper, {
67
+ as: "span",
68
+ className: cn("reference", resolved.gone && "is-gone", selected && "is-selected"),
69
+ "data-type": "reference",
70
+ "data-target": target,
71
+ title: resolved.gone ? void 0 : resolved.title,
72
+ role: "link",
73
+ onClick,
74
+ onDoubleClick: (event) => {
75
+ event.preventDefault();
76
+ openLocator();
77
+ },
78
+ onContextMenu: (event) => {
79
+ event.preventDefault();
80
+ openLocator();
81
+ },
82
+ children: /* @__PURE__ */ jsxs(Popover, {
83
+ open,
84
+ onOpenChange: (value) => {
85
+ if (!value) commit();
86
+ },
87
+ children: [/* @__PURE__ */ jsx(PopoverAnchor, {
88
+ asChild: true,
89
+ children: /* @__PURE__ */ jsx("span", { children: text })
90
+ }), /* @__PURE__ */ jsx(PopoverContent, {
91
+ align: "start",
92
+ side: "bottom",
93
+ className: "w-56 p-2",
94
+ onCloseAutoFocus: (event) => event.preventDefault(),
95
+ children: /* @__PURE__ */ jsx(Input, {
96
+ value: draft,
97
+ className: "h-7 w-full text-xs",
98
+ placeholder: t("composites.reference.locatorPlaceholder"),
99
+ "aria-label": t("composites.reference.locator"),
100
+ onChange: (event) => setDraft(event.target.value),
101
+ onKeyDown: (event) => {
102
+ if (event.key === "Enter") {
103
+ event.preventDefault();
104
+ commit();
105
+ }
106
+ }
107
+ })
108
+ })]
109
+ })
110
+ });
111
+ }
112
+ //#endregion
113
+ export { ReferenceView };
114
+
115
+ //# sourceMappingURL=ReferenceView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReferenceView.js","names":[],"sources":["../../../../src/features/composites/react/ReferenceView.tsx"],"sourcesContent":["import { NodeViewWrapper, type NodeViewProps } from '@tiptap/react'\nimport { type MouseEvent, useEffect, useState } from 'react'\nimport { Input } from '../../../react/ui/input'\nimport { Popover, PopoverAnchor, PopoverContent } from '../../../react/ui/popover'\nimport { cn } from '../../../react/ui/utils'\nimport { useEditorI18n } from '../../../react/use-editor-i18n'\nimport { referenceAttrsOf, resolveReference } from '../reference-label'\nimport { revealSource } from '../reveal-source'\n\n/**\n * The `reference` chip: the live short citation (or title) of the Baustein it points at, followed by its locator.\n * A click reveals the target and, with a locator, opens its source there (page of a PDF, time of a recording); a\n * target that no longer exists shows a greyed „gone“ label. Double click or right click opens a popover to set the\n * locator („Stelle“) in an editable editor.\n */\nexport function ReferenceView({ editor, node, selected, getPos }: NodeViewProps) {\n const { t } = useEditorI18n()\n const [resolved, setResolved] = useState(() => resolveReference(editor, referenceAttrsOf(node)))\n const [open, setOpen] = useState(false)\n const [draft, setDraft] = useState('')\n const target = String(node.attrs.target)\n const locator = typeof node.attrs.locator === 'string' ? node.attrs.locator : ''\n\n // The target's title and bibliography edits change the label: re-resolve after document changes, once per frame.\n useEffect(() => {\n let frame = 0\n const resolve = () => {\n if (editor.isDestroyed) return\n const next = resolveReference(editor, { target, label: String(node.attrs.label ?? '') })\n setResolved(current => (next.label === current.label && next.title === current.title && next.gone === current.gone ? current : next))\n }\n const schedule = () => {\n cancelAnimationFrame(frame)\n frame = requestAnimationFrame(resolve)\n }\n resolve()\n editor.on('update', schedule)\n return () => {\n cancelAnimationFrame(frame)\n editor.off('update', schedule)\n }\n }, [editor, target, node.attrs.label])\n\n const label = resolved.gone ? t('composites.reference.gone') : resolved.label\n const text = locator && !resolved.gone ? `${label}, ${locator}` : label\n\n function onClick() {\n if (!editor.commands.revealBlock(target)) return\n if (locator) revealSource(editor, target, locator)\n }\n\n function openLocator() {\n if (!editor.isEditable) return\n setDraft(locator)\n setOpen(true)\n }\n\n function commit() {\n setOpen(false)\n const pos = getPos()\n if (typeof pos !== 'number' || draft.trim() === locator) return\n editor.commands.setReferenceLocator(pos, draft)\n }\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={cn('reference', resolved.gone && 'is-gone', selected && 'is-selected')}\n data-type=\"reference\"\n data-target={target}\n title={resolved.gone ? undefined : resolved.title}\n role=\"link\"\n onClick={onClick}\n onDoubleClick={(event: MouseEvent) => {\n event.preventDefault()\n openLocator()\n }}\n onContextMenu={(event: MouseEvent) => {\n event.preventDefault()\n openLocator()\n }}\n >\n <Popover open={open} onOpenChange={(value) => { if (!value) commit() }}>\n <PopoverAnchor asChild>\n <span>{text}</span>\n </PopoverAnchor>\n <PopoverContent\n align=\"start\"\n side=\"bottom\"\n className=\"w-56 p-2\"\n onCloseAutoFocus={event => event.preventDefault()}\n >\n <Input\n value={draft}\n className=\"h-7 w-full text-xs\"\n placeholder={t('composites.reference.locatorPlaceholder')}\n aria-label={t('composites.reference.locator')}\n onChange={event => setDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n commit()\n }\n }}\n />\n </PopoverContent>\n </Popover>\n </NodeViewWrapper>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,SAAgB,cAAc,EAAE,QAAQ,MAAM,UAAU,UAAyB;CAC/E,MAAM,EAAE,MAAM,cAAc;CAC5B,MAAM,CAAC,UAAU,eAAe,eAAe,iBAAiB,QAAQ,iBAAiB,IAAI,CAAC,CAAC;CAC/F,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;CACrC,MAAM,SAAS,OAAO,KAAK,MAAM,MAAM;CACvC,MAAM,UAAU,OAAO,KAAK,MAAM,YAAY,WAAW,KAAK,MAAM,UAAU;CAG9E,gBAAgB;EACd,IAAI,QAAQ;EACZ,MAAM,gBAAgB;GACpB,IAAI,OAAO,aAAa;GACxB,MAAM,OAAO,iBAAiB,QAAQ;IAAE;IAAQ,OAAO,OAAO,KAAK,MAAM,SAAS,EAAE;GAAE,CAAC;GACvF,aAAY,YAAY,KAAK,UAAU,QAAQ,SAAS,KAAK,UAAU,QAAQ,SAAS,KAAK,SAAS,QAAQ,OAAO,UAAU,IAAK;EACtI;EACA,MAAM,iBAAiB;GACrB,qBAAqB,KAAK;GAC1B,QAAQ,sBAAsB,OAAO;EACvC;EACA,QAAQ;EACR,OAAO,GAAG,UAAU,QAAQ;EAC5B,aAAa;GACX,qBAAqB,KAAK;GAC1B,OAAO,IAAI,UAAU,QAAQ;EAC/B;CACF,GAAG;EAAC;EAAQ;EAAQ,KAAK,MAAM;CAAK,CAAC;CAErC,MAAM,QAAQ,SAAS,OAAO,EAAE,2BAA2B,IAAI,SAAS;CACxE,MAAM,OAAO,WAAW,CAAC,SAAS,OAAO,GAAG,MAAM,IAAI,YAAY;CAElE,SAAS,UAAU;EACjB,IAAI,CAAC,OAAO,SAAS,YAAY,MAAM,GAAG;EAC1C,IAAI,SAAS,aAAa,QAAQ,QAAQ,OAAO;CACnD;CAEA,SAAS,cAAc;EACrB,IAAI,CAAC,OAAO,YAAY;EACxB,SAAS,OAAO;EAChB,QAAQ,IAAI;CACd;CAEA,SAAS,SAAS;EAChB,QAAQ,KAAK;EACb,MAAM,MAAM,OAAO;EACnB,IAAI,OAAO,QAAQ,YAAY,MAAM,KAAK,MAAM,SAAS;EACzD,OAAO,SAAS,oBAAoB,KAAK,KAAK;CAChD;CAEA,OACE,oBAAC,iBAAD;EACE,IAAG;EACH,WAAW,GAAG,aAAa,SAAS,QAAQ,WAAW,YAAY,aAAa;EAChF,aAAU;EACV,eAAa;EACb,OAAO,SAAS,OAAO,KAAA,IAAY,SAAS;EAC5C,MAAK;EACI;EACT,gBAAgB,UAAsB;GACpC,MAAM,eAAe;GACrB,YAAY;EACd;EACA,gBAAgB,UAAsB;GACpC,MAAM,eAAe;GACrB,YAAY;EACd;EAEA,UAAA,qBAAC,SAAD;GAAe;GAAM,eAAe,UAAU;IAAE,IAAI,CAAC,OAAO,OAAO;GAAE;GAArE,UAAA,CACE,oBAAC,eAAD;IAAe,SAAA;IACb,UAAA,oBAAC,QAAD,EAAA,UAAO,KAAW,CAAA;GACL,CAAA,GACf,oBAAC,gBAAD;IACE,OAAM;IACN,MAAK;IACL,WAAU;IACV,mBAAkB,UAAS,MAAM,eAAe;IAEhD,UAAA,oBAAC,OAAD;KACE,OAAO;KACP,WAAU;KACV,aAAa,EAAE,yCAAyC;KACxD,cAAY,EAAE,8BAA8B;KAC5C,WAAU,UAAS,SAAS,MAAM,OAAO,KAAK;KAC9C,YAAY,UAAU;MACpB,IAAI,MAAM,QAAQ,SAAS;OACzB,MAAM,eAAe;OACrB,OAAO;MACT;KACF;IACD,CAAA;GACa,CAAA,CACT;;CACM,CAAA;AAErB"}
@@ -2,13 +2,13 @@ import { DRAG_HANDLE_VISIBILITIES, HEADING_CONVERSION_SCOPES, KIND_ICON_VISIBILI
2
2
  import { useEditorI18n } from "../../../react/use-editor-i18n.js";
3
3
  import { Icon } from "../../../react/Icon.js";
4
4
  import { useEditorSettings } from "../../../react/settings.js";
5
- import { STRUCTURE_MODE_KEYS } from "../structure-mode.js";
6
- import { TREE_ROOT_KEYS } from "../tree-root.js";
7
5
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../../react/ui/select.js";
8
6
  import { SettingsSection } from "../../../react/SettingsSection.js";
9
7
  import { Label } from "../../../react/ui/label.js";
10
8
  import { RadioGroup, RadioGroupItem } from "../../../react/ui/radio-group.js";
9
+ import { STRUCTURE_MODE_KEYS } from "../structure-mode.js";
11
10
  import { DRAG_HANDLE_KEYS, HEADING_SCOPE_KEYS, KIND_ICON_KEYS, optionItems } from "../editing-settings-keys.js";
11
+ import { TREE_ROOT_KEYS } from "../tree-root.js";
12
12
  import { useId } from "react";
13
13
  import { jsx, jsxs } from "react/jsx-runtime";
14
14
  //#region src/features/composites/react/SettingsEditingTab.tsx
@@ -10,6 +10,7 @@ import { CompositeSummaryEditor } from "./react/CompositeSummaryEditor.js";
10
10
  import { CompositeTable } from "./react/CompositeTable.js";
11
11
  import { CompositeTagsEditor } from "./react/CompositeTagsEditor.js";
12
12
  import { CompositeView } from "./react/CompositeView.js";
13
+ import { ReferenceView } from "./react/ReferenceView.js";
13
14
  import { SettingsEditingTab } from "./react/SettingsEditingTab.js";
14
15
  import { useCompositeAnchors } from "./react/use-composite-anchors.js";
15
16
  import { useCompositeRows } from "./react/use-composite-rows.js";
@@ -20,5 +21,5 @@ import { useCompositeRows } from "./react/use-composite-rows.js";
20
21
  */
21
22
  export declare function compositeFeature(options?: CompositeFeatureOptions): ReactFeature;
22
23
  //#endregion
23
- export { CompositeChrome, CompositeDetails, CompositeFieldEditor, CompositeInspector, CompositeStatusMenu, CompositeSummaryEditor, CompositeTable, CompositeTagsEditor, CompositeView, SettingsEditingTab, useCompositeAnchors, useCompositeRows };
24
+ export { CompositeChrome, CompositeDetails, CompositeFieldEditor, CompositeInspector, CompositeStatusMenu, CompositeSummaryEditor, CompositeTable, CompositeTagsEditor, CompositeView, ReferenceView, SettingsEditingTab, useCompositeAnchors, useCompositeRows };
24
25
  //# sourceMappingURL=react.d.ts.map
@@ -1,12 +1,13 @@
1
1
  import { compositeFeatureCore } from "./feature.js";
2
+ import { useCompositeRows } from "./react/use-composite-rows.js";
2
3
  import { CompositeFieldEditor } from "./react/CompositeFieldEditor.js";
3
4
  import { CompositeSummaryEditor } from "./react/CompositeSummaryEditor.js";
4
5
  import { CompositeDetails } from "./react/CompositeDetails.js";
5
6
  import { CompositeStatusMenu } from "./react/CompositeStatusMenu.js";
6
7
  import { CompositeTagsEditor } from "./react/CompositeTagsEditor.js";
7
8
  import { useCompositeAnchors } from "./react/use-composite-anchors.js";
8
- import { useCompositeRows } from "./react/use-composite-rows.js";
9
9
  import { CompositeChrome } from "./react/CompositeChrome.js";
10
+ import { ReferenceView } from "./react/ReferenceView.js";
10
11
  import { CompositeView } from "./react/CompositeView.js";
11
12
  import { SettingsEditingTab } from "./react/SettingsEditingTab.js";
12
13
  import { CompositeInspector } from "./react/CompositeInspector.js";
@@ -21,10 +22,13 @@ function compositeFeature(options = {}) {
21
22
  return compositeFeatureCore({
22
23
  chrome: CompositeChrome,
23
24
  settingsTab: SettingsEditingTab,
24
- nodeViews: { composite: ReactNodeViewRenderer(CompositeView) }
25
+ nodeViews: {
26
+ composite: ReactNodeViewRenderer(CompositeView),
27
+ reference: ReactNodeViewRenderer(ReferenceView)
28
+ }
25
29
  }, options);
26
30
  }
27
31
  //#endregion
28
- export { CompositeChrome, CompositeDetails, CompositeFieldEditor, CompositeInspector, CompositeStatusMenu, CompositeSummaryEditor, CompositeTable, CompositeTagsEditor, CompositeView, SettingsEditingTab, compositeFeature, useCompositeAnchors, useCompositeRows };
32
+ export { CompositeChrome, CompositeDetails, CompositeFieldEditor, CompositeInspector, CompositeStatusMenu, CompositeSummaryEditor, CompositeTable, CompositeTagsEditor, CompositeView, ReferenceView, SettingsEditingTab, compositeFeature, useCompositeAnchors, useCompositeRows };
29
33
 
30
34
  //# sourceMappingURL=react.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","names":[],"sources":["../../../src/features/composites/react.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { ReactNodeViewRenderer } from '@tiptap/react'\nimport type { ComponentType } from 'react'\nimport type { ReactFeature } from '../../react'\nimport { type CompositeFeatureOptions, compositeFeatureCore } from './feature'\nimport { CompositeChrome } from './react/CompositeChrome'\nimport { CompositeView } from './react/CompositeView'\nimport { SettingsEditingTab } from './react/SettingsEditingTab'\n\nexport { CompositeChrome } from './react/CompositeChrome'\nexport { CompositeDetails } from './react/CompositeDetails'\nexport { CompositeFieldEditor } from './react/CompositeFieldEditor'\nexport { CompositeInspector } from './react/CompositeInspector'\nexport { CompositeStatusMenu } from './react/CompositeStatusMenu'\nexport { CompositeSummaryEditor } from './react/CompositeSummaryEditor'\nexport { CompositeTable } from './react/CompositeTable'\nexport { CompositeTagsEditor } from './react/CompositeTagsEditor'\nexport { CompositeView } from './react/CompositeView'\nexport { SettingsEditingTab } from './react/SettingsEditingTab'\nexport { useCompositeAnchors } from './react/use-composite-anchors'\nexport { useCompositeRows } from './react/use-composite-rows'\n\n/**\n * The React composites feature (shadcn): see `compositeFeatureCore`. The host places `CompositeTable` and\n * `CompositeInspector` beside the editor.\n */\nexport function compositeFeature(options: CompositeFeatureOptions = {}): ReactFeature {\n return compositeFeatureCore<ComponentType<{ editor: Editor }>>({\n chrome: CompositeChrome,\n // A settings tab receives only its descriptor's `props` (`{ kinds }`), not the toolbar's `{ editor }` (see `EditorSettingsPanel`).\n settingsTab: SettingsEditingTab as unknown as ComponentType<{ editor: Editor }>,\n nodeViews: { composite: ReactNodeViewRenderer(CompositeView) },\n }, options)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,iBAAiB,UAAmC,CAAC,GAAiB;CACpF,OAAO,qBAAwD;EAC7D,QAAQ;EAER,aAAa;EACb,WAAW,EAAE,WAAW,sBAAsB,aAAa,EAAE;CAC/D,GAAG,OAAO;AACZ"}
1
+ {"version":3,"file":"react.js","names":[],"sources":["../../../src/features/composites/react.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { ReactNodeViewRenderer } from '@tiptap/react'\nimport type { ComponentType } from 'react'\nimport type { ReactFeature } from '../../react'\nimport { type CompositeFeatureOptions, compositeFeatureCore } from './feature'\nimport { CompositeChrome } from './react/CompositeChrome'\nimport { ReferenceView } from './react/ReferenceView'\nimport { CompositeView } from './react/CompositeView'\nimport { SettingsEditingTab } from './react/SettingsEditingTab'\n\nexport { CompositeChrome } from './react/CompositeChrome'\nexport { CompositeDetails } from './react/CompositeDetails'\nexport { CompositeFieldEditor } from './react/CompositeFieldEditor'\nexport { CompositeInspector } from './react/CompositeInspector'\nexport { CompositeStatusMenu } from './react/CompositeStatusMenu'\nexport { CompositeSummaryEditor } from './react/CompositeSummaryEditor'\nexport { CompositeTable } from './react/CompositeTable'\nexport { CompositeTagsEditor } from './react/CompositeTagsEditor'\nexport { CompositeView } from './react/CompositeView'\nexport { ReferenceView } from './react/ReferenceView'\nexport { SettingsEditingTab } from './react/SettingsEditingTab'\nexport { useCompositeAnchors } from './react/use-composite-anchors'\nexport { useCompositeRows } from './react/use-composite-rows'\n\n/**\n * The React composites feature (shadcn): see `compositeFeatureCore`. The host places `CompositeTable` and\n * `CompositeInspector` beside the editor.\n */\nexport function compositeFeature(options: CompositeFeatureOptions = {}): ReactFeature {\n return compositeFeatureCore<ComponentType<{ editor: Editor }>>({\n chrome: CompositeChrome,\n // A settings tab receives only its descriptor's `props` (`{ kinds }`), not the toolbar's `{ editor }` (see `EditorSettingsPanel`).\n settingsTab: SettingsEditingTab as unknown as ComponentType<{ editor: Editor }>,\n nodeViews: { composite: ReactNodeViewRenderer(CompositeView), reference: ReactNodeViewRenderer(ReferenceView) },\n }, options)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,iBAAiB,UAAmC,CAAC,GAAiB;CACpF,OAAO,qBAAwD;EAC7D,QAAQ;EAER,aAAa;EACb,WAAW;GAAE,WAAW,sBAAsB,aAAa;GAAG,WAAW,sBAAsB,aAAa;EAAE;CAChH,GAAG,OAAO;AACZ"}