@dxos/plugin-markdown 0.8.2-staging.7ac8446 → 0.8.3-main.672df60

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 (227) hide show
  1. package/dist/lib/browser/MarkdownContainer-DGPA7SEG.mjs +588 -0
  2. package/dist/lib/browser/MarkdownContainer-DGPA7SEG.mjs.map +7 -0
  3. package/dist/lib/browser/MarkdownPreview-KQN2TGK6.mjs +80 -0
  4. package/dist/lib/browser/MarkdownPreview-KQN2TGK6.mjs.map +7 -0
  5. package/dist/lib/browser/anchor-sort-VS4OZVPP.mjs +32 -0
  6. package/dist/lib/browser/anchor-sort-VS4OZVPP.mjs.map +7 -0
  7. package/dist/lib/browser/{app-graph-serializer-NOXI4IQ5.mjs → app-graph-serializer-V6RLEHVY.mjs} +5 -6
  8. package/dist/lib/browser/app-graph-serializer-V6RLEHVY.mjs.map +7 -0
  9. package/dist/lib/browser/{artifact-definition-CE6J6NY4.mjs → artifact-definition-5NAODQLG.mjs} +65 -17
  10. package/dist/lib/browser/artifact-definition-5NAODQLG.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-3ULJ4FIJ.mjs → chunk-77NGW7EO.mjs} +12 -26
  12. package/dist/lib/browser/chunk-77NGW7EO.mjs.map +7 -0
  13. package/dist/lib/browser/{chunk-QXDKFACU.mjs → chunk-C5RABVIX.mjs} +6 -5
  14. package/dist/lib/browser/chunk-C5RABVIX.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-ECSM56YC.mjs +80 -0
  16. package/dist/lib/browser/chunk-ECSM56YC.mjs.map +7 -0
  17. package/dist/lib/browser/chunk-OTOPAFWC.mjs +20 -0
  18. package/dist/lib/browser/chunk-OTOPAFWC.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-NAGMSX77.mjs → chunk-QVJETNGS.mjs} +2 -2
  20. package/dist/lib/{node-esm/chunk-ETXPC5VP.mjs.map → browser/chunk-QVJETNGS.mjs.map} +1 -1
  21. package/dist/lib/browser/index.mjs +34 -18
  22. package/dist/lib/browser/index.mjs.map +3 -3
  23. package/dist/lib/browser/intent-resolver-4GDYST4Y.mjs +65 -0
  24. package/dist/lib/browser/intent-resolver-4GDYST4Y.mjs.map +7 -0
  25. package/dist/lib/browser/meta.json +1 -1
  26. package/dist/lib/browser/react-surface-DM6B4UUJ.mjs +200 -0
  27. package/dist/lib/browser/react-surface-DM6B4UUJ.mjs.map +7 -0
  28. package/dist/lib/browser/{settings-GCSS3Y4Z.mjs → settings-W5CK4PXP.mjs} +4 -4
  29. package/dist/lib/browser/settings-W5CK4PXP.mjs.map +7 -0
  30. package/dist/lib/browser/{state-O7P5JDIH.mjs → state-KI6PJ6DT.mjs} +3 -3
  31. package/dist/lib/browser/state-KI6PJ6DT.mjs.map +7 -0
  32. package/dist/lib/browser/types/index.mjs +3 -1
  33. package/dist/lib/node/MarkdownContainer-BZK66EQD.cjs +601 -0
  34. package/dist/lib/node/MarkdownContainer-BZK66EQD.cjs.map +7 -0
  35. package/dist/lib/node/MarkdownPreview-H7FFIWJH.cjs +103 -0
  36. package/dist/lib/node/MarkdownPreview-H7FFIWJH.cjs.map +7 -0
  37. package/dist/lib/node/{thread-42R57L4K.cjs → anchor-sort-NHVF23EU.cjs} +15 -20
  38. package/dist/lib/node/anchor-sort-NHVF23EU.cjs.map +7 -0
  39. package/dist/lib/node/{app-graph-serializer-HKK3SEDN.cjs → app-graph-serializer-CLALIYN3.cjs} +10 -11
  40. package/dist/lib/node/app-graph-serializer-CLALIYN3.cjs.map +7 -0
  41. package/dist/lib/node/{artifact-definition-XGADFWCQ.cjs → artifact-definition-VEAHK7BX.cjs} +68 -21
  42. package/dist/lib/node/artifact-definition-VEAHK7BX.cjs.map +7 -0
  43. package/dist/lib/node/chunk-BBDDZLQH.cjs +58 -0
  44. package/dist/lib/node/chunk-BBDDZLQH.cjs.map +7 -0
  45. package/dist/lib/node/{chunk-7QVONRSI.cjs → chunk-G7RBJX22.cjs} +13 -41
  46. package/dist/lib/node/chunk-G7RBJX22.cjs.map +7 -0
  47. package/dist/lib/node/{chunk-DZXTXSXX.cjs → chunk-IFYSBQE5.cjs} +5 -5
  48. package/dist/lib/node/{chunk-DZXTXSXX.cjs.map → chunk-IFYSBQE5.cjs.map} +1 -1
  49. package/dist/lib/node/{chunk-UEXGNGSS.cjs → chunk-RQS4KBMG.cjs} +45 -39
  50. package/dist/lib/node/chunk-RQS4KBMG.cjs.map +7 -0
  51. package/dist/lib/node/{chunk-H5MYVP6F.cjs → chunk-ZDTL47I7.cjs} +9 -8
  52. package/dist/lib/node/chunk-ZDTL47I7.cjs.map +7 -0
  53. package/dist/lib/node/index.cjs +43 -28
  54. package/dist/lib/node/index.cjs.map +3 -3
  55. package/dist/lib/node/intent-resolver-AUZVK3NZ.cjs +78 -0
  56. package/dist/lib/node/intent-resolver-AUZVK3NZ.cjs.map +7 -0
  57. package/dist/lib/node/meta.json +1 -1
  58. package/dist/lib/node/react-surface-QBW4FFXF.cjs +213 -0
  59. package/dist/lib/node/react-surface-QBW4FFXF.cjs.map +7 -0
  60. package/dist/lib/node/{settings-S2ISUVIH.cjs → settings-IRKU3WPM.cjs} +7 -7
  61. package/dist/lib/node/settings-IRKU3WPM.cjs.map +7 -0
  62. package/dist/lib/node/{state-L44SG3ZM.cjs → state-KKDRAG7X.cjs} +7 -7
  63. package/dist/lib/node/state-KKDRAG7X.cjs.map +7 -0
  64. package/dist/lib/node/types/index.cjs +8 -6
  65. package/dist/lib/node/types/index.cjs.map +2 -2
  66. package/dist/lib/node-esm/MarkdownContainer-2DYVQ6RC.mjs +589 -0
  67. package/dist/lib/node-esm/MarkdownContainer-2DYVQ6RC.mjs.map +7 -0
  68. package/dist/lib/node-esm/MarkdownPreview-JUIXYYKF.mjs +81 -0
  69. package/dist/lib/node-esm/MarkdownPreview-JUIXYYKF.mjs.map +7 -0
  70. package/dist/lib/node-esm/anchor-sort-G2HLCYFK.mjs +33 -0
  71. package/dist/lib/node-esm/anchor-sort-G2HLCYFK.mjs.map +7 -0
  72. package/dist/lib/node-esm/{app-graph-serializer-QQ2CTHOQ.mjs → app-graph-serializer-C3RNTQGM.mjs} +5 -6
  73. package/dist/lib/node-esm/app-graph-serializer-C3RNTQGM.mjs.map +7 -0
  74. package/dist/lib/node-esm/{artifact-definition-WRG5ZRN5.mjs → artifact-definition-7TIJW2CO.mjs} +65 -17
  75. package/dist/lib/node-esm/artifact-definition-7TIJW2CO.mjs.map +7 -0
  76. package/dist/lib/node-esm/{chunk-F6UHVLH7.mjs → chunk-6RPARLIK.mjs} +12 -26
  77. package/dist/lib/node-esm/chunk-6RPARLIK.mjs.map +7 -0
  78. package/dist/lib/node-esm/{chunk-ETXPC5VP.mjs → chunk-JXXDCSMW.mjs} +2 -2
  79. package/dist/lib/{browser/chunk-NAGMSX77.mjs.map → node-esm/chunk-JXXDCSMW.mjs.map} +1 -1
  80. package/dist/lib/node-esm/chunk-KK7LP3UQ.mjs +22 -0
  81. package/dist/lib/node-esm/chunk-KK7LP3UQ.mjs.map +7 -0
  82. package/dist/lib/node-esm/chunk-NCMPVEXO.mjs +81 -0
  83. package/dist/lib/node-esm/chunk-NCMPVEXO.mjs.map +7 -0
  84. package/dist/lib/node-esm/{chunk-JAVD67QP.mjs → chunk-TCFJNUAE.mjs} +6 -5
  85. package/dist/lib/node-esm/chunk-TCFJNUAE.mjs.map +7 -0
  86. package/dist/lib/node-esm/index.mjs +34 -18
  87. package/dist/lib/node-esm/index.mjs.map +3 -3
  88. package/dist/lib/node-esm/intent-resolver-FTNXUNI2.mjs +66 -0
  89. package/dist/lib/node-esm/intent-resolver-FTNXUNI2.mjs.map +7 -0
  90. package/dist/lib/node-esm/meta.json +1 -1
  91. package/dist/lib/node-esm/react-surface-A4VAOQG6.mjs +201 -0
  92. package/dist/lib/node-esm/react-surface-A4VAOQG6.mjs.map +7 -0
  93. package/dist/lib/node-esm/{settings-ZDIFTK4N.mjs → settings-MK7D7LHQ.mjs} +4 -4
  94. package/dist/lib/node-esm/settings-MK7D7LHQ.mjs.map +7 -0
  95. package/dist/lib/node-esm/{state-DWPOKLEY.mjs → state-LLGVRYKL.mjs} +3 -3
  96. package/dist/lib/node-esm/state-LLGVRYKL.mjs.map +7 -0
  97. package/dist/lib/node-esm/types/index.mjs +3 -1
  98. package/dist/types/src/MarkdownPlugin.d.ts.map +1 -1
  99. package/dist/types/src/capabilities/anchor-sort.d.ts +6 -0
  100. package/dist/types/src/capabilities/anchor-sort.d.ts.map +1 -0
  101. package/dist/types/src/capabilities/app-graph-serializer.d.ts +2 -2
  102. package/dist/types/src/capabilities/app-graph-serializer.d.ts.map +1 -1
  103. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  104. package/dist/types/src/capabilities/index.d.ts +7 -7
  105. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  106. package/dist/types/src/capabilities/intent-resolver.d.ts +2 -2
  107. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  108. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  109. package/dist/types/src/capabilities/state.d.ts +2 -2
  110. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  111. package/dist/types/src/components/MarkdownContainer.d.ts +5 -3
  112. package/dist/types/src/components/MarkdownContainer.d.ts.map +1 -1
  113. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.d.ts +24 -0
  114. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.d.ts.map +1 -0
  115. package/dist/types/src/components/{MarkdownEditor.stories.d.ts → MarkdownEditor/MarkdownEditor.stories.d.ts} +3 -3
  116. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.stories.d.ts.map +1 -0
  117. package/dist/types/src/components/MarkdownEditor/index.d.ts +2 -0
  118. package/dist/types/src/components/MarkdownEditor/index.d.ts.map +1 -0
  119. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.d.ts +6 -0
  120. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.d.ts.map +1 -0
  121. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts +23 -0
  122. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts.map +1 -0
  123. package/dist/types/src/components/MarkdownPreview/index.d.ts +4 -0
  124. package/dist/types/src/components/MarkdownPreview/index.d.ts.map +1 -0
  125. package/dist/types/src/components/{MarkdownSettings.d.ts → MarkdownSettings/MarkdownSettings.d.ts} +1 -1
  126. package/dist/types/src/components/MarkdownSettings/MarkdownSettings.d.ts.map +1 -0
  127. package/dist/types/src/components/MarkdownSettings/index.d.ts +2 -0
  128. package/dist/types/src/components/MarkdownSettings/index.d.ts.map +1 -0
  129. package/dist/types/src/components/Suggestions.stories.d.ts +12 -0
  130. package/dist/types/src/components/Suggestions.stories.d.ts.map +1 -0
  131. package/dist/types/src/components/Toolbar.stories.d.ts +2 -2
  132. package/dist/types/src/components/Toolbar.stories.d.ts.map +1 -1
  133. package/dist/types/src/components/index.d.ts +2 -1
  134. package/dist/types/src/components/index.d.ts.map +1 -1
  135. package/dist/types/src/extensions.d.ts +8 -5
  136. package/dist/types/src/extensions.d.ts.map +1 -1
  137. package/dist/types/src/hooks/useSelectCurrentThread.d.ts.map +1 -1
  138. package/dist/types/src/translations.d.ts +4 -42
  139. package/dist/types/src/translations.d.ts.map +1 -1
  140. package/dist/types/src/types/schema.d.ts +29 -129
  141. package/dist/types/src/types/schema.d.ts.map +1 -1
  142. package/dist/types/src/types/types.d.ts +40 -88
  143. package/dist/types/src/types/types.d.ts.map +1 -1
  144. package/dist/types/src/util.d.ts +1 -0
  145. package/dist/types/src/util.d.ts.map +1 -1
  146. package/dist/types/tsconfig.tsbuildinfo +1 -1
  147. package/package.json +47 -34
  148. package/src/MarkdownPlugin.tsx +22 -12
  149. package/src/capabilities/anchor-sort.ts +30 -0
  150. package/src/capabilities/app-graph-serializer.ts +4 -5
  151. package/src/capabilities/artifact-definition.ts +48 -10
  152. package/src/capabilities/index.ts +1 -1
  153. package/src/capabilities/intent-resolver.ts +40 -12
  154. package/src/capabilities/react-surface.tsx +20 -5
  155. package/src/capabilities/settings.ts +2 -2
  156. package/src/capabilities/state.ts +4 -4
  157. package/src/components/MarkdownContainer.tsx +20 -7
  158. package/src/components/{MarkdownEditor.stories.tsx → MarkdownEditor/MarkdownEditor.stories.tsx} +22 -35
  159. package/src/components/{MarkdownEditor.tsx → MarkdownEditor/MarkdownEditor.tsx} +32 -73
  160. package/src/components/MarkdownEditor/index.ts +5 -0
  161. package/src/components/MarkdownPreview/MarkdownPreview.stories.tsx +73 -0
  162. package/src/components/MarkdownPreview/MarkdownPreview.tsx +71 -0
  163. package/src/components/MarkdownPreview/index.ts +9 -0
  164. package/src/components/{MarkdownSettings.tsx → MarkdownSettings/MarkdownSettings.tsx} +2 -2
  165. package/src/components/MarkdownSettings/index.ts +5 -0
  166. package/src/components/Suggestions.stories.tsx +217 -0
  167. package/src/components/Toolbar.stories.tsx +29 -29
  168. package/src/components/index.ts +1 -0
  169. package/src/extensions.tsx +82 -48
  170. package/src/hooks/useSelectCurrentThread.tsx +2 -2
  171. package/src/translations.ts +3 -3
  172. package/src/types/schema.ts +22 -15
  173. package/src/types/types.ts +23 -21
  174. package/src/util.tsx +8 -4
  175. package/dist/lib/browser/MarkdownContainer-T3HU27RE.mjs +0 -563
  176. package/dist/lib/browser/MarkdownContainer-T3HU27RE.mjs.map +0 -7
  177. package/dist/lib/browser/app-graph-serializer-NOXI4IQ5.mjs.map +0 -7
  178. package/dist/lib/browser/artifact-definition-CE6J6NY4.mjs.map +0 -7
  179. package/dist/lib/browser/chunk-3ULJ4FIJ.mjs.map +0 -7
  180. package/dist/lib/browser/chunk-QXDKFACU.mjs.map +0 -7
  181. package/dist/lib/browser/chunk-YCJNW2RU.mjs +0 -75
  182. package/dist/lib/browser/chunk-YCJNW2RU.mjs.map +0 -7
  183. package/dist/lib/browser/intent-resolver-42GQ6HNZ.mjs +0 -50
  184. package/dist/lib/browser/intent-resolver-42GQ6HNZ.mjs.map +0 -7
  185. package/dist/lib/browser/react-surface-RQX3CPFV.mjs +0 -176
  186. package/dist/lib/browser/react-surface-RQX3CPFV.mjs.map +0 -7
  187. package/dist/lib/browser/settings-GCSS3Y4Z.mjs.map +0 -7
  188. package/dist/lib/browser/state-O7P5JDIH.mjs.map +0 -7
  189. package/dist/lib/browser/thread-3QGCFNVZ.mjs +0 -37
  190. package/dist/lib/browser/thread-3QGCFNVZ.mjs.map +0 -7
  191. package/dist/lib/node/MarkdownContainer-6ZJIFAP6.cjs +0 -576
  192. package/dist/lib/node/MarkdownContainer-6ZJIFAP6.cjs.map +0 -7
  193. package/dist/lib/node/app-graph-serializer-HKK3SEDN.cjs.map +0 -7
  194. package/dist/lib/node/artifact-definition-XGADFWCQ.cjs.map +0 -7
  195. package/dist/lib/node/chunk-7QVONRSI.cjs.map +0 -7
  196. package/dist/lib/node/chunk-H5MYVP6F.cjs.map +0 -7
  197. package/dist/lib/node/chunk-UEXGNGSS.cjs.map +0 -7
  198. package/dist/lib/node/intent-resolver-NW27BF3W.cjs +0 -63
  199. package/dist/lib/node/intent-resolver-NW27BF3W.cjs.map +0 -7
  200. package/dist/lib/node/react-surface-5X3SMHGI.cjs +0 -189
  201. package/dist/lib/node/react-surface-5X3SMHGI.cjs.map +0 -7
  202. package/dist/lib/node/settings-S2ISUVIH.cjs.map +0 -7
  203. package/dist/lib/node/state-L44SG3ZM.cjs.map +0 -7
  204. package/dist/lib/node/thread-42R57L4K.cjs.map +0 -7
  205. package/dist/lib/node-esm/MarkdownContainer-URAPTO37.mjs +0 -564
  206. package/dist/lib/node-esm/MarkdownContainer-URAPTO37.mjs.map +0 -7
  207. package/dist/lib/node-esm/app-graph-serializer-QQ2CTHOQ.mjs.map +0 -7
  208. package/dist/lib/node-esm/artifact-definition-WRG5ZRN5.mjs.map +0 -7
  209. package/dist/lib/node-esm/chunk-4AM4VU3Y.mjs +0 -76
  210. package/dist/lib/node-esm/chunk-4AM4VU3Y.mjs.map +0 -7
  211. package/dist/lib/node-esm/chunk-F6UHVLH7.mjs.map +0 -7
  212. package/dist/lib/node-esm/chunk-JAVD67QP.mjs.map +0 -7
  213. package/dist/lib/node-esm/intent-resolver-7HOMUVHR.mjs +0 -51
  214. package/dist/lib/node-esm/intent-resolver-7HOMUVHR.mjs.map +0 -7
  215. package/dist/lib/node-esm/react-surface-6IKC3G46.mjs +0 -177
  216. package/dist/lib/node-esm/react-surface-6IKC3G46.mjs.map +0 -7
  217. package/dist/lib/node-esm/settings-ZDIFTK4N.mjs.map +0 -7
  218. package/dist/lib/node-esm/state-DWPOKLEY.mjs.map +0 -7
  219. package/dist/lib/node-esm/thread-R2KHZD6V.mjs +0 -38
  220. package/dist/lib/node-esm/thread-R2KHZD6V.mjs.map +0 -7
  221. package/dist/types/src/capabilities/thread.d.ts +0 -6
  222. package/dist/types/src/capabilities/thread.d.ts.map +0 -1
  223. package/dist/types/src/components/MarkdownEditor.d.ts +0 -39
  224. package/dist/types/src/components/MarkdownEditor.d.ts.map +0 -1
  225. package/dist/types/src/components/MarkdownEditor.stories.d.ts.map +0 -1
  226. package/dist/types/src/components/MarkdownSettings.d.ts.map +0 -1
  227. package/src/capabilities/thread.ts +0 -35
