@dxos/plugin-markdown 0.8.4-main.2c6827d → 0.8.4-main.3c1ae3b

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 (142) hide show
  1. package/dist/lib/browser/MarkdownCard-THZFDOOV.mjs +13 -0
  2. package/dist/lib/browser/MarkdownContainer-VKPSVI5F.mjs +16 -0
  3. package/dist/lib/browser/{anchor-sort-3HGPGCOO.mjs → anchor-sort-3MYLO74J.mjs} +6 -5
  4. package/dist/lib/browser/anchor-sort-3MYLO74J.mjs.map +7 -0
  5. package/dist/lib/browser/{app-graph-serializer-POZN234F.mjs → app-graph-serializer-BZJ4TQOE.mjs} +3 -3
  6. package/dist/lib/browser/{blueprint-definition-GIPKFDY5.mjs → blueprint-definition-R5T6LTPN.mjs} +3 -3
  7. package/dist/lib/browser/{chunk-K3LXOU3E.mjs → chunk-56SUMOIZ.mjs} +102 -195
  8. package/dist/lib/browser/chunk-56SUMOIZ.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-6OMOMVO7.mjs +107 -0
  10. package/dist/lib/browser/chunk-6OMOMVO7.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-QYSEJ5GP.mjs → chunk-CN35HEBX.mjs} +6 -6
  12. package/dist/lib/browser/chunk-CN35HEBX.mjs.map +7 -0
  13. package/dist/lib/browser/{chunk-PBJLFIOX.mjs → chunk-KCOBZZIL.mjs} +38 -23
  14. package/dist/lib/browser/chunk-KCOBZZIL.mjs.map +7 -0
  15. package/dist/lib/browser/{chunk-GH6GQSBL.mjs → chunk-KPH4ZPQN.mjs} +53 -5
  16. package/dist/lib/browser/chunk-KPH4ZPQN.mjs.map +7 -0
  17. package/dist/lib/browser/{chunk-22XSSNBS.mjs → chunk-NXT2E2BG.mjs} +4 -3
  18. package/dist/lib/browser/chunk-NXT2E2BG.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-Y53FQREH.mjs → chunk-RJPOHSYN.mjs} +8 -6
  20. package/dist/lib/browser/chunk-RJPOHSYN.mjs.map +7 -0
  21. package/dist/lib/browser/{chunk-2MLGSYRN.mjs → chunk-U6Y53XZK.mjs} +7 -7
  22. package/dist/lib/browser/index.mjs +10 -24
  23. package/dist/lib/browser/index.mjs.map +3 -3
  24. package/dist/lib/browser/{intent-resolver-Z5L7TXUK.mjs → intent-resolver-55ASQRIW.mjs} +3 -3
  25. package/dist/lib/browser/{intent-resolver-Z5L7TXUK.mjs.map → intent-resolver-55ASQRIW.mjs.map} +1 -1
  26. package/dist/lib/browser/meta.json +1 -1
  27. package/dist/lib/browser/{react-surface-GO5ZOKNN.mjs → react-surface-Q3C5H2KT.mjs} +21 -17
  28. package/dist/lib/browser/react-surface-Q3C5H2KT.mjs.map +7 -0
  29. package/dist/lib/browser/{settings-TZUDB5EW.mjs → settings-G3ZOXJQY.mjs} +2 -2
  30. package/dist/lib/browser/toolkit.mjs +2 -2
  31. package/dist/lib/browser/types/index.mjs +1 -1
  32. package/dist/lib/node-esm/{MarkdownCard-ZXPJLUYO.mjs → MarkdownCard-QHSSZGIY.mjs} +5 -4
  33. package/dist/lib/node-esm/{MarkdownContainer-YRDSRDCS.mjs → MarkdownContainer-G3ZQJS7A.mjs} +7 -6
  34. package/dist/lib/node-esm/{anchor-sort-PCDXEBJ2.mjs → anchor-sort-W4HCTYUQ.mjs} +6 -5
  35. package/dist/lib/node-esm/anchor-sort-W4HCTYUQ.mjs.map +7 -0
  36. package/dist/lib/node-esm/{app-graph-serializer-NF65JYAS.mjs → app-graph-serializer-OCTHXWLF.mjs} +3 -3
  37. package/dist/lib/node-esm/{blueprint-definition-ENKJZYQS.mjs → blueprint-definition-2JV3WV22.mjs} +3 -3
  38. package/dist/lib/node-esm/{chunk-PLZ7EVCT.mjs → chunk-6F6FCTIA.mjs} +53 -5
  39. package/dist/lib/node-esm/chunk-6F6FCTIA.mjs.map +7 -0
  40. package/dist/lib/node-esm/{chunk-HAIEWPU7.mjs → chunk-C5KXP2ZE.mjs} +8 -6
  41. package/dist/lib/node-esm/chunk-C5KXP2ZE.mjs.map +7 -0
  42. package/dist/lib/node-esm/{chunk-CT7CFX5G.mjs → chunk-FR6RW6DH.mjs} +102 -195
  43. package/dist/lib/node-esm/chunk-FR6RW6DH.mjs.map +7 -0
  44. package/dist/lib/node-esm/{chunk-AMHACOXW.mjs → chunk-I5JSQBPI.mjs} +4 -3
  45. package/dist/lib/node-esm/chunk-I5JSQBPI.mjs.map +7 -0
  46. package/dist/lib/node-esm/{chunk-KCHUTL3Q.mjs → chunk-KM7KYV6W.mjs} +7 -7
  47. package/dist/lib/node-esm/chunk-KYWXTMKI.mjs +108 -0
  48. package/dist/lib/node-esm/chunk-KYWXTMKI.mjs.map +7 -0
  49. package/dist/lib/node-esm/{chunk-PIOOG7A5.mjs → chunk-R3SGV4ES.mjs} +38 -23
  50. package/dist/lib/node-esm/chunk-R3SGV4ES.mjs.map +7 -0
  51. package/dist/lib/node-esm/{chunk-NGYJNQ6A.mjs → chunk-YFRTKXTB.mjs} +6 -6
  52. package/dist/lib/node-esm/chunk-YFRTKXTB.mjs.map +7 -0
  53. package/dist/lib/node-esm/index.mjs +10 -24
  54. package/dist/lib/node-esm/index.mjs.map +3 -3
  55. package/dist/lib/node-esm/{intent-resolver-6B3PFQ5F.mjs → intent-resolver-DTBVWCNO.mjs} +3 -3
  56. package/dist/lib/node-esm/{intent-resolver-6B3PFQ5F.mjs.map → intent-resolver-DTBVWCNO.mjs.map} +1 -1
  57. package/dist/lib/node-esm/meta.json +1 -1
  58. package/dist/lib/node-esm/{react-surface-I46BPCWT.mjs → react-surface-QWRT4SD6.mjs} +21 -17
  59. package/dist/lib/node-esm/react-surface-QWRT4SD6.mjs.map +7 -0
  60. package/dist/lib/node-esm/{settings-CJ3T5EX4.mjs → settings-IBFFCGNL.mjs} +2 -2
  61. package/dist/lib/node-esm/toolkit.mjs +2 -2
  62. package/dist/lib/node-esm/types/index.mjs +1 -1
  63. package/dist/types/src/MarkdownPlugin.d.ts.map +1 -1
  64. package/dist/types/src/capabilities/anchor-sort.d.ts.map +1 -1
  65. package/dist/types/src/components/MarkdownCard/MarkdownCard.d.ts +14 -1
  66. package/dist/types/src/components/MarkdownCard/MarkdownCard.d.ts.map +1 -1
  67. package/dist/types/src/components/MarkdownContainer.d.ts +6 -1
  68. package/dist/types/src/components/MarkdownContainer.d.ts.map +1 -1
  69. package/dist/types/src/components/MarkdownContainer.stories.d.ts +1 -0
  70. package/dist/types/src/components/MarkdownContainer.stories.d.ts.map +1 -1
  71. package/dist/types/src/components/MarkdownEditor/MarkdownEditorContent.d.ts +8 -5
  72. package/dist/types/src/components/MarkdownEditor/MarkdownEditorContent.d.ts.map +1 -1
  73. package/dist/types/src/components/Suggestions.stories.d.ts.map +1 -1
  74. package/dist/types/src/components/index.d.ts +5 -2
  75. package/dist/types/src/components/index.d.ts.map +1 -1
  76. package/dist/types/src/functions/open.d.ts.map +1 -1
  77. package/dist/types/src/functions/update.d.ts.map +1 -1
  78. package/dist/types/src/testing.d.ts +2 -2
  79. package/dist/types/src/testing.d.ts.map +1 -1
  80. package/dist/types/src/translations.d.ts +1 -0
  81. package/dist/types/src/translations.d.ts.map +1 -1
  82. package/dist/types/src/types/Markdown.d.ts +6 -6
  83. package/dist/types/src/types/Markdown.d.ts.map +1 -1
  84. package/dist/types/src/types/MarkdownAction.d.ts +3 -3
  85. package/dist/types/src/util.d.ts +3 -0
  86. package/dist/types/src/util.d.ts.map +1 -1
  87. package/dist/types/src/util.test.d.ts +2 -0
  88. package/dist/types/src/util.test.d.ts.map +1 -0
  89. package/dist/types/tsconfig.tsbuildinfo +1 -1
  90. package/package.json +44 -44
  91. package/src/MarkdownPlugin.tsx +5 -21
  92. package/src/capabilities/anchor-sort.ts +4 -3
  93. package/src/capabilities/artifact-definition.ts +1 -1
  94. package/src/capabilities/intent-resolver.ts +1 -1
  95. package/src/capabilities/react-surface.tsx +32 -28
  96. package/src/components/MarkdownCard/MarkdownCard.tsx +39 -32
  97. package/src/components/MarkdownContainer.tsx +68 -73
  98. package/src/components/MarkdownEditor/MarkdownEditor.tsx +5 -5
  99. package/src/components/MarkdownEditor/MarkdownEditorContent.tsx +24 -8
  100. package/src/components/Suggestions.stories.tsx +2 -1
  101. package/src/components/index.ts +8 -3
  102. package/src/functions/create.test.ts +14 -18
  103. package/src/functions/open.ts +3 -2
  104. package/src/functions/update.test.ts +17 -21
  105. package/src/functions/update.ts +3 -2
  106. package/src/hooks/useExtensions.tsx +2 -2
  107. package/src/hooks/useLinkQuery.ts +10 -10
  108. package/src/testing.ts +5 -5
  109. package/src/translations.ts +1 -0
  110. package/src/types/Markdown.ts +4 -5
  111. package/src/util.test.ts +44 -0
  112. package/src/util.tsx +72 -4
  113. package/dist/lib/browser/MarkdownCard-JYMDPKV5.mjs +0 -12
  114. package/dist/lib/browser/MarkdownContainer-Y75XSVBX.mjs +0 -15
  115. package/dist/lib/browser/anchor-sort-3HGPGCOO.mjs.map +0 -7
  116. package/dist/lib/browser/chunk-22XSSNBS.mjs.map +0 -7
  117. package/dist/lib/browser/chunk-GH6GQSBL.mjs.map +0 -7
  118. package/dist/lib/browser/chunk-K3LXOU3E.mjs.map +0 -7
  119. package/dist/lib/browser/chunk-PBJLFIOX.mjs.map +0 -7
  120. package/dist/lib/browser/chunk-QYSEJ5GP.mjs.map +0 -7
  121. package/dist/lib/browser/chunk-Y53FQREH.mjs.map +0 -7
  122. package/dist/lib/browser/react-surface-GO5ZOKNN.mjs.map +0 -7
  123. package/dist/lib/node-esm/anchor-sort-PCDXEBJ2.mjs.map +0 -7
  124. package/dist/lib/node-esm/chunk-AMHACOXW.mjs.map +0 -7
  125. package/dist/lib/node-esm/chunk-CT7CFX5G.mjs.map +0 -7
  126. package/dist/lib/node-esm/chunk-HAIEWPU7.mjs.map +0 -7
  127. package/dist/lib/node-esm/chunk-NGYJNQ6A.mjs.map +0 -7
  128. package/dist/lib/node-esm/chunk-PIOOG7A5.mjs.map +0 -7
  129. package/dist/lib/node-esm/chunk-PLZ7EVCT.mjs.map +0 -7
  130. package/dist/lib/node-esm/react-surface-I46BPCWT.mjs.map +0 -7
  131. /package/dist/lib/browser/{MarkdownCard-JYMDPKV5.mjs.map → MarkdownCard-THZFDOOV.mjs.map} +0 -0
  132. /package/dist/lib/browser/{MarkdownContainer-Y75XSVBX.mjs.map → MarkdownContainer-VKPSVI5F.mjs.map} +0 -0
  133. /package/dist/lib/browser/{app-graph-serializer-POZN234F.mjs.map → app-graph-serializer-BZJ4TQOE.mjs.map} +0 -0
  134. /package/dist/lib/browser/{blueprint-definition-GIPKFDY5.mjs.map → blueprint-definition-R5T6LTPN.mjs.map} +0 -0
  135. /package/dist/lib/browser/{chunk-2MLGSYRN.mjs.map → chunk-U6Y53XZK.mjs.map} +0 -0
  136. /package/dist/lib/browser/{settings-TZUDB5EW.mjs.map → settings-G3ZOXJQY.mjs.map} +0 -0
  137. /package/dist/lib/node-esm/{MarkdownCard-ZXPJLUYO.mjs.map → MarkdownCard-QHSSZGIY.mjs.map} +0 -0
  138. /package/dist/lib/node-esm/{MarkdownContainer-YRDSRDCS.mjs.map → MarkdownContainer-G3ZQJS7A.mjs.map} +0 -0
  139. /package/dist/lib/node-esm/{app-graph-serializer-NF65JYAS.mjs.map → app-graph-serializer-OCTHXWLF.mjs.map} +0 -0
  140. /package/dist/lib/node-esm/{blueprint-definition-ENKJZYQS.mjs.map → blueprint-definition-2JV3WV22.mjs.map} +0 -0
  141. /package/dist/lib/node-esm/{chunk-KCHUTL3Q.mjs.map → chunk-KM7KYV6W.mjs.map} +0 -0
  142. /package/dist/lib/node-esm/{settings-CJ3T5EX4.mjs.map → settings-IBFFCGNL.mjs.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-markdown",
3
- "version": "0.8.4-main.2c6827d",
3
+ "version": "0.8.4-main.3c1ae3b",
4
4
  "description": "DXOS Surface plugin for interacting with Markdown",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -54,40 +54,40 @@
54
54
  "@preact/signals-core": "^1.12.1",
55
55
  "@radix-ui/react-context": "1.1.1",
56
56
  "react-dropzone": "^14.2.3",
57
- "@dxos/ai": "0.8.4-main.2c6827d",
58
- "@dxos/assistant": "0.8.4-main.2c6827d",
59
- "@dxos/blueprints": "0.8.4-main.2c6827d",
60
- "@dxos/client-protocol": "0.8.4-main.2c6827d",
61
- "@dxos/echo-db": "0.8.4-main.2c6827d",
62
- "@dxos/app-framework": "0.8.4-main.2c6827d",
63
- "@dxos/async": "0.8.4-main.2c6827d",
64
- "@dxos/effect": "0.8.4-main.2c6827d",
65
- "@dxos/echo": "0.8.4-main.2c6827d",
66
- "@dxos/functions": "0.8.4-main.2c6827d",
67
- "@dxos/invariant": "0.8.4-main.2c6827d",
68
- "@dxos/keys": "0.8.4-main.2c6827d",
69
- "@dxos/functions-runtime": "0.8.4-main.2c6827d",
70
- "@dxos/lit-ui": "0.8.4-main.2c6827d",
71
- "@dxos/live-object": "0.8.4-main.2c6827d",
72
- "@dxos/local-storage": "0.8.4-main.2c6827d",
73
- "@dxos/log": "0.8.4-main.2c6827d",
74
- "@dxos/plugin-client": "0.8.4-main.2c6827d",
75
- "@dxos/plugin-attention": "0.8.4-main.2c6827d",
76
- "@dxos/plugin-deck": "0.8.4-main.2c6827d",
77
- "@dxos/plugin-graph": "0.8.4-main.2c6827d",
78
- "@dxos/plugin-preview": "0.8.4-main.2c6827d",
79
- "@dxos/plugin-space": "0.8.4-main.2c6827d",
80
- "@dxos/react-client": "0.8.4-main.2c6827d",
81
- "@dxos/plugin-theme": "0.8.4-main.2c6827d",
82
- "@dxos/react-hooks": "0.8.4-main.2c6827d",
83
- "@dxos/react-ui-attention": "0.8.4-main.2c6827d",
84
- "@dxos/react-ui-form": "0.8.4-main.2c6827d",
85
- "@dxos/react-ui-editor": "0.8.4-main.2c6827d",
86
- "@dxos/react-ui-menu": "0.8.4-main.2c6827d",
87
- "@dxos/react-ui-stack": "0.8.4-main.2c6827d",
88
- "@dxos/schema": "0.8.4-main.2c6827d",
89
- "@dxos/types": "0.8.4-main.2c6827d",
90
- "@dxos/util": "0.8.4-main.2c6827d"
57
+ "@dxos/app-framework": "0.8.4-main.3c1ae3b",
58
+ "@dxos/ai": "0.8.4-main.3c1ae3b",
59
+ "@dxos/assistant": "0.8.4-main.3c1ae3b",
60
+ "@dxos/async": "0.8.4-main.3c1ae3b",
61
+ "@dxos/client-protocol": "0.8.4-main.3c1ae3b",
62
+ "@dxos/blueprints": "0.8.4-main.3c1ae3b",
63
+ "@dxos/echo": "0.8.4-main.3c1ae3b",
64
+ "@dxos/echo-db": "0.8.4-main.3c1ae3b",
65
+ "@dxos/functions": "0.8.4-main.3c1ae3b",
66
+ "@dxos/effect": "0.8.4-main.3c1ae3b",
67
+ "@dxos/functions-runtime": "0.8.4-main.3c1ae3b",
68
+ "@dxos/invariant": "0.8.4-main.3c1ae3b",
69
+ "@dxos/keys": "0.8.4-main.3c1ae3b",
70
+ "@dxos/lit-ui": "0.8.4-main.3c1ae3b",
71
+ "@dxos/live-object": "0.8.4-main.3c1ae3b",
72
+ "@dxos/local-storage": "0.8.4-main.3c1ae3b",
73
+ "@dxos/log": "0.8.4-main.3c1ae3b",
74
+ "@dxos/plugin-attention": "0.8.4-main.3c1ae3b",
75
+ "@dxos/plugin-client": "0.8.4-main.3c1ae3b",
76
+ "@dxos/plugin-deck": "0.8.4-main.3c1ae3b",
77
+ "@dxos/plugin-graph": "0.8.4-main.3c1ae3b",
78
+ "@dxos/plugin-preview": "0.8.4-main.3c1ae3b",
79
+ "@dxos/plugin-space": "0.8.4-main.3c1ae3b",
80
+ "@dxos/plugin-theme": "0.8.4-main.3c1ae3b",
81
+ "@dxos/react-client": "0.8.4-main.3c1ae3b",
82
+ "@dxos/react-ui-attention": "0.8.4-main.3c1ae3b",
83
+ "@dxos/react-hooks": "0.8.4-main.3c1ae3b",
84
+ "@dxos/react-ui-editor": "0.8.4-main.3c1ae3b",
85
+ "@dxos/react-ui-menu": "0.8.4-main.3c1ae3b",
86
+ "@dxos/react-ui-form": "0.8.4-main.3c1ae3b",
87
+ "@dxos/react-ui-stack": "0.8.4-main.3c1ae3b",
88
+ "@dxos/schema": "0.8.4-main.3c1ae3b",
89
+ "@dxos/util": "0.8.4-main.3c1ae3b",
90
+ "@dxos/types": "0.8.4-main.3c1ae3b"
91
91
  },
