@dxos/plugin-markdown 0.8.4-main.67995b8 → 0.8.4-main.ae835ea

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 (244) hide show
  1. package/dist/lib/browser/MarkdownCard-SLM6QZYC.mjs +12 -0
  2. package/dist/lib/browser/MarkdownCard-SLM6QZYC.mjs.map +7 -0
  3. package/dist/lib/browser/MarkdownContainer-UZFQC6XY.mjs +15 -0
  4. package/dist/lib/browser/MarkdownContainer-UZFQC6XY.mjs.map +7 -0
  5. package/dist/lib/browser/{anchor-sort-Z7JQA7RL.mjs → anchor-sort-4XPPLMZS.mjs} +5 -5
  6. package/dist/lib/browser/{anchor-sort-Z7JQA7RL.mjs.map → anchor-sort-4XPPLMZS.mjs.map} +1 -1
  7. package/dist/lib/browser/{app-graph-serializer-ZT5OVF5G.mjs → app-graph-serializer-QQFV4K6P.mjs} +9 -10
  8. package/dist/lib/browser/app-graph-serializer-QQFV4K6P.mjs.map +7 -0
  9. package/dist/lib/browser/blueprint-definition-BC5R3T72.mjs +11 -0
  10. package/dist/lib/browser/blueprint-definition-BC5R3T72.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-VMX5SDGW.mjs → chunk-2LLVTQCK.mjs} +6 -5
  12. package/dist/lib/browser/chunk-2LLVTQCK.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-3VILQLA4.mjs +95 -0
  14. package/dist/lib/browser/chunk-3VILQLA4.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-5AYTOIUF.mjs +822 -0
  16. package/dist/lib/browser/chunk-5AYTOIUF.mjs.map +7 -0
  17. package/dist/lib/browser/{chunk-K7ZFMSC4.mjs → chunk-A3CQYGCN.mjs} +8 -4
  18. package/dist/lib/browser/chunk-A3CQYGCN.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-ZGY3DYC2.mjs → chunk-BQTYJOFB.mjs} +5 -7
  20. package/dist/lib/browser/chunk-BQTYJOFB.mjs.map +7 -0
  21. package/dist/lib/browser/chunk-GLEYXJX3.mjs +22 -0
  22. package/dist/lib/browser/chunk-GLEYXJX3.mjs.map +7 -0
  23. package/dist/lib/browser/{chunk-CD4E4K7J.mjs → chunk-IBCHVMZW.mjs} +2 -2
  24. package/dist/lib/browser/{chunk-CD4E4K7J.mjs.map → chunk-IBCHVMZW.mjs.map} +2 -2
  25. package/dist/lib/browser/chunk-JAETS5LE.mjs +106 -0
  26. package/dist/lib/browser/chunk-JAETS5LE.mjs.map +7 -0
  27. package/dist/lib/browser/{chunk-YHMGUSO7.mjs → chunk-UKTCPHLI.mjs} +13 -14
  28. package/dist/lib/browser/chunk-UKTCPHLI.mjs.map +7 -0
  29. package/dist/lib/browser/index.mjs +32 -20
  30. package/dist/lib/browser/index.mjs.map +3 -3
  31. package/dist/lib/browser/{intent-resolver-EBEF7WEI.mjs → intent-resolver-VQGMBNXZ.mjs} +20 -18
  32. package/dist/lib/browser/intent-resolver-VQGMBNXZ.mjs.map +7 -0
  33. package/dist/lib/browser/meta.json +1 -1
  34. package/dist/lib/browser/{react-surface-ZPMZT4VU.mjs → react-surface-WOMJOPJE.mjs} +83 -74
  35. package/dist/lib/browser/react-surface-WOMJOPJE.mjs.map +7 -0
  36. package/dist/lib/browser/{settings-MBDK4TWE.mjs → settings-LBXJHVBU.mjs} +5 -5
  37. package/dist/lib/browser/{settings-MBDK4TWE.mjs.map → settings-LBXJHVBU.mjs.map} +1 -1
  38. package/dist/lib/browser/{state-ZA6PZPUI.mjs → state-BTUKVZHY.mjs} +5 -5
  39. package/dist/lib/browser/state-BTUKVZHY.mjs.map +7 -0
  40. package/dist/lib/browser/toolkit-YPIVDB4A.mjs +66 -0
  41. package/dist/lib/browser/toolkit-YPIVDB4A.mjs.map +7 -0
  42. package/dist/lib/browser/types/index.mjs +2 -2
  43. package/dist/lib/node-esm/MarkdownCard-MCWEFW4F.mjs +13 -0
  44. package/dist/lib/node-esm/MarkdownCard-MCWEFW4F.mjs.map +7 -0
  45. package/dist/lib/node-esm/MarkdownContainer-KAQOK7K5.mjs +16 -0
  46. package/dist/lib/node-esm/MarkdownContainer-KAQOK7K5.mjs.map +7 -0
  47. package/dist/lib/node-esm/{anchor-sort-R6AAKYNG.mjs → anchor-sort-4SXYVYXT.mjs} +5 -5
  48. package/dist/lib/node-esm/{anchor-sort-R6AAKYNG.mjs.map → anchor-sort-4SXYVYXT.mjs.map} +1 -1
  49. package/dist/lib/node-esm/{app-graph-serializer-X4M5QEI6.mjs → app-graph-serializer-KBVRLQN2.mjs} +9 -10
  50. package/dist/lib/node-esm/app-graph-serializer-KBVRLQN2.mjs.map +7 -0
  51. package/dist/lib/node-esm/blueprint-definition-FPNOTEYC.mjs +12 -0
  52. package/dist/lib/node-esm/blueprint-definition-FPNOTEYC.mjs.map +7 -0
  53. package/dist/lib/node-esm/chunk-2Q4WCKWT.mjs +823 -0
  54. package/dist/lib/node-esm/chunk-2Q4WCKWT.mjs.map +7 -0
  55. package/dist/lib/node-esm/chunk-DOB2MJAX.mjs +107 -0
  56. package/dist/lib/node-esm/chunk-DOB2MJAX.mjs.map +7 -0
  57. package/dist/lib/node-esm/chunk-GGKPPGWA.mjs +24 -0
  58. package/dist/lib/node-esm/chunk-GGKPPGWA.mjs.map +7 -0
  59. package/dist/lib/node-esm/{chunk-B3J2M4YL.mjs → chunk-GMMVSXQ6.mjs} +2 -2
  60. package/dist/lib/node-esm/{chunk-B3J2M4YL.mjs.map → chunk-GMMVSXQ6.mjs.map} +2 -2
  61. package/dist/lib/node-esm/{chunk-6GCOJS4Y.mjs → chunk-JELROKGD.mjs} +13 -14
  62. package/dist/lib/node-esm/chunk-JELROKGD.mjs.map +7 -0
  63. package/dist/lib/node-esm/{chunk-LZK3TLKM.mjs → chunk-QH4MC5BE.mjs} +6 -5
  64. package/dist/lib/node-esm/chunk-QH4MC5BE.mjs.map +7 -0
  65. package/dist/lib/node-esm/{chunk-RCIXKCVG.mjs → chunk-SHAMSMKQ.mjs} +5 -7
  66. package/dist/lib/node-esm/chunk-SHAMSMKQ.mjs.map +7 -0
  67. package/dist/lib/node-esm/{chunk-YGNVDYMB.mjs → chunk-SJ2QRGPM.mjs} +8 -4
  68. package/dist/lib/node-esm/chunk-SJ2QRGPM.mjs.map +7 -0
  69. package/dist/lib/node-esm/chunk-YYSASY7X.mjs +96 -0
  70. package/dist/lib/node-esm/chunk-YYSASY7X.mjs.map +7 -0
  71. package/dist/lib/node-esm/index.mjs +32 -20
  72. package/dist/lib/node-esm/index.mjs.map +3 -3
  73. package/dist/lib/node-esm/{intent-resolver-L2UGZ72W.mjs → intent-resolver-Q4XVI5EX.mjs} +20 -18
  74. package/dist/lib/node-esm/intent-resolver-Q4XVI5EX.mjs.map +7 -0
  75. package/dist/lib/node-esm/meta.json +1 -1
  76. package/dist/lib/node-esm/{react-surface-3JJSTTQP.mjs → react-surface-FAMZTAXK.mjs} +83 -74
  77. package/dist/lib/node-esm/react-surface-FAMZTAXK.mjs.map +7 -0
  78. package/dist/lib/node-esm/{settings-LBDWWPZJ.mjs → settings-2YRA67H6.mjs} +5 -5
  79. package/dist/lib/node-esm/{settings-LBDWWPZJ.mjs.map → settings-2YRA67H6.mjs.map} +1 -1
  80. package/dist/lib/node-esm/{state-UIHO2SFZ.mjs → state-K6EH7SRZ.mjs} +5 -5
  81. package/dist/lib/node-esm/state-K6EH7SRZ.mjs.map +7 -0
  82. package/dist/lib/node-esm/toolkit-36BFLIR3.mjs +67 -0
  83. package/dist/lib/node-esm/toolkit-36BFLIR3.mjs.map +7 -0
  84. package/dist/lib/node-esm/types/index.mjs +2 -2
  85. package/dist/types/src/MarkdownPlugin.d.ts +1 -1
  86. package/dist/types/src/MarkdownPlugin.d.ts.map +1 -1
  87. package/dist/types/src/capabilities/anchor-sort.d.ts +2 -2
  88. package/dist/types/src/capabilities/app-graph-serializer.d.ts +1 -1
  89. package/dist/types/src/capabilities/app-graph-serializer.d.ts.map +1 -1
  90. package/dist/types/src/capabilities/artifact-definition.d.ts +1 -9
  91. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  92. package/dist/types/src/capabilities/blueprint-definition.d.ts +5 -0
  93. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
  94. package/dist/types/src/capabilities/capabilities.d.ts +1 -1
  95. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  96. package/dist/types/src/capabilities/index.d.ts +12 -10
  97. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  98. package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
  99. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  100. package/dist/types/src/capabilities/react-surface.d.ts +1 -1
  101. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  102. package/dist/types/src/capabilities/settings.d.ts +1 -1
  103. package/dist/types/src/capabilities/state.d.ts +2 -2
  104. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  105. package/dist/types/src/capabilities/toolkit.d.ts +20 -0
  106. package/dist/types/src/capabilities/toolkit.d.ts.map +1 -0
  107. package/dist/types/src/components/MarkdownCard/MarkdownCard.d.ts +7 -0
  108. package/dist/types/src/components/MarkdownCard/MarkdownCard.d.ts.map +1 -0
  109. package/dist/types/src/components/MarkdownCard/MarkdownCard.stories.d.ts +9 -0
  110. package/dist/types/src/components/MarkdownCard/MarkdownCard.stories.d.ts.map +1 -0
  111. package/dist/types/src/components/MarkdownCard/index.d.ts +4 -0
  112. package/dist/types/src/components/MarkdownCard/index.d.ts.map +1 -0
  113. package/dist/types/src/components/MarkdownContainer.d.ts +8 -12
  114. package/dist/types/src/components/MarkdownContainer.d.ts.map +1 -1
  115. package/dist/types/src/components/MarkdownContainer.stories.d.ts +54 -5
  116. package/dist/types/src/components/MarkdownContainer.stories.d.ts.map +1 -1
  117. package/dist/types/src/components/MarkdownEditor/FileUpload.d.ts +11 -0
  118. package/dist/types/src/components/MarkdownEditor/FileUpload.d.ts.map +1 -0
  119. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.d.ts +42 -23
  120. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.d.ts.map +1 -1
  121. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.stories.d.ts +8 -15
  122. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.stories.d.ts.map +1 -1
  123. package/dist/types/src/components/MarkdownEditor/MarkdownEditorContent.d.ts +26 -0
  124. package/dist/types/src/components/MarkdownEditor/MarkdownEditorContent.d.ts.map +1 -0
  125. package/dist/types/src/components/MarkdownEditor/MarkdownEditorToolbar.d.ts +12 -0
  126. package/dist/types/src/components/MarkdownEditor/MarkdownEditorToolbar.d.ts.map +1 -0
  127. package/dist/types/src/components/MarkdownSettings/MarkdownSettings.d.ts.map +1 -1
  128. package/dist/types/src/components/Suggestions.stories.d.ts +1 -2
  129. package/dist/types/src/components/Suggestions.stories.d.ts.map +1 -1
  130. package/dist/types/src/components/index.d.ts +4 -2
  131. package/dist/types/src/components/index.d.ts.map +1 -1
  132. package/dist/types/src/functions/diff.d.ts +6 -0
  133. package/dist/types/src/functions/diff.d.ts.map +1 -0
  134. package/dist/types/src/functions/index.d.ts +3 -0
  135. package/dist/types/src/functions/index.d.ts.map +1 -0
  136. package/dist/types/src/functions/open.d.ts +7 -0
  137. package/dist/types/src/functions/open.d.ts.map +1 -0
  138. package/dist/types/src/hooks/index.d.ts +3 -0
  139. package/dist/types/src/hooks/index.d.ts.map +1 -1
  140. package/dist/types/src/hooks/useExtensions.d.ts +21 -0
  141. package/dist/types/src/hooks/useExtensions.d.ts.map +1 -0
  142. package/dist/types/src/hooks/useLinkQuery.d.ts +4 -0
  143. package/dist/types/src/hooks/useLinkQuery.d.ts.map +1 -0
  144. package/dist/types/src/hooks/usePopoverMenuOptions.d.ts +9 -0
  145. package/dist/types/src/hooks/usePopoverMenuOptions.d.ts.map +1 -0
  146. package/dist/types/src/hooks/useSelectCurrentThread.d.ts +1 -1
  147. package/dist/types/src/hooks/useSelectCurrentThread.d.ts.map +1 -1
  148. package/dist/types/src/index.d.ts +2 -1
  149. package/dist/types/src/index.d.ts.map +1 -1
  150. package/dist/types/src/meta.d.ts +0 -1
  151. package/dist/types/src/meta.d.ts.map +1 -1
  152. package/dist/types/src/translations.d.ts +4 -0
  153. package/dist/types/src/translations.d.ts.map +1 -1
  154. package/dist/types/src/types/Markdown.d.ts +7 -5
  155. package/dist/types/src/types/Markdown.d.ts.map +1 -1
  156. package/dist/types/src/types/MarkdownAction.d.ts +6 -14
  157. package/dist/types/src/types/MarkdownAction.d.ts.map +1 -1
  158. package/dist/types/src/types/types.d.ts.map +1 -1
  159. package/dist/types/src/util.d.ts +1 -1
  160. package/dist/types/src/util.d.ts.map +1 -1
  161. package/dist/types/tsconfig.tsbuildinfo +1 -1
  162. package/package.json +62 -56
  163. package/src/MarkdownPlugin.tsx +103 -94
  164. package/src/capabilities/app-graph-serializer.ts +4 -4
  165. package/src/capabilities/artifact-definition.ts +15 -19
  166. package/src/capabilities/blueprint-definition.ts +39 -0
  167. package/src/capabilities/capabilities.ts +2 -1
  168. package/src/capabilities/index.ts +3 -1
  169. package/src/capabilities/intent-resolver.ts +14 -13
  170. package/src/capabilities/react-surface.tsx +39 -60
  171. package/src/capabilities/state.ts +3 -2
  172. package/src/capabilities/toolkit.ts +53 -0
  173. package/src/components/{MarkdownPreview/MarkdownPreview.stories.tsx → MarkdownCard/MarkdownCard.stories.tsx} +14 -15
  174. package/src/components/{MarkdownPreview/MarkdownPreview.tsx → MarkdownCard/MarkdownCard.tsx} +45 -33
  175. package/src/components/MarkdownCard/index.ts +9 -0
  176. package/src/components/MarkdownContainer.stories.tsx +80 -43
  177. package/src/components/MarkdownContainer.tsx +86 -219
  178. package/src/components/MarkdownEditor/FileUpload.tsx +63 -0
  179. package/src/components/MarkdownEditor/MarkdownEditor.stories.tsx +58 -34
  180. package/src/components/MarkdownEditor/MarkdownEditor.tsx +220 -271
  181. package/src/components/MarkdownEditor/MarkdownEditorContent.tsx +134 -0
  182. package/src/components/MarkdownEditor/MarkdownEditorToolbar.tsx +63 -0
  183. package/src/components/MarkdownSettings/MarkdownSettings.tsx +77 -74
  184. package/src/components/Suggestions.stories.tsx +40 -41
  185. package/src/components/index.ts +3 -1
  186. package/src/functions/diff.ts +37 -0
  187. package/src/functions/index.ts +6 -0
  188. package/src/functions/open.ts +32 -0
  189. package/src/hooks/index.ts +3 -0
  190. package/src/{extensions.tsx → hooks/useExtensions.tsx} +61 -119
  191. package/src/hooks/useLinkQuery.ts +82 -0
  192. package/src/hooks/usePopoverMenuOptions.ts +71 -0
  193. package/src/hooks/useSelectCurrentThread.tsx +3 -3
  194. package/src/index.ts +3 -1
  195. package/src/meta.ts +3 -6
  196. package/src/translations.ts +4 -0
  197. package/src/types/Markdown.ts +8 -5
  198. package/src/types/MarkdownAction.ts +5 -6
  199. package/src/types/types.ts +1 -0
  200. package/src/util.tsx +9 -2
  201. package/dist/lib/browser/MarkdownContainer-NNBPE6A5.mjs +0 -779
  202. package/dist/lib/browser/MarkdownContainer-NNBPE6A5.mjs.map +0 -7
  203. package/dist/lib/browser/MarkdownPreview-7VG3K24R.mjs +0 -80
  204. package/dist/lib/browser/MarkdownPreview-7VG3K24R.mjs.map +0 -7
  205. package/dist/lib/browser/app-graph-serializer-ZT5OVF5G.mjs.map +0 -7
  206. package/dist/lib/browser/artifact-definition-7VNP5PCP.mjs +0 -145
  207. package/dist/lib/browser/artifact-definition-7VNP5PCP.mjs.map +0 -7
  208. package/dist/lib/browser/chunk-K7ZFMSC4.mjs.map +0 -7
  209. package/dist/lib/browser/chunk-VCUKIILA.mjs +0 -20
  210. package/dist/lib/browser/chunk-VCUKIILA.mjs.map +0 -7
  211. package/dist/lib/browser/chunk-VMX5SDGW.mjs.map +0 -7
  212. package/dist/lib/browser/chunk-YHMGUSO7.mjs.map +0 -7
  213. package/dist/lib/browser/chunk-ZGY3DYC2.mjs.map +0 -7
  214. package/dist/lib/browser/intent-resolver-EBEF7WEI.mjs.map +0 -7
  215. package/dist/lib/browser/react-surface-ZPMZT4VU.mjs.map +0 -7
  216. package/dist/lib/browser/state-ZA6PZPUI.mjs.map +0 -7
  217. package/dist/lib/node-esm/MarkdownContainer-Q6UO7DKT.mjs +0 -780
  218. package/dist/lib/node-esm/MarkdownContainer-Q6UO7DKT.mjs.map +0 -7
  219. package/dist/lib/node-esm/MarkdownPreview-UVWR2YK3.mjs +0 -81
  220. package/dist/lib/node-esm/MarkdownPreview-UVWR2YK3.mjs.map +0 -7
  221. package/dist/lib/node-esm/app-graph-serializer-X4M5QEI6.mjs.map +0 -7
  222. package/dist/lib/node-esm/artifact-definition-IRIILD7S.mjs +0 -146
  223. package/dist/lib/node-esm/artifact-definition-IRIILD7S.mjs.map +0 -7
  224. package/dist/lib/node-esm/chunk-6GCOJS4Y.mjs.map +0 -7
  225. package/dist/lib/node-esm/chunk-A7LLVI34.mjs +0 -22
  226. package/dist/lib/node-esm/chunk-A7LLVI34.mjs.map +0 -7
  227. package/dist/lib/node-esm/chunk-LZK3TLKM.mjs.map +0 -7
  228. package/dist/lib/node-esm/chunk-RCIXKCVG.mjs.map +0 -7
  229. package/dist/lib/node-esm/chunk-YGNVDYMB.mjs.map +0 -7
  230. package/dist/lib/node-esm/intent-resolver-L2UGZ72W.mjs.map +0 -7
  231. package/dist/lib/node-esm/react-surface-3JJSTTQP.mjs.map +0 -7
  232. package/dist/lib/node-esm/state-UIHO2SFZ.mjs.map +0 -7
  233. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.d.ts +0 -6
  234. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.d.ts.map +0 -1
  235. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts +0 -10
  236. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts.map +0 -1
  237. package/dist/types/src/components/MarkdownPreview/index.d.ts +0 -4
  238. package/dist/types/src/components/MarkdownPreview/index.d.ts.map +0 -1
  239. package/dist/types/src/components/Toolbar.stories.d.ts +0 -11
  240. package/dist/types/src/components/Toolbar.stories.d.ts.map +0 -1
  241. package/dist/types/src/extensions.d.ts +0 -24
  242. package/dist/types/src/extensions.d.ts.map +0 -1
  243. package/src/components/MarkdownPreview/index.ts +0 -9
  244. package/src/components/Toolbar.stories.tsx +0 -112