@@ -5,15 +5,16 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { type Meta } from '@storybook/react';
8
- import React, { type FC, useState } from 'react';
8
+ import React, { type FC, useCallback, useState } from 'react';
9
9
 
10
+ import { invariant } from '@dxos/invariant';
10
11
  import { PublicKey } from '@dxos/keys';
11
- import { create } from '@dxos/live-object';
12
+ import { live } from '@dxos/live-object';
12
13
  import { faker } from '@dxos/random';
13
14
  import { createDocAccessor, createObject } from '@dxos/react-client/echo';
14
15
  import { useThemeContext } from '@dxos/react-ui';
15
16
  import {
16
- type EditorAction,
17
+ EditorToolbar,
17
18
  type Comment,
18
19
  comments,
19
20
  createBasicExtensions,
@@ -21,26 +22,23 @@ import {
21
22
  createMarkdownExtensions,
22
23
  createThemeExtensions,
23
24
  decorateMarkdown,
24
- editorContent,
25
+ editorSlots,
25
26
  formattingKeymap,
26
- EditorToolbar,
27
27
  translations,
28
- useActionHandler,
29
28
  useComments,
30
29
  useFormattingState,
31
30
  useTextEditor,
32
31
  useEditorToolbarState,
32
+ type EditorViewMode,
33
33
  } from '@dxos/react-ui-editor';
34
- import { TextType } from '@dxos/schema';
34
+ import { DataType } from '@dxos/schema';
35
35
  import { withLayout, withTheme } from '@dxos/storybook-utils';
36
36
 
37
37
  faker.seed(101);
38
38
 
39
- const _onUpload = async (file: File) => ({ url: file.name });
40
-
41
39
  const DefaultStory: FC<{ content?: string }> = ({ content = '' }) => {
42
40
  const { themeMode } = useThemeContext();
43
- const [text] = useState(createObject(create(TextType, { content })));
41
+ const [text] = useState(createObject(live(DataType.Text, { content })));
44
42
  const toolbarState = useEditorToolbarState({ viewMode: 'preview' });
45
43
  const formattingObserver = useFormattingState(toolbarState);
46
44
  const { parentRef, view } = useTextEditor(() => {
@@ -51,7 +49,7 @@ const DefaultStory: FC<{ content?: string }> = ({ content = '' }) => {
51
49
  formattingObserver,
52
50
  createBasicExtensions({ readOnly: toolbarState.viewMode === 'readonly' }),
53
51
  createMarkdownExtensions({ themeMode }),
54
- createThemeExtensions({ themeMode, syntaxHighlighting: true, slots: { editor: { className: editorContent } } }),
52
+ createThemeExtensions({ themeMode, syntaxHighlighting: true, slots: editorSlots }),
55
53
  createDataExtensions({ id: text.id, text: createDocAccessor(text, ['content']) }),
56
54
  comments({
57
55
  onCreate: ({ cursor }) => {
@@ -66,22 +64,22 @@ const DefaultStory: FC<{ content?: string }> = ({ content = '' }) => {
66
64
  };
67
65
  }, [text, formattingObserver, toolbarState.viewMode, themeMode]);
68
66
 
69
- const handleToolbarAction = useActionHandler(view);
70
- const handleAction = (action: EditorAction) => {
71
- if (action.type === 'view-mode') {
72
- toolbarState.viewMode = action.properties.data;
73
- } else {
74
- handleToolbarAction?.(action);
75
- }
67
+ const handleViewModeChange = (viewMode: EditorViewMode) => {
68
+ toolbarState.viewMode = viewMode;
76
69
  };
77
70
 
71
+ const getView = useCallback(() => {
72
+ invariant(view);
73
+ return view;
74
+ }, [view]);
75
+
78
76
  const [_comments, setComments] = useState<Comment[]>([]);
79
77
  useComments(view, text.id, _comments);
80
78
 
81
79
  return (
82
- <div role='none' className='fixed inset-0 flex flex-col'>
83
- <EditorToolbar onAction={handleAction} state={toolbarState ?? {}} />
84
- <div ref={parentRef} />
80
+ <div role='none' className='flex flex-col'>
81
+ <EditorToolbar state={toolbarState ?? {}} getView={getView} viewMode={handleViewModeChange} />
82
+ <div className='flex grow overflow-hidden' ref={parentRef} />
85
83
  </div>
86
84
  );
87
85
  };
@@ -96,18 +94,20 @@ const content = [
96
94
  '',
97
95
  ].join('\n');
98
96
 
99
- export const Default = {
100
- args: {
101
- content,
102
- },
103
- };
104
-
105
97
  const meta: Meta<typeof EditorToolbar> = {
106
98
  title: 'plugins/plugin-markdown/Toolbar',
107
99
  component: EditorToolbar,
108
100
  render: DefaultStory as any,
109
- decorators: [withTheme, withLayout({ tooltips: true })],
110
- parameters: { translations, layout: 'fullscreen' },
101
+ decorators: [withTheme, withLayout({ fullscreen: true })],
102
+ parameters: {
103
+ translations,
104
+ },
111
105
  };
112
106
 
113
107
  export default meta;
108
+
109
+ export const Default = {
110
+ args: {
111
+ content,
112
+ },
113
+ };
@@ -7,3 +7,4 @@ import { lazy } from 'react';
7
7
  export * from './MarkdownSettings';
8
8
 
9
9
  export const MarkdownContainer = lazy(() => import('./MarkdownContainer'));
10
+ export const MarkdownPreview = lazy(() => import('./MarkdownPreview'));
@@ -13,9 +13,10 @@ import {
13
13
  useIntentDispatcher,
14
14
  } from '@dxos/app-framework';
15
15
  import { invariant } from '@dxos/invariant';
16
- import { createDocAccessor, fullyQualifiedId, getSpace, type Query } from '@dxos/react-client/echo';
16
+ import { createDocAccessor, fullyQualifiedId, getSpace, type QueryResult } from '@dxos/react-client/echo';
17
17
  import { useIdentity } from '@dxos/react-client/halo';
18
18
  import { Icon, ThemeProvider } from '@dxos/react-ui';
19
+ import { type SelectionManager } from '@dxos/react-ui-attention';
19
20
  import {
20
21
  type AutocompleteResult,
21
22
  type EditorStateStore,
@@ -29,11 +30,16 @@ import {
29
30
  formattingKeymap,
30
31
  linkTooltip,
31
32
  listener,
33
+ preview,
32
34
  selectionState,
33
35
  typewriter,
36
+ type RenderCallback,
37
+ EditorView,
38
+ documentId,
39
+ Cursor,
34
40
  } from '@dxos/react-ui-editor';
35
41
  import { defaultTx } from '@dxos/react-ui-theme';
36
- import { type TextType } from '@dxos/schema';
42
+ import { type DataType } from '@dxos/schema';
37
43
  import { isNotFalsy } from '@dxos/util';
38
44
 
39
45
  import { MarkdownCapabilities } from './capabilities';
@@ -43,10 +49,11 @@ import { setFallbackName } from './util';
43
49
  type ExtensionsOptions = {
44
50
  document?: DocumentType;
45
51
  id?: string;
46
- text?: TextType;
52
+ text?: DataType.Text;
47
53
  dispatch?: PromiseIntentDispatcher;
48
- query?: Query<DocumentType>;
54
+ query?: QueryResult<DocumentType>;
49
55
  settings: MarkdownSettingsProps;
56
+ selectionManager?: SelectionManager;
50
57
  viewMode?: EditorViewMode;
51
58
  editorStateStore?: EditorStateStore;
52
59
  };
@@ -57,6 +64,7 @@ export const useExtensions = ({
57
64
  id,
58
65
  text,
59
66
  settings,
67
+ selectionManager,
60
68
  viewMode,
61
69
  editorStateStore,
62
70
  }: ExtensionsOptions): Extension[] => {
@@ -66,7 +74,7 @@ export const useExtensions = ({
66
74
 
67
75
  // TODO(wittjosiah): Autocomplete is not working and this query is causing performance issues.
68
76
  // TODO(burdon): Unsubscribe.
69
- // const query = space?.db.query(Filter.schema(DocumentType));
77
+ // const query = space?.db.query(Filter.type(DocumentType));
70
78
  // query?.subscribe();
71
79
  const baseExtensions = useMemo(
72
80
  () =>
@@ -75,6 +83,7 @@ export const useExtensions = ({
75
83
  id,
76
84
  text,
77
85
  settings,
86
+ selectionManager,
78
87
  viewMode,
79
88
  dispatch,
80
89
  // query,
@@ -91,6 +100,7 @@ export const useExtensions = ({
91
100
  settings.numberedHeadings,
92
101
  settings.debug,
93
102
  settings.typewriter,
103
+ selectionManager,
94
104
  ],
95
105
  );
96
106
 
@@ -99,18 +109,20 @@ export const useExtensions = ({
99
109
  //
100
110
  // External extensions from other plugins.
101
111
  //
102
- const pluginExtensions = useMemo<Extension[] | undefined>(
103
- () =>
104
- extensionProviders.flat().reduce((acc: Extension[], provider) => {
105
- const extension = typeof provider === 'function' ? provider({ document }) : provider;
106
- if (extension) {
107
- acc.push(extension);
108
- }
112
+ const pluginExtensions = useMemo<Extension[]>(() => {
113
+ if (!document) {
114
+ return [];
115
+ }
109
116
 
110
- return acc;
111
- }, []),
112
- [extensionProviders, document],
113
- );
117
+ return extensionProviders.flat().reduce((acc: Extension[], provider) => {
118
+ const extension = typeof provider === 'function' ? provider({ document }) : provider;
119
+ if (extension) {
120
+ acc.push(extension);
121
+ }
122
+
123
+ return acc;
124
+ }, []);
125
+ }, [extensionProviders, document]);
114
126
 
115
127
  //
116
128
  // Basic plugins.
@@ -154,10 +166,12 @@ const createBaseExtensions = ({
154
166
  id,
155
167
  dispatch,
156
168
  settings,
169
+ selectionManager,
157
170
  query,
158
171
  viewMode,
159
172
  }: ExtensionsOptions): Extension[] => {
160
173
  const extensions: Extension[] = [
174
+ selectionManager && selectionChange(selectionManager),
161
175
  settings.editorInputMode && InputModeExtensions[settings.editorInputMode],
162
176
  settings.folding && folding(),
163
177
  ].filter(isNotFalsy);
@@ -175,7 +189,7 @@ const createBaseExtensions = ({
175
189
  // TODO(wittjosiah): For internal links, consider ignoring the link text and rendering the label of the object being linked to.
176
190
  renderLinkButton:
177
191
  dispatch && (document || id)
178
- ? onRenderLink((id: string) => {
192
+ ? createLinkRenderer((id: string) => {
179
193
  void dispatch(
180
194
  createIntent(LayoutAction.Open, {
181
195
  part: 'main',
@@ -189,6 +203,7 @@ const createBaseExtensions = ({
189
203
  : undefined,
190
204
  }),
191
205
  linkTooltip(renderLinkTooltip),
206
+ preview(),
192
207
  ],
193
208
  );
194
209
  }
@@ -227,46 +242,65 @@ const createBaseExtensions = ({
227
242
  return extensions;
228
243
  };
229
244
 
245
+ export const selectionChange = (selectionManager: SelectionManager) => {
246
+ return EditorView.updateListener.of((update) => {
247
+ if (update.selectionSet) {
248
+ const id = update.state.facet(documentId);
249
+ const cursorConverter = update.state.facet(Cursor.converter);
250
+ const selection = update.state.selection;
251
+ const ranges = selection.ranges
252
+ .map((range) => ({
253
+ from: cursorConverter.toCursor(range.from),
254
+ to: cursorConverter.toCursor(range.to),
255
+ }))
256
+ .filter(({ from, to }) => to > from);
257
+ selectionManager.updateMultiRange(id, ranges);
258
+ }
259
+ });
260
+ };
261
+
230
262
  // TODO(burdon): Factor out styles.
231
263
  const style = {
232
264
  hover: 'rounded-sm text-primary-500 hover:text-primary-600 dark:text-primary-500 hover:dark:text-primary-400',
233
265
  icon: 'inline-block leading-none mis-1 cursor-pointer',
234
266
  };
235
267
 
236
- const onRenderLink = (onSelectObject: (id: string) => void) => (el: Element, url: string) => {
237
- // TODO(burdon): Formalize/document internal link format.
238
- const isInternal =
239
- url.startsWith('/') ||
240
- // TODO(wittjosiah): This should probably be parsed out on paste?
241
- url.startsWith(window.location.origin);
268
+ const createLinkRenderer =
269
+ (onSelectObject: (id: string) => void): RenderCallback<{ url: string }> =>
270
+ (el, { url }) => {
271
+ // TODO(burdon): Formalize/document internal link format.
272
+ const isInternal =
273
+ url.startsWith('/') ||
274
+ // TODO(wittjosiah): This should probably be parsed out on paste?
275
+ url.startsWith(window.location.origin);
242
276
 
243
- const options: AnchorHTMLAttributes<any> = isInternal
244
- ? {
245
- onClick: () => {
246
- const qualifiedId = url.split('/').at(-1);
247
- invariant(qualifiedId, 'Invalid link format.');
248
- onSelectObject(qualifiedId);
249
- },
250
- }
251
- : {
252
- href: url,
253
- rel: 'noreferrer',
254
- target: '_blank',
255
- };
277
+ const options: AnchorHTMLAttributes<any> = isInternal
278
+ ? {
279
+ onClick: () => {
280
+ const qualifiedId = url.split('/').at(-1);
281
+ invariant(qualifiedId, 'Invalid link format.');
282
+ onSelectObject(qualifiedId);
283
+ },
284
+ }
285
+ : {
286
+ href: url,
287
+ rel: 'noreferrer',
288
+ target: '_blank',
289
+ };
256
290
 
257
- renderRoot(
258
- el,
259
- <a {...options} className={style.hover}>
260
- <Icon
261
- icon={isInternal ? 'ph--arrow-square-down--bold' : 'ph--arrow-square-out--bold'}
262
- size={4}
263
- classNames={style.icon}
264
- />
265
- </a>,
266
- );
267
- };
291
+ renderRoot(
292
+ el,
293
+ <a {...options} className={style.hover}>
294
+ <Icon
295
+ icon={isInternal ? 'ph--arrow-square-down--bold' : 'ph--arrow-square-out--bold'}
296
+ size={4}
297
+ classNames={style.icon}
298
+ />
299
+ </a>,
300
+ );
301
+ };
268
302
 
269
- const renderLinkTooltip = (el: Element, url: string) => {
303
+ const renderLinkTooltip: RenderCallback<{ url: string }> = (el, { url }) => {
270
304
  const web = new URL(url);
271
305
  renderRoot(
272
306
  el,
@@ -3,10 +3,10 @@
3
3
  //
4
4
 
5
5
  import { EditorView } from '@codemirror/view';
6
+ import { Schema } from 'effect';
6
7
  import { useMemo } from 'react';
7
8
 
8
9
  import { createResolver, LayoutAction, useIntentResolver } from '@dxos/app-framework';
9
- import { S } from '@dxos/echo-schema';
10
10
  import { invariant } from '@dxos/invariant';
11
11
  import { Cursor, setSelection } from '@dxos/react-ui-editor';
12
12
 
@@ -22,7 +22,7 @@ export const useSelectCurrentThread = (editorView: EditorView | undefined, docum
22
22
  intent: LayoutAction.UpdateLayout,
23
23
  position: 'hoist',
24
24
  filter: (data): data is { part: 'current'; subject: string; options: { cursor: string } } => {
25
- if (!S.is(LayoutAction.ScrollIntoView.fields.input)(data)) {
25
+ if (!Schema.is(LayoutAction.ScrollIntoView.fields.input)(data)) {
26
26
  return false;
27
27
  }
28
28
 
@@ -2,15 +2,13 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { getSchemaTypename } from '@dxos/echo-schema';
6
-
7
5
  import { MARKDOWN_PLUGIN } from './meta';
8
6
  import { DocumentType } from './types';
9
7
 
10
8
  export default [
11
9
  {
12
10
  'en-US': {
13
- [getSchemaTypename(DocumentType)!]: {
11
+ [DocumentType.typename]: {
14
12
  'typename label': 'Document',
15
13
  'object name placeholder': 'New document',
16
14
  },
@@ -35,6 +33,8 @@ export default [
35
33
  'toggle view mode label': 'Toggle read-only',
36
34
  'default view mode label': 'Default view mode',
37
35
  'upload image label': 'Upload image',
36
+ 'fallback title': 'Untitled',
37
+ 'navigate to document label': 'Open document',
38
38
  },
39
39
  },
40
40
  },
@@ -2,23 +2,30 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { EchoObject, Expando, LabelAnnotationId, Ref, S } from '@dxos/echo-schema';
6
- import { ThreadType } from '@dxos/plugin-space/types';
7
- import { TextType } from '@dxos/schema';
5
+ import { Schema } from 'effect';
8
6
 
9
- export const DocumentSchema = S.Struct({
10
- name: S.optional(S.String),
11
- fallbackName: S.optional(S.String),
12
- content: Ref(TextType),
13
- threads: S.mutable(S.Array(Ref(ThreadType))),
14
- assistantChatQueue: S.optional(Ref(Expando)),
15
- }).annotations({
16
- // TODO(dmaretskyi): `S.Struct(...).pipe(defaultLabel(['name', 'fallbackName']))` for type-safe annotations.
17
- [LabelAnnotationId]: ['name', 'fallbackName'],
18
- });
7
+ import { Type, Ref } from '@dxos/echo';
8
+ import { LabelAnnotation } from '@dxos/echo-schema';
9
+ import { live } from '@dxos/live-object';
10
+ import { DataType } from '@dxos/schema';
19
11
 
20
- export const DocumentType = DocumentSchema.pipe(EchoObject({ typename: 'dxos.org/type/Document', version: '0.1.0' }));
21
- export type DocumentType = S.Schema.Type<typeof DocumentType>;
12
+ export const DocumentSchema = Schema.Struct({
13
+ name: Schema.optional(Schema.String),
14
+ fallbackName: Schema.optional(Schema.String),
15
+ content: Type.Ref(DataType.Text),
16
+ }).pipe(LabelAnnotation.set(['name', 'fallbackName']));
17
+
18
+ export const DocumentType = DocumentSchema.pipe(
19
+ Type.Obj({
20
+ typename: 'dxos.org/type/Document',
21
+ version: '0.1.0',
22
+ }),
23
+ );
24
+ export type DocumentType = Schema.Schema.Type<typeof DocumentType>;
25
+
26
+ // TODO(burdon): Replace when defaults are supported.
27
+ export const createDocument = ({ name, content }: { name: string; content: string }) =>
28
+ live(DocumentType, { name, content: Ref.make(live(DataType.Text, { content })) });
22
29
 
23
30
  /**
24
31
  * Checks if an object conforms to the interface needed to render an editor.
@@ -2,7 +2,9 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { S } from '@dxos/echo-schema';
5
+ import { Schema } from 'effect';
6
+
7
+ import { Type } from '@dxos/echo';
6
8
  // TODO(wittjosiah): This pulls in UI code into the types entrypoint.
7
9
  import { type Extension, EditorInputMode, EditorViewMode } from '@dxos/react-ui-editor';
8
10
 
@@ -12,23 +14,23 @@ import { MARKDOWN_PLUGIN } from '../meta';
12
14
  const MARKDOWN_ACTION = `${MARKDOWN_PLUGIN}/action`;
13
15
 
14
16
  export namespace MarkdownAction {
15
- export class Create extends S.TaggedClass<Create>()(MARKDOWN_ACTION, {
16
- input: S.Struct({
17
- spaceId: S.String,
18
- name: S.optional(S.String),
19
- content: S.optional(S.String),
17
+ export class Create extends Schema.TaggedClass<Create>()(MARKDOWN_ACTION, {
18
+ input: Schema.Struct({
19
+ spaceId: Type.SpaceId,
20
+ name: Schema.optional(Schema.String),
21
+ content: Schema.optional(Schema.String),
20
22
  }),
21
- output: S.Struct({
23
+ output: Schema.Struct({
22
24
  object: DocumentType,
23
25
  }),
24
26
  }) {}
25
27
 
26
- export class SetViewMode extends S.TaggedClass<SetViewMode>()(`${MARKDOWN_ACTION}/set-view-mode`, {
27
- input: S.Struct({
28
- id: S.String,
28
+ export class SetViewMode extends Schema.TaggedClass<SetViewMode>()(`${MARKDOWN_ACTION}/set-view-mode`, {
29
+ input: Schema.Struct({
30
+ id: Schema.String,
29
31
  viewMode: EditorViewMode,
30
32
  }),
31
- output: S.Void,
33
+ output: Schema.Void,
32
34
  }) {}
33
35
  }
34
36
 
@@ -48,18 +50,18 @@ export type MarkdownPluginState = {
48
50
  viewMode: Record<string, EditorViewMode>;
49
51
  };
50
52
 
51
- export const MarkdownSettingsSchema = S.mutable(
52
- S.Struct({
53
+ export const MarkdownSettingsSchema = Schema.mutable(
54
+ Schema.Struct({
53
55
  defaultViewMode: EditorViewMode,
54
- editorInputMode: S.optional(EditorInputMode),
55
- experimental: S.optional(S.Boolean),
56
- debug: S.optional(S.Boolean),
57
- toolbar: S.optional(S.Boolean),
58
- typewriter: S.optional(S.String),
56
+ editorInputMode: Schema.optional(EditorInputMode),
57
+ experimental: Schema.optional(Schema.Boolean),
58
+ debug: Schema.optional(Schema.Boolean),
59
+ toolbar: Schema.optional(Schema.Boolean),
60
+ typewriter: Schema.optional(Schema.String),
59
61
  // TODO(burdon): Per document settings.
60
- numberedHeadings: S.optional(S.Boolean),
61
- folding: S.optional(S.Boolean),
62
+ numberedHeadings: Schema.optional(Schema.Boolean),
63
+ folding: Schema.optional(Schema.Boolean),
62
64
  }),
63
65
  );
64
66
 
65
- export type MarkdownSettingsProps = S.Schema.Type<typeof MarkdownSettingsSchema>;
67
+ export type MarkdownSettingsProps = Schema.Schema.Type<typeof MarkdownSettingsSchema>;
package/src/util.tsx CHANGED
@@ -4,13 +4,13 @@
4
4
 
5
5
  import { debounce } from '@dxos/async';
6
6
  import { type TypedObjectSerializer } from '@dxos/plugin-space/types';
7
- import { create, createObject, isEchoObject, loadObjectReferences, makeRef } from '@dxos/react-client/echo';
8
- import { TextType } from '@dxos/schema';
7
+ import { live, createObject, isEchoObject, loadObjectReferences, Ref } from '@dxos/react-client/echo';
8
+ import { DataType } from '@dxos/schema';
9
9
 
10
10
  import { DocumentType, type MarkdownProperties } from './types';
11
11
 
12
12
  export const isMarkdownProperties = (data: unknown): data is MarkdownProperties =>
13
- isEchoObject(data)
13
+ (isEchoObject(data) as boolean)
14
14
  ? true
15
15
  : data && typeof data === 'object'
16
16
  ? 'title' in data && typeof data.title === 'string'
@@ -22,6 +22,10 @@ export const getFallbackName = (content: string) => {
22
22
  return content.substring(0, 31).split('\n')[0].replaceAll(nonTitleChars, '').trim();
23
23
  };
24
24
 
25
+ export const getAbstract = (content: string) => {
26
+ return content.substring(0, 128).split('\n')[0].replaceAll(nonTitleChars, '').trim();
27
+ };
28
+
25
29
  export const setFallbackName = debounce((doc: DocumentType, content: string) => {
26
30
  const name = getFallbackName(content);
27
31
  if (doc.fallbackName !== name) {
@@ -38,7 +42,7 @@ export const serializer: TypedObjectSerializer<DocumentType> = {
38
42
  deserialize: async ({ content: serialized }) => {
39
43
  const { name, fallbackName, content } = JSON.parse(serialized);
40
44
  return createObject(
41
- create(DocumentType, { name, fallbackName, content: makeRef(create(TextType, { content })), threads: [] }),
45
+ live(DocumentType, { name, fallbackName, content: Ref.make(live(DataType.Text, { content })) }),
42
46
  );
43
47
  },
44
48
  };