92
92
  "devDependencies": {
93
93
  "@effect-atom/atom-react": "^0.3.4",
@@ -98,13 +98,13 @@
98
98
  "react": "~19.2.0",
99
99
  "react-dom": "~19.2.0",
100
100
  "vite": "7.1.9",
101
- "@dxos/plugin-storybook-layout": "0.8.4-main.2c6827d",
102
- "@dxos/debug": "0.8.4-main.2c6827d",
103
- "@dxos/react-ui": "0.8.4-main.2c6827d",
104
- "@dxos/plugin-theme": "0.8.4-main.2c6827d",
105
- "@dxos/react-ui-theme": "0.8.4-main.2c6827d",
106
- "@dxos/storybook-utils": "0.8.4-main.2c6827d",
107
- "@dxos/random": "0.8.4-main.2c6827d"
101
+ "@dxos/debug": "0.8.4-main.3c1ae3b",
102
+ "@dxos/plugin-storybook-layout": "0.8.4-main.3c1ae3b",
103
+ "@dxos/plugin-theme": "0.8.4-main.3c1ae3b",
104
+ "@dxos/random": "0.8.4-main.3c1ae3b",
105
+ "@dxos/react-ui": "0.8.4-main.3c1ae3b",
106
+ "@dxos/react-ui-theme": "0.8.4-main.3c1ae3b",
107
+ "@dxos/storybook-utils": "0.8.4-main.3c1ae3b"
108
108
  },