@@ -2,21 +2,22 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React from 'react';
5
+ import React, { useCallback } from 'react';
6
6
 
7
- import { createSurface, contributes, Capabilities, useCapability } from '@dxos/app-framework';
7
+ import { Capabilities, contributes, createSurface, useCapability } from '@dxos/app-framework';
8
8
  import { Obj } from '@dxos/echo';
9
9
  import { SettingsStore } from '@dxos/local-storage';
10
10
  import { AttentionCapabilities } from '@dxos/plugin-attention';
11
11
  import { fullyQualifiedId } from '@dxos/react-client/echo';
12
12
  import { DataType } from '@dxos/schema';
13
13
 
14
- import { MarkdownCapabilities } from './capabilities';
15
- import { MarkdownContainer, MarkdownSettings, MarkdownPreview } from '../components';
14
+ import { MarkdownCard, MarkdownContainer, type MarkdownContainerProps, MarkdownSettings } from '../components';
16
15
  import { meta } from '../meta';
17
16
  import { Markdown } from '../types';
18
17
  import { isEditorModel } from '../util';
19
18
 
19
+ import { MarkdownCapabilities } from './capabilities';
20
+
20
21
  export default () =>
21
22
  contributes(Capabilities.ReactSurface, [
22
23
  createSurface({
@@ -25,25 +26,7 @@ export default () =>
25
26
  filter: (data): data is { subject: Markdown.Document; variant: undefined } =>
26
27
  Obj.instanceOf(Markdown.Document, data.subject) && !data.variant,
27
28
  component: ({ data, role }) => {
28
- const selectionManager = useCapability(AttentionCapabilities.Selection);
29
- const settingsStore = useCapability(Capabilities.SettingsStore);
30
- const settings = settingsStore.getStore<Markdown.Settings>(meta.id)!.value;
31
- const { state, editorState, getViewMode, setViewMode } = useCapability(MarkdownCapabilities.State);
32
- const viewMode = getViewMode(fullyQualifiedId(data.subject));
33
-
34
- return (
35
- <MarkdownContainer
36
- id={fullyQualifiedId(data.subject)}
37
- object={data.subject}
38
- role={role}
39
- settings={settings}
40
- selectionManager={selectionManager}
41
- extensionProviders={state.extensionProviders}
42
- viewMode={viewMode}
43
- editorStateStore={editorState}
44
- onViewModeChange={setViewMode}
45
- />
46
- );
29
+ return <Container id={fullyQualifiedId(data.subject)} subject={data.subject} role={role} />;
47
30
  },
48
31
  }),
49
32
  createSurface({
@@ -52,49 +35,16 @@ export default () =>
52
35
  filter: (data): data is { id: string; subject: DataType.Text } =>
53
36
  typeof data.id === 'string' && Obj.instanceOf(DataType.Text, data.subject),
54
37
  component: ({ data, role }) => {
55
- const selectionManager = useCapability(AttentionCapabilities.Selection);
56
- const settingsStore = useCapability(Capabilities.SettingsStore);
57
- const settings = settingsStore.getStore<Markdown.Settings>(meta.id)!.value;
58
- const { state, editorState, getViewMode, setViewMode } = useCapability(MarkdownCapabilities.State);
59
-
60
- return (
61
- <MarkdownContainer
62
- id={data.id}
63
- object={data.subject}
64
- role={role}
65
- settings={settings}
66
- selectionManager={selectionManager}
67
- extensionProviders={state.extensionProviders}
68
- viewMode={getViewMode(data.id)}
69
- editorStateStore={editorState}
70
- onViewModeChange={setViewMode}
71
- />
72
- );
38
+ return <Container id={data.id} subject={data.subject} role={role} />;
73
39
  },
74
40
  }),
41
+ // TODO(burdon): Remove this variant and conform to DataType.Text.
75
42
  createSurface({
76
43
  id: `${meta.id}/surface/editor`,
77
44
  role: ['article', 'section'],
78
45
  filter: (data): data is { subject: { id: string; text: string } } => isEditorModel(data.subject),
79
46
  component: ({ data, role }) => {
80
- const selectionManager = useCapability(AttentionCapabilities.Selection);
81
- const settingsStore = useCapability(Capabilities.SettingsStore);
82
- const settings = settingsStore.getStore<Markdown.Settings>(meta.id)!.value;
83
- const { state, editorState, getViewMode, setViewMode } = useCapability(MarkdownCapabilities.State);
84
-
85
- return (
86
- <MarkdownContainer
87
- id={data.subject.id}
88
- object={data.subject}
89
- role={role}
90
- settings={settings}
91
- selectionManager={selectionManager}
92
- extensionProviders={state.extensionProviders}
93
- viewMode={getViewMode(data.subject.id)}
94
- editorStateStore={editorState}
95
- onViewModeChange={setViewMode}
96
- />
97
- );
47
+ return <Container id={data.subject.id} subject={data.subject} role={role} />;
98
48
  },
99
49
  }),
100
50
  createSurface({
@@ -109,6 +59,35 @@ export default () =>
109
59
  role: ['card--popover', 'card--intrinsic', 'card--extrinsic', 'card--transclusion', 'card'],
110
60
  filter: (data): data is { subject: Markdown.Document | DataType.Text } =>
111
61
  Obj.instanceOf(Markdown.Document, data.subject) || Obj.instanceOf(DataType.Text, data.subject),
112
- component: ({ data, role }) => <MarkdownPreview {...data} role={role} />,
62
+ component: ({ data, role }) => <MarkdownCard {...data} role={role} />,
113
63
  }),
114
64
  ]);
65
+
66
+ /**
67
+ * Common wrapper.
68
+ */
69
+ const Container = ({ id, subject, role }: { id: string; subject: MarkdownContainerProps['object']; role: string }) => {
70
+ const selectionManager = useCapability(AttentionCapabilities.Selection);
71
+ const settingsStore = useCapability(Capabilities.SettingsStore);
72
+ const settings = settingsStore.getStore<Markdown.Settings>(meta.id)!.value;
73
+ const { state, editorState, getViewMode, setViewMode } = useCapability(MarkdownCapabilities.State);
74
+ const viewMode = getViewMode(id);
75
+ const handleViewModeChange = useCallback<NonNullable<MarkdownContainerProps['onViewModeChange']>>(
76
+ (mode) => setViewMode(id, mode),
77
+ [id, setViewMode],
78
+ );
79
+
80
+ return (
81
+ <MarkdownContainer
82
+ id={id}
83
+ object={subject}
84
+ role={role}
85
+ settings={settings}
86
+ selectionManager={selectionManager}
87
+ extensionProviders={state.extensionProviders}
88
+ editorStateStore={editorState}
89
+ viewMode={viewMode}
90
+ onViewModeChange={handleViewModeChange}
91
+ />
92
+ );
93
+ };
@@ -2,14 +2,15 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, contributes, type PluginContext } from '@dxos/app-framework';
5
+ import { Capabilities, type PluginContext, contributes } from '@dxos/app-framework';
6
6
  import { LocalStorageStore } from '@dxos/local-storage';