109
109
  "peerDependencies": {
110
110
  "@effect-atom/atom-react": "^0.3.4",
@@ -112,8 +112,8 @@
112
112
  "effect": "^3.13.3",
113
113
  "react": "^19.0.0",
114
114
  "react-dom": "^19.0.0",
115
- "@dxos/react-ui": "0.8.4-main.2c6827d",
116
- "@dxos/react-ui-theme": "0.8.4-main.2c6827d"
115
+ "@dxos/react-ui": "0.8.4-main.3c1ae3b",
116
+ "@dxos/react-ui-theme": "0.8.4-main.3c1ae3b"
117
117
  },
118
118
  "publishConfig": {
119
119
  "access": "public"
@@ -4,10 +4,9 @@
4
4
 
5
5
  import { Capabilities, Events, contributes, createIntent, defineModule, definePlugin } from '@dxos/app-framework';
6
6
  import { type Obj, Ref } from '@dxos/echo';
7
+ import { createDocAccessor, getTextInRange } from '@dxos/echo-db';
7
8
  import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
8
- import { SpaceCapabilities } from '@dxos/plugin-space';
9
- import { defineObjectForm } from '@dxos/plugin-space/types';
10
- import { createDocAccessor, getTextInRange } from '@dxos/react-client/echo';
9
+ import { type CreateObjectIntent } from '@dxos/plugin-space/types';
11
10
  import { translations as editorTranslations } from '@dxos/react-ui-editor';
12
11
  import { Text } from '@dxos/schema';
13
12
 
@@ -72,30 +71,15 @@ export const MarkdownPlugin = definePlugin(meta, () => [
72
71
  return getTextInRange(createDocAccessor(doc.content.target!, ['content']), start, end);
73
72
  }
74
73
  },
74
+ createObjectIntent: (() => createIntent(MarkdownAction.Create)) satisfies CreateObjectIntent,
75
+ addToCollectionOnCreate: true,
75
76
  },