7
7
  import { type EditorViewMode, createEditorStateStore } from '@dxos/react-ui-editor';
8
8
 
9
- import { MarkdownCapabilities } from './capabilities';
10
9
  import { meta } from '../meta';
11
10
  import { type Markdown, type MarkdownPluginState } from '../types';
12
11
 
12
+ import { MarkdownCapabilities } from './capabilities';
13
+
13
14
  export default (context: PluginContext) => {
14
15
  const state = new LocalStorageStore<MarkdownPluginState>(meta.id, { extensionProviders: [], viewMode: {} });
15
16
  state.prop({ key: 'viewMode', type: LocalStorageStore.json<{ [key: string]: EditorViewMode }>() });
@@ -0,0 +1,53 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Tool from '@effect/ai/Tool';
6
+ import * as Toolkit from '@effect/ai/Toolkit';
7
+ import * as Effect from 'effect/Effect';
8
+ import * as Schema from 'effect/Schema';
9
+
10
+ import { Capabilities, type Capability, type PluginContext, contributes, createIntent } from '@dxos/app-framework';
11
+ import { invariant } from '@dxos/invariant';
12
+ import { getActiveSpace } from '@dxos/plugin-space';
13
+ import { SpaceAction } from '@dxos/plugin-space/types';
14
+
15
+ import { MarkdownAction } from '../types';
16
+
17
+ // TODO(burdon): Reconcile with functions (currently reuses plugin framework intents).
18
+ const Toolkit$ = Toolkit.make(
19
+ Tool.make('create-document', {
20
+ description: 'Creates a new markdown document.',
21
+ parameters: {
22
+ name: Schema.optional(Schema.String),
23
+ content: Schema.optional(Schema.String),
24
+ },
25
+ // TODO(wittjosiah): Return document.
26
+ success: Schema.Any,
27
+ failure: Schema.Never,
28
+ }),
29
+ );
30
+
31
+ export namespace MarkdownToolkit {
32
+ export const Toolkit = Toolkit$;
33
+
34
+ export const createLayer = (context: PluginContext) =>
35
+ Toolkit$.toLayer({
36
+ 'create-document': ({ name, content }) => {
37
+ const { dispatch } = context.getCapability(Capabilities.IntentDispatcher);
38
+ const space = getActiveSpace(context);
39
+ invariant(space, 'No active space');
40
+
41
+ return Effect.gen(function* () {
42
+ const { object } = yield* dispatch(createIntent(MarkdownAction.Create, { name, content }));
43
+ yield* dispatch(createIntent(SpaceAction.AddObject, { object, target: space }));
44
+ return { id: object.id };
45
+ }).pipe(Effect.orDie);
46
+ },
47
+ });
48
+ }
49
+
50
+ export default (context: PluginContext): Capability<any>[] => [
51
+ contributes(Capabilities.Toolkit, MarkdownToolkit.Toolkit),
52
+ contributes(Capabilities.ToolkitHandler, MarkdownToolkit.createLayer(context)),
53
+ ];
@@ -2,44 +2,43 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
- import { type StoryObj, type Meta } from '@storybook/react-vite';
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React from 'react';
9
7
 
10
8
  import { IntentPlugin } from '@dxos/app-framework';
11
9
  import { withPluginManager } from '@dxos/app-framework/testing';
12
10
  import { Markdown } from '@dxos/plugin-markdown/types';
13
11
  import { faker } from '@dxos/random';
12
+ import { withTheme } from '@dxos/react-ui/testing';
14
13
  import { CardContainer } from '@dxos/react-ui-stack/testing';
15
- import { withTheme, withLayout } from '@dxos/storybook-utils';
16
14
 
17
- import { MarkdownPreview } from './MarkdownPreview';
18
15
  import { translations } from '../../translations';
19
16
 
17
+ import { MarkdownCard } from './MarkdownCard';
18
+
20
19
  faker.seed(1234);
21
20
 
22
- const meta: Meta<typeof MarkdownPreview> = {
23
- title: 'Cards/plugin-markdown',
24
- component: MarkdownPreview,
21
+ const meta: Meta<typeof MarkdownCard> = {
22
+ title: 'plugins/plugin-markdown/Card',
23
+ component: MarkdownCard,
25
24
  render: ({ role, subject, ...args }) => {
26
25
  return (
27
26
  <CardContainer icon='ph--text-aa--regular' role={role}>
28
- <MarkdownPreview role={role} subject={subject} {...args} />
27
+ <MarkdownCard role={role} subject={subject} {...args} />
29
28
  </CardContainer>
30
29
  );
31
30
  },
32
31
  decorators: [
32
+ withTheme,
33
33
  withPluginManager({
34
34
  plugins: [IntentPlugin()],
35
35
  }),
36
- withTheme,
37
- withLayout(),
38
36
  ],
39
37
  parameters: {
40
38
  layout: 'centered',
41
39
  translations,
42
40
  },
41
+ tags: ['cards'],
43
42
  };
44
43
 
45
44
  export default meta;
@@ -56,9 +55,9 @@ export const Popover: Story = {
56
55
  },
57
56
  };
58
57
 
59
- export const Extrinsic: Story = {
58
+ export const Intrinsic: Story = {
60
59
  args: {
61
- role: 'card--extrinsic',
60
+ role: 'card--intrinsic',
62
61
  subject: Markdown.makeDocument({
63
62
  name: faker.lorem.words(3),
64
63
  content: faker.lorem.paragraphs(3),
@@ -66,9 +65,9 @@ export const Extrinsic: Story = {
66
65
  },
67
66
  };
68
67
 
69
- export const Intrinsic: Story = {
68
+ export const Extrinsic: Story = {
70
69
  args: {
71
- role: 'card--intrinsic',
70
+ role: 'card--extrinsic',
72
71
  subject: Markdown.makeDocument({
73
72
  name: faker.lorem.words(3),
74
73
  content: faker.lorem.paragraphs(3),
@@ -2,49 +2,34 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { pipe } from 'effect';
5
+ import * as Function from 'effect/Function';
6
6
  import React, { useCallback } from 'react';
7
7
 
8
- import { chain, createIntent, LayoutAction, useIntentDispatcher } from '@dxos/app-framework';
8
+ import { LayoutAction, chain, createIntent, useIntentDispatcher } from '@dxos/app-framework';
9
9
  import { Obj } from '@dxos/echo';
10
10
  import { type PreviewProps } from '@dxos/plugin-preview';
11
11
  import { fullyQualifiedId } from '@dxos/react-client/echo';
12
- import { Button, Icon, useTranslation } from '@dxos/react-ui';
12
+ import { IconButton, useTranslation } from '@dxos/react-ui';
13
13
  import { Card } from '@dxos/react-ui-stack';
14
14
  import { DataType } from '@dxos/schema';
15
15
 
16
16
  import { meta } from '../../meta';
17
17
  import { Markdown } from '../../types';
18
- import { getAbstract, getFallbackName } from '../../util';
18
+ import { getContentSnippet, getFallbackName } from '../../util';
19
19
 
20
- // TODO(burdon): Factor out.
21
- const getTitle = (subject: Markdown.Document | DataType.Text, fallback: string) => {
22
- if (Obj.instanceOf(Markdown.Document, subject)) {
23
- return subject.name ?? subject.fallbackName ?? getFallbackName(subject.content?.target?.content ?? fallback);
24
- } else if (Obj.instanceOf(DataType.Text, subject)) {
25
- return getFallbackName(subject.content);
26
- }
27
- };
20
+ export type MarkdownCardProps = PreviewProps<Markdown.Document | DataType.Text>;
28
21
 
29
- // TODO(burdon): Factor out.
30
- const getSnippet = (subject: Markdown.Document | DataType.Text, fallback: string) => {
31
- if (Obj.instanceOf(Markdown.Document, subject)) {
32
- return getAbstract(subject.content?.target?.content ?? fallback);
33
- } else if (Obj.instanceOf(DataType.Text, subject)) {
34
- return getAbstract(subject.content);
35
- }
36
- };
37
-
38
- export const MarkdownPreview = ({ subject, role }: PreviewProps<Markdown.Document | DataType.Text>) => {
22
+ export const MarkdownCard = ({ subject, role }: MarkdownCardProps) => {
39
23
  const { dispatchPromise: dispatch } = useIntentDispatcher();
40
24
  const { t } = useTranslation(meta.id);
41
25
  const snippet = getSnippet(subject, t('fallback abstract'));
26
+ const info = getInfo(subject);
42
27
 
43
28
  // TODO(wittjosiah): Factor out so this component isn't dependent on the app framework.
44
29
  const handleNavigate = useCallback(
45
30
  () =>
46
31
  dispatch(
47
- pipe(
32
+ Function.pipe(
48
33
  createIntent(LayoutAction.UpdatePopover, {
49
34
  part: 'popover',
50
35
  subject: null,
@@ -58,16 +43,43 @@ export const MarkdownPreview = ({ subject, role }: PreviewProps<Markdown.Documen
58
43
 
59
44
  return (
60
45
  <Card.SurfaceRoot role={role}>
61
- <Card.Heading>{getTitle(subject, t('fallback title'))}</Card.Heading>
62
- {snippet && <Card.Text classNames='line-clamp-3 break-words col-span-2'>{snippet}</Card.Text>}
63
- {role === 'card--popover' && (
64
- <Card.Chrome>
65
- <Button onClick={handleNavigate}>
66
- <span className='grow'>{t('navigate to document label')}</span>
67
- <Icon icon='ph--arrow-right--regular' />
68
- </Button>
69
- </Card.Chrome>
70
- )}
46
+ <Card.Heading classNames='flex items-center'>
47
+ {getTitle(subject, t('fallback title'))}
48
+ <span className='grow' />
49
+ <IconButton
50
+ iconOnly
51
+ icon='ph--arrow-right--regular'
52
+ label={t('navigate to document label')}
53
+ onClick={handleNavigate}
54
+ />
55
+ </Card.Heading>
56
+ {snippet && <Card.Text classNames='line-clamp-3 text-sm text-description'>{snippet}</Card.Text>}
57
+ <Card.Text classNames='text-xs text-description'>
58
+ {info.words} {t('words label', { count: info.words })}
59
+ </Card.Text>
71
60
  </Card.SurfaceRoot>
72
61
  );
73
62
  };
63
+
64
+ const getInfo = (subject: Markdown.Document | DataType.Text) => {
65
+ const text = (Obj.instanceOf(Markdown.Document, subject) ? subject.content?.target?.content : subject.content) ?? '';
66
+ return { words: text.split(' ').length };
67
+ };
68
+
69
+ // TODO(burdon): Factor out.
70
+ const getTitle = (subject: Markdown.Document | DataType.Text, fallback: string) => {
71
+ if (Obj.instanceOf(Markdown.Document, subject)) {
72
+ return subject.name ?? subject.fallbackName ?? getFallbackName(subject.content?.target?.content ?? fallback);
73
+ } else if (Obj.instanceOf(DataType.Text, subject)) {
74
+ return getFallbackName(subject.content);
75
+ }
76
+ };
77
+
78
+ // TODO(burdon): Factor out.
79
+ const getSnippet = (subject: Markdown.Document | DataType.Text, fallback: string) => {
80
+ if (Obj.instanceOf(Markdown.Document, subject)) {
81
+ return Obj.getDescription(subject) || getContentSnippet(subject.content?.target?.content ?? fallback);
82
+ } else if (Obj.instanceOf(DataType.Text, subject)) {
83
+ return getContentSnippet(subject.content ?? fallback);
84
+ }
85
+ };
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { MarkdownCard } from './MarkdownCard';
6
+
7
+ export * from './MarkdownCard';
8
+
9
+ export default MarkdownCard;
@@ -2,28 +2,35 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
- import { type Meta } from '@storybook/react-vite';
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React, { useMemo } from 'react';
9
7
 
10
- import { Capabilities, contributes, IntentPlugin, SettingsPlugin, Surface } from '@dxos/app-framework';
8
+ import {
9
+ type Capabilities,
10
+ IntentPlugin,
11
+ LayoutAction,
12
+ SettingsPlugin,
13
+ Surface,
14
+ createIntent,
15
+ useIntentDispatcher,
16
+ } from '@dxos/app-framework';
11
17
  import { withPluginManager } from '@dxos/app-framework/testing';
12
- import { todo } from '@dxos/debug';
13
- import { Query, Type } from '@dxos/echo';
18
+ import { Obj, Query } from '@dxos/echo';
14
19
  import { AttentionPlugin } from '@dxos/plugin-attention';
15
20
  import { ClientPlugin } from '@dxos/plugin-client';
16
21
  import { GraphPlugin } from '@dxos/plugin-graph';
17
22
  import { PreviewPlugin } from '@dxos/plugin-preview';
18
- import { SpaceCapabilities, SpacePlugin } from '@dxos/plugin-space';
23
+ import { SpacePlugin } from '@dxos/plugin-space';
19
24
  import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
20
25
  import { ThemePlugin } from '@dxos/plugin-theme';
21
26
  import { faker } from '@dxos/random';
22
- import { useQuery, useSpace } from '@dxos/react-client/echo';
27
+ import { fullyQualifiedId, useQuery, useSpace } from '@dxos/react-client/echo';
28
+ import { useAsyncEffect } from '@dxos/react-ui';
29
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
30
+ import { useAttentionAttributes } from '@dxos/react-ui-attention';
23
31
  import { defaultTx } from '@dxos/react-ui-theme';
24
32
  import { DataType } from '@dxos/schema';
25
- import { createObjectFactory, Testing, type ValueGenerator } from '@dxos/schema/testing';
26
- import { withLayout } from '@dxos/storybook-utils';
33
+ import { type ValueGenerator, createObjectFactory } from '@dxos/schema/testing';
27
34
 
28
35
  import { MarkdownPlugin } from '../MarkdownPlugin';
29
36
  import { translations } from '../translations';
@@ -34,67 +41,97 @@ faker.seed(1);
34
41
  const generator: ValueGenerator = faker as any;
35
42
 
36
43
  const DefaultStory = () => {
44
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
37
45
  const space = useSpace();
38
46
  const [doc] = useQuery(space, Query.type(Markdown.Document));
39
47
  const data = useMemo(() => ({ subject: doc }), [doc]);
48
+ const id = doc && fullyQualifiedId(doc);
49
+ const attentionAttrs = useAttentionAttributes(id);
50
+
51
+ useAsyncEffect(async () => {
52
+ if (space) {
53
+ await dispatch(createIntent(LayoutAction.SwitchWorkspace, { part: 'workspace', subject: space.id }));
54
+ }
55
+ }, [space, dispatch]);
40
56
 
41
- return <Surface role='article' data={data} />;
57
+ return (
58
+ <div className='contents' {...attentionAttrs}>
59
+ <Surface role='article' data={data} limit={1} />
60
+ </div>
61
+ );
42
62
  };
43
63
 
44
- const meta: Meta<typeof DefaultStory> = {
64
+ const meta = {
45
65
  title: 'plugins/plugin-markdown/MarkdownContainer',
46
66
  render: DefaultStory,
47
67
  decorators: [
48
- withPluginManager({
68
+ withTheme,
69
+ withLayout({ container: 'column' }),
70
+ withPluginManager<{ title?: string; content?: string }>((context) => ({
49
71
  plugins: [
50
- AttentionPlugin(),
51
- ThemePlugin({ tx: defaultTx }),
52
- StorybookLayoutPlugin(),
53
72
  ClientPlugin({
54
- types: [Markdown.Document, DataType.Text, Testing.Contact],
55
- onClientInitialized: async (_, client) => {
73
+ types: [Markdown.Document, DataType.Text, DataType.Person, DataType.Organization],
74
+ onClientInitialized: async ({ client }) => {
56
75
  await client.halo.createIdentity();
57
76
  await client.spaces.waitUntilReady();
58
77
  await client.spaces.default.waitUntilReady();
78
+
59
79
  const space = client.spaces.default;
60
- const doc = Markdown.makeDocument({ name: 'Test', content: '# Test\n\n' });
61
- space.db.add(doc);
62
80
  const createObjects = createObjectFactory(space.db, generator);
63
- await createObjects([{ type: Testing.Contact, count: 10 }]);
81
+ await createObjects([{ type: DataType.Organization, count: 10 }]);
82
+
83
+ const queue = space.queues.create();
84
+ const kai = Obj.make(DataType.Person, { fullName: 'Kai' });
85
+ const dxos = Obj.make(DataType.Organization, { name: 'DXOS' });
86
+ await queue.append([kai, dxos]);
87
+
88
+ space.db.add(
89
+ Markdown.makeDocument({
90
+ name: context.args.title ?? 'Testing',
91
+ content: [
92
+ `# ${context.args.title ?? 'Testing'}`,
93
+ context.args.content ?? '',
94
+ // TODO(burdon): Popovers not currently working.
95
+ '## Here are some objects',
96
+ `![Alice](${Obj.getDXN(kai)})`,
97
+ `![DXOS](${Obj.getDXN(dxos)})`,
98
+ '',
99
+ 'END',
100
+ '',
101
+ ].join('\n\n'),
102
+ }),
103
+ );
104
+
64
105
  await space.db.flush({ indexes: true });
65
106
  },
66
107
  }),
67
- SpacePlugin(),
68
- SettingsPlugin(),
108
+ SpacePlugin({}),
109
+ GraphPlugin(),
69
110
  IntentPlugin(),
111
+ SettingsPlugin(),
112
+ // UI
113
+ ThemePlugin({ tx: defaultTx }),
114
+ AttentionPlugin(),
70
115
  MarkdownPlugin(),
71
116
  PreviewPlugin(),
72
- GraphPlugin(),
73
- ],
74
- capabilities: [
75
- // NOTE: Editor only queries for object form schemas when linking.
76
- contributes(SpaceCapabilities.ObjectForm, {
77
- objectSchema: Testing.Contact,
78
- getIntent: () => todo(),
79
- }),
80
- contributes(Capabilities.Metadata, {
81
- id: Type.getTypename(Testing.Contact),
82
- metadata: {
83
- icon: 'ph--user--regular',
84
- },
85
- }),
117
+ StorybookLayoutPlugin({}),
86
118
  ],
87
- }),
88
- withLayout({ fullscreen: true }),
119
+ })),
89
120
  ],
90
121
  parameters: {
91
- translations,
122
+ layout: 'fullscreen',
92
123
  controls: { disable: true },
124
+ translations,
93
125
  },
94
- };
126
+ } satisfies Meta<typeof Capabilities>;
95
127
 
96
128
  export default meta;
97
129
 
98
- type Story = Meta<typeof DefaultStory>;
130
+ type Story = StoryObj<typeof meta>;
99
131
 
100
- export const Default: Story = {};
132
+ export const Default: Story = {
133
+ args: {
134
+ title: 'Testing',
135
+ content: ['This is a line with **some** formatting.'].join('\n\n'),
136
+ },
137
+ };