76
77
  }),
77
78
  }),
78
- defineModule({
79
- id: `${meta.id}/module/object-form`,
80
- activatesOn: ClientEvents.SetupSchema,
81
- activate: () =>
82
- contributes(
83
- SpaceCapabilities.ObjectForm,
84
- defineObjectForm({
85
- objectSchema: Markdown.Document,
86
- getIntent: () => createIntent(MarkdownAction.Create, {}),
87
- }),
88
- ),
89
- }),
90
79
  defineModule({
91
80
  id: `${meta.id}/module/schema`,
92
81
  activatesOn: ClientEvents.SetupSchema,
93
- activate: () => contributes(ClientCapabilities.Schema, [Text.Text]),
94
- }),
95
- defineModule({
96
- id: `${meta.id}/module/whitelist-schema`,
97
- activatesOn: ClientEvents.SetupSchema,
98
- activate: () => contributes(ClientCapabilities.SchemaWhiteList, [Markdown.Document]),
82
+ activate: () => contributes(ClientCapabilities.Schema, [Markdown.Document, Text.Text]),
99
83
  }),
100
84
  defineModule({
101
85
  id: `${meta.id}/module/react-surface`,
@@ -3,7 +3,8 @@
3
3
  //
4
4
 
5
5
  import { Capabilities, contributes } from '@dxos/app-framework';
6
- import { createDocAccessor, getRangeFromCursor, getTarget } from '@dxos/react-client/echo';
6
+ import { Relation } from '@dxos/echo';
7
+ import { createDocAccessor, getRangeFromCursor } from '@dxos/echo-db';
7
8
  import { type AnchoredTo } from '@dxos/types';
8
9
 
9
10
  import { Markdown } from '../types';
@@ -12,9 +13,9 @@ export default () =>
12
13
  contributes(Capabilities.AnchorSort, {
13
14
  key: Markdown.Document.typename,
14
15
  sort: (anchorA: AnchoredTo.AnchoredTo, anchorB: AnchoredTo.AnchoredTo) => {
15
- const doc = getTarget(anchorA) as Markdown.Document;
16
+ const doc = Relation.getTarget(anchorA) as Markdown.Document;
16
17
  const accessor = doc.content.target ? createDocAccessor(doc.content.target, ['content']) : undefined;
17
- if (doc !== getTarget(anchorB) || !accessor) {
18
+ if (doc !== Relation.getTarget(anchorB) || !accessor) {
18
19
  return 0;
19
20
  }
20
21
 
@@ -94,7 +94,7 @@ export default () => {
94
94
  }),
95
95
  execute: async ({ id }, { extensions }) => {
96
96
  invariant(extensions?.space, 'No space');
97
- const document = await extensions.space.db.query(Filter.ids(ArtifactId.toDXN(id).toString())).first();
97
+ const document = await extensions.space.db.query(Filter.id(ArtifactId.toDXN(id).toString())).first();
98
98
  assertArgument(Obj.instanceOf(Markdown.Document, document), 'document', 'Invalid type');
99
99
 
100
100
  const { content } = await document.content?.load();
@@ -14,7 +14,7 @@ import {
14
14
  createResolver,
15
15
  } from '@dxos/app-framework';
16
16
  import { Obj } from '@dxos/echo';
17
- import { createDocAccessor, getRangeFromCursor } from '@dxos/react-client/echo';
17
+ import { createDocAccessor, getRangeFromCursor } from '@dxos/echo-db';
18
18
 
19
19
  import { Markdown, MarkdownAction } from '../types';
20
20
 
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React, { useCallback } from 'react';
5
+ import React, { forwardRef, useCallback } from 'react';
6
6
 
7
7
  import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
8
8
  import { SurfaceCardRole, useCapability } from '@dxos/app-framework/react';
@@ -25,8 +25,8 @@ export default () =>
25
25
  role: ['article', 'section', 'tabpanel'],
26
26
  filter: (data): data is { subject: Markdown.Document; variant: undefined } =>
27
27
  Obj.instanceOf(Markdown.Document, data.subject) && !data.variant,
28
- component: ({ data, role }) => {
29
- return <Container id={Obj.getDXN(data.subject).toString()} subject={data.subject} role={role} />;
28
+ component: ({ data, role, ref }) => {
29
+ return <Container id={Obj.getDXN(data.subject).toString()} subject={data.subject} role={role} ref={ref} />;
30
30
  },
31
31
  }),
32
32
  createSurface({
@@ -59,35 +59,39 @@ export default () =>
59
59
  role: SurfaceCardRole.literals as any,
60
60
  filter: (data): data is { subject: Markdown.Document | Text.Text } =>
61
61
  Obj.instanceOf(Markdown.Document, data.subject) || Obj.instanceOf(Text.Text, data.subject),
62
- component: ({ data, role }) => <MarkdownCard {...data} role={role as SurfaceCardRole} />,
62
+ component: ({ data, role, ref }) => <MarkdownCard {...data} role={role as SurfaceCardRole} ref={ref} />,
63
63
  }),
64
64
  ]);
65
65
 
66
66
  /**
67
67
  * Common wrapper.
68
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
- );
69
+ // TOOD(burdon): Use common type def.
70
+ const Container = forwardRef<HTMLDivElement, { id: string; subject: MarkdownContainerProps['object']; role: string }>(
71
+ ({ id, subject, role }, forwardedRef) => {
72
+ const selectionManager = useCapability(AttentionCapabilities.Selection);
73
+ const settingsStore = useCapability(Capabilities.SettingsStore);
74
+ const settings = settingsStore.getStore<Markdown.Settings>(meta.id)!.value;
75
+ const { state, editorState, getViewMode, setViewMode } = useCapability(MarkdownCapabilities.State);
76
+ const viewMode = getViewMode(id);
77
+ const handleViewModeChange = useCallback<NonNullable<MarkdownContainerProps['onViewModeChange']>>(
78
+ (mode) => setViewMode(id, mode),
79
+ [id, setViewMode],
80
+ );
79
81
 
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
- };
82
+ return (
83
+ <MarkdownContainer
84
+ id={id}
85
+ object={subject}
86
+ role={role}
87
+ settings={settings}
88
+ selectionManager={selectionManager}
89
+ extensionProviders={state.extensionProviders}
90
+ editorStateStore={editorState}
91
+ viewMode={viewMode}
92
+ onViewModeChange={handleViewModeChange}
93
+ ref={forwardedRef}
94
+ />
95
+ );
96
+ },
97
+ );
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import * as Function from 'effect/Function';
6
- import React, { useCallback } from 'react';
6
+ import React, { forwardRef, useCallback, useMemo } from 'react';
7
7
 
8
8
  import { LayoutAction, chain, createIntent } from '@dxos/app-framework';
9
9
  import { useIntentDispatcher } from '@dxos/app-framework/react';
@@ -16,19 +16,20 @@ import { Text } from '@dxos/schema';
16
16
  import { meta } from '../../meta';
17
17
  import { Markdown } from '../../types';
18
18
  import { getContentSnippet, getFallbackName } from '../../util';
19
+ import { MarkdownEditor } from '../MarkdownEditor';
19
20
 
20
21
  export type MarkdownCardProps = CardPreviewProps<Markdown.Document | Text.Text>;
21
22
 
22
- export const MarkdownCard = ({ subject, role }: MarkdownCardProps) => {
23
- const { dispatchPromise: dispatch } = useIntentDispatcher();
24
- const { t } = useTranslation(meta.id);
25
- const snippet = getSnippet(subject, t('fallback abstract'));
26
- const info = getInfo(subject);
23
+ export const MarkdownCard = forwardRef<HTMLDivElement, MarkdownCardProps>(
24
+ ({ subject, role }: MarkdownCardProps, forwardedRef) => {
25
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
26
+ const { t } = useTranslation(meta.id);
27
+ const snippet = useMemo(() => getSnippet(subject, t('fallback abstract')), [subject]);
28
+ const info = getInfo(subject);
27
29
 
28
- // TODO(wittjosiah): Factor out so this component isn't dependent on the app framework.
29
- const handleNavigate = useCallback(
30
- () =>
31
- dispatch(
30
+ // TODO(wittjosiah): Factor out so this component isn't dependent on the app framework.
31
+ const handleNavigate = useCallback(() => {
32
+ void dispatch(
32
33
  Function.pipe(
33
34
  createIntent(LayoutAction.UpdatePopover, {
34
35
  part: 'popover',
@@ -40,29 +41,35 @@ export const MarkdownCard = ({ subject, role }: MarkdownCardProps) => {
40
41
  subject: [Obj.getDXN(subject).toString()],
41
42
  }),
42
43
  ),
43
- ),
44
- [dispatch, subject],
45
- );
44
+ );
45
+ }, [dispatch, subject]);
46
46
 
47
- return (
48
- <Card.SurfaceRoot role={role}>
49
- <Card.Heading classNames='flex items-center'>
50
- {getTitle(subject, t('fallback title'))}
51
- <span className='grow' />
52
- <IconButton
53
- iconOnly
54
- icon='ph--arrow-right--regular'
55
- label={t('navigate to document label')}
56
- onClick={handleNavigate}
57
- />
58
- </Card.Heading>
59
- {snippet && <Card.Text classNames='line-clamp-3 text-sm text-description'>{snippet}</Card.Text>}
60
- <Card.Text classNames='text-xs text-description'>
61
- {info.words} {t('words label', { count: info.words })}
62
- </Card.Text>
63
- </Card.SurfaceRoot>
64
- );
65
- };
47
+ return (
48
+ <Card.SurfaceRoot role={role} ref={forwardedRef}>
49
+ <Card.Heading classNames='flex items-center'>
50
+ {getTitle(subject, t('fallback title'))}
51
+ <span className='grow' />
52
+ <IconButton
53
+ iconOnly
54
+ icon='ph--arrow-right--regular'
55
+ label={t('navigate to document label')}
56
+ onClick={handleNavigate}
57
+ />
58
+ </Card.Heading>
59
+ {snippet && (
60
+ <Card.Text classNames='flex max-h-[300px] overflow-hidden'>
61
+ <MarkdownEditor.Root id={subject.id} viewMode='readonly'>
62
+ <MarkdownEditor.Content initialValue={snippet} slots={{}} classNames='!bg-transparent' />
63
+ </MarkdownEditor.Root>
64
+ </Card.Text>
65
+ )}
66
+ <Card.Text classNames='text-xs text-description'>
67
+ {info.words} {t('words label', { count: info.words })}
68
+ </Card.Text>
69
+ </Card.SurfaceRoot>
70
+ );
71
+ },
72
+ );
66
73
 
67
74
  const getInfo = (subject: Markdown.Document | Text.Text) => {
68
75
  const text = (Obj.instanceOf(Markdown.Document, subject) ? subject.content?.target?.content : subject.content) ?? '';
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { type Extension } from '@codemirror/state';
6
6
  import { Atom } from '@effect-atom/atom-react';
7
- import React, { useMemo } from 'react';
7
+ import React, { forwardRef, useMemo } from 'react';
8
8
 
9
9
  import { Capabilities } from '@dxos/app-framework';
10
10
  import { useAppGraph, useCapabilities } from '@dxos/app-framework/react';
@@ -29,85 +29,80 @@ export type MarkdownContainerProps = {
29
29
  Pick<MarkdownEditorContentProps, 'editorStateStore'> &
30
30
  Pick<MarkdownPluginState, 'extensionProviders'>);
31
31
 
32
- export const MarkdownContainer = ({
33
- id,
34
- role,
35
- object,
36
- settings,
37
- extensionProviders,
38
- ...props
39
- }: MarkdownContainerProps) => {
40
- const space = getSpace(object);
41
- const isDocument = Obj.instanceOf(Markdown.Document, object);
42
- const isText = Obj.instanceOf(Text.Text, object);
43
- const attendableId = isDocument ? Obj.getDXN(object).toString() : undefined;
32
+ export const MarkdownContainer = forwardRef<HTMLDivElement, MarkdownContainerProps>(
33
+ ({ id, role, object, settings, extensionProviders, ...props }, forwardedRef) => {
34
+ const space = getSpace(object);
35
+ const isDocument = Obj.instanceOf(Markdown.Document, object);
36
+ const isText = Obj.instanceOf(Text.Text, object);
37
+ const attendableId = isDocument ? Obj.getDXN(object).toString() : undefined;
44
38
 
45
- // Extensions from other plugins.
46
- // TODO(burdon): Document MarkdownPluginState.extensionProviders
47
- const otherExtensionProviders = useCapabilities(MarkdownCapabilities.Extensions);
48
- const extensions = useMemo<Extension[]>(() => {
49
- if (!Obj.instanceOf(Markdown.Document, object)) {
50
- return [];
51
- }
39
+ // Extensions from other plugins.
40
+ // TODO(burdon): Document MarkdownPluginState.extensionProviders
41
+ const otherExtensionProviders = useCapabilities(MarkdownCapabilities.Extensions);
42
+ const extensions = useMemo<Extension[]>(() => {
43
+ if (!Obj.instanceOf(Markdown.Document, object)) {
44
+ return [];
45
+ }
52
46
 
53
- return [...(otherExtensionProviders ?? []), ...(extensionProviders ?? [])]
54
- .flat()
55
- .reduce((acc: Extension[], provider) => {
56
- const extension =
57
- typeof provider === 'function' ? provider({ document: object as Markdown.Document }) : provider;
58
- if (extension) {
59
- acc.push(extension);
60
- }
47
+ return [...(otherExtensionProviders ?? []), ...(extensionProviders ?? [])]
48
+ .flat()
49
+ .reduce((acc: Extension[], provider) => {
50
+ const extension =
51
+ typeof provider === 'function' ? provider({ document: object as Markdown.Document }) : provider;
52
+ if (extension) {
53
+ acc.push(extension);
54
+ }
61
55
 
62
- return acc;
63
- }, []);
64
- }, [extensionProviders, otherExtensionProviders, object]);
56
+ return acc;
57
+ }, []);
58
+ }, [extensionProviders, otherExtensionProviders, object]);
65
59
 
66
- // Toolbar actions from app graph.
67
- const { graph } = useAppGraph();
68
- const customActions = useMemo(() => {
69
- return Atom.make((get) => {
70
- const actions = get(graph.actions(id));
71
- const nodes = actions.filter((action) => action.properties.disposition === 'toolbar');
72
- const edges = nodes.map((node) => ({ source: 'root', target: node.id }));
73
- return { nodes, edges };
74
- });
75
- }, [graph]);
60
+ // Toolbar actions from app graph.
61
+ const { graph } = useAppGraph();
62
+ const customActions = useMemo(() => {
63
+ return Atom.make((get) => {
64
+ const actions = get(graph.actions(id));
65
+ const nodes = actions.filter((action) => action.properties.disposition === 'toolbar');
66
+ const edges = nodes.map((node) => ({ source: 'root', target: node.id }));
67
+ return { nodes, edges };
68
+ });
69
+ }, [graph]);
76
70
 
77
- // File upload.
78
- const [upload] = useCapabilities(Capabilities.FileUploader);
79
- const handleFileUpload = useMemo(() => {
80
- if (!space || !upload) {
81
- return undefined;
82
- }
71
+ // File upload.
72
+ const [upload] = useCapabilities(Capabilities.FileUploader);
73
+ const handleFileUpload = useMemo(() => {
74
+ if (!space || !upload) {
75
+ return undefined;
76
+ }
83
77
 
84
- return async (file: File) => upload(space, file);
85
- }, [space, upload]);
78
+ return async (file: File) => upload(space, file);
79
+ }, [space, upload]);
86
80
 
87
- // Query for @ refs.
88
- const handleLinkQuery = useLinkQuery(space);
81
+ // Query for @ refs.
82
+ const handleLinkQuery = useLinkQuery(space);
89
83
 
90
- return (
91
- <StackItem.Content toolbar={settings.toolbar}>
92
- <MarkdownEditor.Root
93
- id={attendableId ?? id}
94
- object={object}
95
- extensions={extensions}
96
- onFileUpload={handleFileUpload}
97
- onLinkQuery={handleLinkQuery}
98
- {...props}
99
- >
100
- {settings.toolbar && (
101
- <MarkdownEditor.Toolbar id={attendableId ?? id} role={role} customActions={customActions} />
102
- )}
103
- <MarkdownEditor.Content
104
- initialValue={isDocument ? object.content?.target?.content : isText ? object.content : object.text}
105
- scrollPastEnd={role === 'article'}
106
- />
107
- <MarkdownEditor.Blocks />
108
- </MarkdownEditor.Root>
109
- </StackItem.Content>
110
- );
111
- };
84
+ return (
85
+ <StackItem.Content toolbar={settings.toolbar} ref={forwardedRef}>
86
+ <MarkdownEditor.Root
87
+ id={attendableId ?? id}
88
+ object={object}
89
+ extensions={extensions}
90
+ onFileUpload={handleFileUpload}
91
+ onLinkQuery={handleLinkQuery}
92
+ {...props}
93
+ >
94
+ {settings.toolbar && (
95
+ <MarkdownEditor.Toolbar id={attendableId ?? id} role={role} customActions={customActions} />
96
+ )}
97
+ <MarkdownEditor.Content
98
+ initialValue={isDocument ? object.content?.target?.content : isText ? object.content : object.text}
99
+ scrollPastEnd={role === 'article'}
100
+ />
101
+ <MarkdownEditor.Blocks />
102
+ </MarkdownEditor.Root>
103
+ </StackItem.Content>
104
+ );
105
+ },
106
+ );
112
107
 
113
108
  export default MarkdownContainer;
@@ -154,11 +154,11 @@ type MarkdownEditorContentProps = Omit<NaturalMarkdownEditorContentProps, 'id' |
154
154
  const MarkdownEditorContent = (props: MarkdownEditorContentProps) => {
155
155
  const {
156
156
  id,
157
- extensions,
158
157
  editorView,
159
158
  setEditorView,
160
- toolbarState,
161
159
  viewMode,
160
+ toolbarState,
161
+ extensions,
162
162
  popoverMenu: { groupsRef, ...menuProps },
163
163
  } = useMarkdownEditorContext(MarkdownEditorContent.displayName);
164
164
 
@@ -167,9 +167,9 @@ const MarkdownEditorContent = (props: MarkdownEditorContentProps) => {
167
167
  <NaturalMarkdownEditorContent
168
168
  {...props}
169
169
  id={id}
170
- extensions={extensions}
171
- toolbarState={toolbarState}
172
170
  viewMode={viewMode}
171
+ toolbarState={toolbarState}
172
+ extensions={extensions}
173
173
  ref={setEditorView}
174
174
  />
175
175
  </EditorMenuProvider>
@@ -218,7 +218,7 @@ MarkdownEditorBlocks.displayName = 'MarkdownEditor.Blocks';
218
218
  const PreviewBlock = ({ el, link }: PreviewBlock) => {
219
219
  const client = useClient();
220
220
  const dxn = DXN.parse(link.ref);
221
- const subject = client.graph.ref(dxn).target;
221
+ const subject = client.graph.makeRef(dxn).target;
222
222
  const data = useMemo(() => ({ subject }), [subject]);
223
223
 
224
224
  return createPortal(<Surface role='card--transclusion' data={data} limit={1} />, el);