@dxos/react-ui-editor 0.3.10 → 0.3.11-main.00a28cb

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 (222) hide show
  1. package/dist/lib/browser/index.mjs +1724 -1105
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +24 -13
  5. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.d.ts +15 -19
  7. package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
  8. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +6 -3
  9. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  10. package/dist/types/src/{hooks/automerge → components/TextEditor}/automerge.stories.d.ts +6 -2
  11. package/dist/types/src/components/TextEditor/automerge.stories.d.ts.map +1 -0
  12. package/dist/types/src/components/TextEditor/codemirror.stories.d.ts.map +1 -1
  13. package/dist/types/src/components/TextEditor/comments.stories.d.ts +26 -0
  14. package/dist/types/src/components/TextEditor/comments.stories.d.ts.map +1 -0
  15. package/dist/types/src/components/TextEditor/index.d.ts +0 -2
  16. package/dist/types/src/components/TextEditor/index.d.ts.map +1 -1
  17. package/dist/types/src/{hooks/yjs → components/TextEditor}/yjs.stories.d.ts +1 -1
  18. package/dist/types/src/components/TextEditor/yjs.stories.d.ts.map +1 -0
  19. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -0
  20. package/dist/types/src/extensions/automerge/automerge.d.ts +9 -0
  21. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -0
  22. package/dist/types/src/extensions/automerge/cursor.d.ts +5 -0
  23. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -0
  24. package/dist/types/src/extensions/automerge/defs.d.ts +26 -0
  25. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -0
  26. package/dist/types/src/extensions/automerge/index.d.ts +3 -0
  27. package/dist/types/src/extensions/automerge/index.d.ts.map +1 -0
  28. package/dist/types/src/extensions/automerge/semaphore.d.ts +14 -0
  29. package/dist/types/src/extensions/automerge/semaphore.d.ts.map +1 -0
  30. package/dist/types/src/extensions/automerge/update-automerge.d.ts +5 -0
  31. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -0
  32. package/dist/types/src/extensions/automerge/update-codemirror.d.ts +5 -0
  33. package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -0
  34. package/dist/types/src/extensions/awareness.d.ts +46 -0
  35. package/dist/types/src/extensions/awareness.d.ts.map +1 -0
  36. package/dist/types/src/extensions/basic.d.ts.map +1 -0
  37. package/dist/types/src/extensions/blast.d.ts.map +1 -0
  38. package/dist/types/src/extensions/code.d.ts.map +1 -0
  39. package/dist/types/src/extensions/comments.d.ts +59 -0
  40. package/dist/types/src/extensions/comments.d.ts.map +1 -0
  41. package/dist/types/src/extensions/cursor.d.ts +25 -0
  42. package/dist/types/src/extensions/cursor.d.ts.map +1 -0
  43. package/dist/types/src/extensions/hr.d.ts +2 -0
  44. package/dist/types/src/extensions/hr.d.ts.map +1 -0
  45. package/dist/types/src/extensions/image.d.ts.map +1 -0
  46. package/dist/types/src/{components/TextEditor/extensions → extensions}/index.d.ts +7 -3
  47. package/dist/types/src/extensions/index.d.ts.map +1 -0
  48. package/dist/types/src/{components/TextEditor/extensions → extensions}/link.d.ts +1 -0
  49. package/dist/types/src/extensions/link.d.ts.map +1 -0
  50. package/dist/types/src/extensions/listener.d.ts +10 -0
  51. package/dist/types/src/extensions/listener.d.ts.map +1 -0
  52. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -0
  53. package/dist/types/src/{components/TextEditor/extensions → extensions}/markdown/highlight.d.ts +0 -1
  54. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -0
  55. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -0
  56. package/dist/types/src/extensions/mention.d.ts.map +1 -0
  57. package/dist/types/src/extensions/outliner.d.ts +4 -0
  58. package/dist/types/src/extensions/outliner.d.ts.map +1 -0
  59. package/dist/types/src/extensions/table.d.ts.map +1 -0
  60. package/dist/types/src/extensions/tasklist.d.ts +7 -0
  61. package/dist/types/src/extensions/tasklist.d.ts.map +1 -0
  62. package/dist/types/src/{components/TextEditor/extensions/demo.d.ts → extensions/typewriter.d.ts} +2 -3
  63. package/dist/types/src/extensions/typewriter.d.ts.map +1 -0
  64. package/dist/types/src/extensions/yjs/cursor.d.ts +4 -0
  65. package/dist/types/src/extensions/yjs/cursor.d.ts.map +1 -0
  66. package/dist/types/src/extensions/yjs/index.d.ts +2 -0
  67. package/dist/types/src/extensions/yjs/index.d.ts.map +1 -0
  68. package/dist/types/src/extensions/yjs/yjs.d.ts +4 -0
  69. package/dist/types/src/extensions/yjs/yjs.d.ts.map +1 -0
  70. package/dist/types/src/extensions/yjs/yjs.test.d.ts +2 -0
  71. package/dist/types/src/extensions/yjs/yjs.test.d.ts.map +1 -0
  72. package/dist/types/src/hooks/automerge.d.ts +3 -0
  73. package/dist/types/src/hooks/automerge.d.ts.map +1 -0
  74. package/dist/types/src/hooks/awareness-provider.d.ts +28 -0
  75. package/dist/types/src/hooks/awareness-provider.d.ts.map +1 -0
  76. package/dist/types/src/hooks/index.d.ts +3 -1
  77. package/dist/types/src/hooks/index.d.ts.map +1 -1
  78. package/dist/types/src/hooks/useTextModel.d.ts +15 -11
  79. package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
  80. package/dist/types/src/hooks/{yjs/space-provider.d.ts → yjs.d.ts} +8 -8
  81. package/dist/types/src/hooks/yjs.d.ts.map +1 -0
  82. package/dist/types/src/index.d.ts +6 -0
  83. package/dist/types/src/index.d.ts.map +1 -1
  84. package/dist/types/src/styles/cursors.d.ts.map +1 -0
  85. package/dist/types/src/styles/index.d.ts +1 -0
  86. package/dist/types/src/styles/index.d.ts.map +1 -1
  87. package/dist/types/src/styles/markdown.d.ts.map +1 -1
  88. package/dist/types/src/styles/tokens.d.ts +1 -0
  89. package/dist/types/src/styles/tokens.d.ts.map +1 -1
  90. package/dist/types/src/testing/replicator.d.ts +2 -2
  91. package/dist/types/src/testing/replicator.d.ts.map +1 -1
  92. package/dist/types/src/{components/TextEditor/themes → themes}/default.d.ts +5 -13
  93. package/dist/types/src/themes/default.d.ts.map +1 -0
  94. package/dist/types/src/themes/index.d.ts.map +1 -0
  95. package/dist/types/src/util.d.ts +5 -0
  96. package/dist/types/src/util.d.ts.map +1 -0
  97. package/package.json +28 -22
  98. package/src/components/TextEditor/MarkdownEditor.stories.tsx +150 -87
  99. package/src/components/TextEditor/TextEditor.stories.tsx +14 -35
  100. package/src/components/TextEditor/TextEditor.tsx +87 -79
  101. package/src/{hooks/automerge → components/TextEditor}/automerge.stories.tsx +67 -8
  102. package/src/components/TextEditor/codemirror.stories.ts +3 -2
  103. package/src/components/TextEditor/comments.stories.tsx +355 -0
  104. package/src/components/TextEditor/index.ts +0 -3
  105. package/src/{hooks/yjs → components/TextEditor}/yjs.stories.tsx +1 -1
  106. package/src/{components/TextEditor/extensions → extensions}/autocomplete.ts +18 -17
  107. package/src/extensions/automerge/automerge.ts +92 -0
  108. package/src/extensions/automerge/cursor.ts +52 -0
  109. package/src/extensions/automerge/defs.ts +66 -0
  110. package/src/extensions/automerge/index.ts +6 -0
  111. package/src/{hooks/automerge/PatchSemaphore.ts → extensions/automerge/semaphore.ts} +26 -25
  112. package/src/{hooks/automerge/translation/codemirror-to-automerge.ts → extensions/automerge/update-automerge.ts} +6 -7
  113. package/src/{hooks/automerge/translation/automerge-to-codemirror.ts → extensions/automerge/update-codemirror.ts} +14 -11
  114. package/src/extensions/awareness.ts +310 -0
  115. package/src/extensions/code.ts +104 -0
  116. package/src/extensions/comments.ts +408 -0
  117. package/src/extensions/cursor.ts +46 -0
  118. package/src/extensions/hr.ts +72 -0
  119. package/src/extensions/image.ts +87 -0
  120. package/src/{components/TextEditor/extensions → extensions}/index.ts +7 -3
  121. package/src/{components/TextEditor/extensions → extensions}/link.ts +116 -62
  122. package/src/extensions/listener.ts +35 -0
  123. package/src/{components/TextEditor/extensions → extensions}/markdown/highlight.ts +4 -16
  124. package/src/extensions/outliner.ts +12 -0
  125. package/src/{components/TextEditor/extensions → extensions}/table.ts +23 -4
  126. package/src/extensions/tasklist.ts +96 -0
  127. package/src/{components/TextEditor/extensions/demo.ts → extensions/typewriter.ts} +2 -3
  128. package/src/extensions/yjs/cursor.ts +22 -0
  129. package/src/extensions/yjs/index.ts +5 -0
  130. package/src/extensions/yjs/yjs.test.ts +35 -0
  131. package/src/extensions/yjs/yjs.ts +16 -0
  132. package/src/hooks/automerge.ts +52 -0
  133. package/src/hooks/awareness-provider.ts +120 -0
  134. package/src/hooks/index.ts +4 -1
  135. package/src/hooks/useTextModel.ts +40 -79
  136. package/src/hooks/{yjs/space-provider.ts → yjs.ts} +49 -19
  137. package/src/index.ts +6 -0
  138. package/src/styles/index.ts +1 -0
  139. package/src/styles/markdown.ts +0 -2
  140. package/src/styles/tokens.ts +3 -0
  141. package/src/testing/replicator.ts +10 -16
  142. package/src/themes/default.ts +275 -0
  143. package/src/util.ts +18 -0
  144. package/dist/types/src/components/TextEditor/extensions/autocomplete.d.ts.map +0 -1
  145. package/dist/types/src/components/TextEditor/extensions/basic.d.ts.map +0 -1
  146. package/dist/types/src/components/TextEditor/extensions/blast.d.ts.map +0 -1
  147. package/dist/types/src/components/TextEditor/extensions/code.d.ts.map +0 -1
  148. package/dist/types/src/components/TextEditor/extensions/comments.d.ts +0 -18
  149. package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +0 -1
  150. package/dist/types/src/components/TextEditor/extensions/demo.d.ts.map +0 -1
  151. package/dist/types/src/components/TextEditor/extensions/experimental.d.ts +0 -10
  152. package/dist/types/src/components/TextEditor/extensions/experimental.d.ts.map +0 -1
  153. package/dist/types/src/components/TextEditor/extensions/highlight.d.ts +0 -24
  154. package/dist/types/src/components/TextEditor/extensions/highlight.d.ts.map +0 -1
  155. package/dist/types/src/components/TextEditor/extensions/image.d.ts.map +0 -1
  156. package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +0 -1
  157. package/dist/types/src/components/TextEditor/extensions/link.d.ts.map +0 -1
  158. package/dist/types/src/components/TextEditor/extensions/listener.d.ts +0 -9
  159. package/dist/types/src/components/TextEditor/extensions/listener.d.ts.map +0 -1
  160. package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts.map +0 -1
  161. package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts.map +0 -1
  162. package/dist/types/src/components/TextEditor/extensions/markdown/index.d.ts.map +0 -1
  163. package/dist/types/src/components/TextEditor/extensions/mention.d.ts.map +0 -1
  164. package/dist/types/src/components/TextEditor/extensions/table.d.ts.map +0 -1
  165. package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts +0 -3
  166. package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts.map +0 -1
  167. package/dist/types/src/components/TextEditor/extensions/tooltip.d.ts +0 -12
  168. package/dist/types/src/components/TextEditor/extensions/tooltip.d.ts.map +0 -1
  169. package/dist/types/src/components/TextEditor/themes/default.d.ts.map +0 -1
  170. package/dist/types/src/components/TextEditor/themes/index.d.ts.map +0 -1
  171. package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts +0 -19
  172. package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts.map +0 -1
  173. package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +0 -1
  174. package/dist/types/src/hooks/automerge/handle.d.ts +0 -9
  175. package/dist/types/src/hooks/automerge/handle.d.ts.map +0 -1
  176. package/dist/types/src/hooks/automerge/index.d.ts +0 -3
  177. package/dist/types/src/hooks/automerge/index.d.ts.map +0 -1
  178. package/dist/types/src/hooks/automerge/plugin.d.ts +0 -26
  179. package/dist/types/src/hooks/automerge/plugin.d.ts.map +0 -1
  180. package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts +0 -5
  181. package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts.map +0 -1
  182. package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts +0 -6
  183. package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts.map +0 -1
  184. package/dist/types/src/hooks/automerge/translation/index.d.ts +0 -3
  185. package/dist/types/src/hooks/automerge/translation/index.d.ts.map +0 -1
  186. package/dist/types/src/hooks/yjs/cursors.d.ts.map +0 -1
  187. package/dist/types/src/hooks/yjs/index.d.ts +0 -3
  188. package/dist/types/src/hooks/yjs/index.d.ts.map +0 -1
  189. package/dist/types/src/hooks/yjs/space-provider.d.ts.map +0 -1
  190. package/dist/types/src/hooks/yjs/yjs.stories.d.ts.map +0 -1
  191. package/src/components/TextEditor/extensions/code.ts +0 -99
  192. package/src/components/TextEditor/extensions/comments.ts +0 -173
  193. package/src/components/TextEditor/extensions/experimental.tsx +0 -114
  194. package/src/components/TextEditor/extensions/highlight.ts +0 -128
  195. package/src/components/TextEditor/extensions/image.ts +0 -67
  196. package/src/components/TextEditor/extensions/listener.ts +0 -23
  197. package/src/components/TextEditor/extensions/tasklist.ts +0 -121
  198. package/src/components/TextEditor/extensions/tooltip.tsx +0 -61
  199. package/src/components/TextEditor/themes/default.ts +0 -279
  200. package/src/hooks/automerge/handle.ts +0 -14
  201. package/src/hooks/automerge/index.ts +0 -6
  202. package/src/hooks/automerge/plugin.ts +0 -134
  203. package/src/hooks/automerge/translation/index.ts +0 -6
  204. package/src/hooks/yjs/index.ts +0 -6
  205. /package/dist/types/src/{components/TextEditor/extensions → extensions}/autocomplete.d.ts +0 -0
  206. /package/dist/types/src/{components/TextEditor/extensions → extensions}/basic.d.ts +0 -0
  207. /package/dist/types/src/{components/TextEditor/extensions → extensions}/blast.d.ts +0 -0
  208. /package/dist/types/src/{components/TextEditor/extensions → extensions}/code.d.ts +0 -0
  209. /package/dist/types/src/{components/TextEditor/extensions → extensions}/image.d.ts +0 -0
  210. /package/dist/types/src/{components/TextEditor/extensions → extensions}/markdown/bundle.d.ts +0 -0
  211. /package/dist/types/src/{components/TextEditor/extensions → extensions}/markdown/index.d.ts +0 -0
  212. /package/dist/types/src/{components/TextEditor/extensions → extensions}/mention.d.ts +0 -0
  213. /package/dist/types/src/{components/TextEditor/extensions → extensions}/table.d.ts +0 -0
  214. /package/dist/types/src/{hooks/yjs → styles}/cursors.d.ts +0 -0
  215. /package/dist/types/src/{components/TextEditor/themes → themes}/index.d.ts +0 -0
  216. /package/src/{components/TextEditor/extensions → extensions}/basic.ts +0 -0
  217. /package/src/{components/TextEditor/extensions → extensions}/blast.ts +0 -0
  218. /package/src/{components/TextEditor/extensions → extensions}/markdown/bundle.ts +0 -0
  219. /package/src/{components/TextEditor/extensions → extensions}/markdown/index.ts +0 -0
  220. /package/src/{components/TextEditor/extensions → extensions}/mention.ts +0 -0
  221. /package/src/{hooks/yjs → styles}/cursors.ts +0 -0
  222. /package/src/{components/TextEditor/themes → themes}/index.ts +0 -0
@@ -1,4 +1,4 @@
1
- import { type StyleSpec } from 'style-mod';
1
+ import { type ThemeStyles } from '../styles';
2
2
  /**
3
3
  * Minimal styles.
4
4
  * https://codemirror.net/examples/styling
@@ -10,16 +10,8 @@ import { type StyleSpec } from 'style-mod';
10
10
  * NOTE: Use one of '&', '&light', and '&dark' prefix to scope instance.
11
11
  * NOTE: `light` and `dark` selectors are preprocessed by CodeMirror and can only be in the base theme.
12
12
  */
13
- export declare const defaultTheme: {
14
- [selector: string]: StyleSpec;
15
- };
16
- export declare const textTheme: {
17
- [selector: string]: StyleSpec;
18
- };
19
- export declare const markdownTheme: {
20
- [selector: string]: StyleSpec;
21
- };
22
- export declare const codeTheme: {
23
- [selector: string]: StyleSpec;
24
- };
13
+ export declare const defaultTheme: ThemeStyles;
14
+ export declare const textTheme: ThemeStyles;
15
+ export declare const markdownTheme: ThemeStyles;
16
+ export declare const codeTheme: ThemeStyles;
25
17
  //# sourceMappingURL=default.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../../../src/themes/default.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,WAAW,EAAU,MAAM,WAAW,CAAC;AAKrD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE,WAiO1B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,WAOvB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,WAO3B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,WAOvB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/themes/index.ts"],"names":[],"mappings":"AAIA,cAAc,WAAW,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * CodeMirror callbacks swallow errors so wrap handlers.
3
+ */
4
+ export declare const callbackWrapper: <T extends Function>(fn: T) => T;
5
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/util.ts"],"names":[],"mappings":"AAMA;;GAEG;AAEH,eAAO,MAAM,eAAe,kCAOR,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-editor",
3
- "version": "0.3.10",
3
+ "version": "0.3.11-main.00a28cb",
4
4
  "description": "Document editing experience within a DXOS shell.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -15,7 +15,7 @@
15
15
  "dependencies": {
16
16
  "@codemirror/autocomplete": "^6.11.1",
17
17
  "@codemirror/commands": "^6.3.2",
18
- "@codemirror/lang-markdown": "^6.2.3",
18
+ "@codemirror/lang-markdown": "^6.2.4",
19
19
  "@codemirror/language": "^6.9.3",
20
20
  "@codemirror/language-data": "^6.3.1",
21
21
  "@codemirror/lint": "^6.4.2",
@@ -32,48 +32,54 @@
32
32
  "lib0": "^0.2.65",
33
33
  "lodash.defaultsdeep": "^4.6.1",
34
34
  "lodash.get": "^4.4.2",
35
+ "lodash.pick": "^4.4.0",
35
36
  "lodash.sortby": "^4.7.0",
36
37
  "style-mod": "^4.1.0",
37
38
  "y-codemirror.next": "^0.3.2",
38
39
  "y-protocols": "^1.0.5",
39
40
  "yjs": "^13.6.10",
40
- "@dxos/automerge": "0.3.10",
41
- "@dxos/async": "0.3.10",
42
- "@dxos/debug": "0.3.10",
43
- "@dxos/display-name": "0.3.10",
44
- "@dxos/invariant": "0.3.10",
45
- "@dxos/echo-schema": "0.3.10",
46
- "@dxos/protocols": "0.3.10",
47
- "@dxos/react-async": "0.3.10",
48
- "@dxos/log": "0.3.10",
49
- "@dxos/react-ui": "0.3.10",
50
- "@dxos/react-ui-theme": "0.3.10",
51
- "@dxos/text-model": "0.3.10",
52
- "@dxos/util": "0.3.10"
41
+ "@dxos/async": "0.3.11-main.00a28cb",
42
+ "@dxos/context": "0.3.11-main.00a28cb",
43
+ "@dxos/automerge": "0.3.11-main.00a28cb",
44
+ "@dxos/display-name": "0.3.11-main.00a28cb",
45
+ "@dxos/echo-schema": "0.3.11-main.00a28cb",
46
+ "@dxos/invariant": "0.3.11-main.00a28cb",
47
+ "@dxos/debug": "0.3.11-main.00a28cb",
48
+ "@dxos/log": "0.3.11-main.00a28cb",
49
+ "@dxos/protocols": "0.3.11-main.00a28cb",
50
+ "@dxos/react-async": "0.3.11-main.00a28cb",
51
+ "@dxos/react-ui": "0.3.11-main.00a28cb",
52
+ "@dxos/react-ui-theme": "0.3.11-main.00a28cb",
53
+ "@dxos/text-model": "0.3.11-main.00a28cb",
54
+ "@dxos/util": "0.3.11-main.00a28cb"
53
55
  },
54
56
  "devDependencies": {
55
57
  "@automerge/automerge-repo-network-broadcastchannel": "^1.0.19",
56
- "@faker-js/faker": "^8.0.2",
58
+ "@faker-js/faker": "^8.3.1",
57
59
  "@phosphor-icons/react": "^2.0.5",
58
60
  "@preact/signals-react": "^1.3.6",
59
61
  "@types/lodash.defaultsdeep": "^4.6.6",
60
62
  "@types/lodash.get": "^4.4.7",
63
+ "@types/lodash.pick": "^4.4.7",
61
64
  "@types/lodash.sortby": "^4.7.7",
62
65
  "@types/react": "^18.0.21",
63
66
  "@types/react-dom": "^18.0.6",
67
+ "deepsignal": "1.4.0-shallow.0",
64
68
  "react": "^18.2.0",
65
69
  "react-dom": "^18.2.0",
66
- "@dxos/config": "0.3.10",
67
- "@dxos/echo-typegen": "0.3.10",
68
- "@dxos/react-ui": "0.3.10",
69
- "@dxos/storybook-utils": "0.3.10",
70
- "@dxos/react-client": "0.3.10"
70
+ "@dxos/config": "0.3.11-main.00a28cb",
71
+ "@dxos/echo-signals": "0.3.11-main.00a28cb",
72
+ "@dxos/echo-typegen": "0.3.11-main.00a28cb",
73
+ "@dxos/keyboard": "0.3.11-main.00a28cb",
74
+ "@dxos/react-client": "0.3.11-main.00a28cb",
75
+ "@dxos/react-ui": "0.3.11-main.00a28cb",
76
+ "@dxos/storybook-utils": "0.3.11-main.00a28cb"
71
77
  },
72
78
  "peerDependencies": {
73
79
  "@phosphor-icons/react": "^2.0.5",
74
80
  "react": "^18.2.0",
75
81
  "react-dom": "^18.2.0",
76
- "@dxos/react-client": "0.3.10"
82
+ "@dxos/react-client": "0.3.11-main.00a28cb"
77
83
  },
78
84
  "publishConfig": {
79
85
  "access": "public"
@@ -8,39 +8,41 @@ import { EditorView } from '@codemirror/view';
8
8
  import { faker } from '@faker-js/faker';
9
9
  import { ArrowSquareOut } from '@phosphor-icons/react';
10
10
  import defaultsDeep from 'lodash.defaultsdeep';
11
- import React, { StrictMode, useRef, useState } from 'react';
11
+ import React, { type FC, StrictMode, useState } from 'react';
12
12
  import { createRoot } from 'react-dom/client';
13
13
 
14
14
  import { TextObject } from '@dxos/echo-schema';
15
+ import { keySymbols, parseShortcut } from '@dxos/keyboard';
15
16
  import { PublicKey } from '@dxos/keys';
16
17
  import { fixedInsetFlexLayout, getSize, groupSurface, mx } from '@dxos/react-ui-theme';
17
18
  import { withTheme } from '@dxos/storybook-utils';
18
19
 
19
- import { MarkdownEditor, type TextEditorProps, type TextEditorRef } from './TextEditor';
20
+ import { MarkdownEditor, type TextEditorProps } from './TextEditor';
20
21
  import {
21
22
  autocomplete,
22
- listener,
23
- link,
24
- tasklist,
25
- tooltip,
26
- type TooltipOptions,
27
- type LinkOptions,
23
+ blast,
24
+ code,
28
25
  comments,
29
- table,
26
+ defaultOptions,
27
+ hr,
30
28
  image,
29
+ link,
31
30
  mention,
32
- blast,
33
- demo,
34
- defaultOptions,
35
- highlight,
36
- code,
37
- } from './extensions';
38
- import { useTextModel } from '../../hooks';
31
+ table,
32
+ tasklist,
33
+ typewriter,
34
+ type CommentsOptions,
35
+ type LinkOptions,
36
+ outliner,
37
+ } from '../../extensions';
38
+ import { type CommentRange, useTextModel } from '../../hooks';
39
39
 
40
40
  // Extensions:
41
41
  // TODO(burdon): Table of contents.
42
42
  // TODO(burdon): Front-matter
43
43
 
44
+ faker.seed(101);
45
+
44
46
  const str = (...lines: string[]) => lines.join('\n');
45
47
 
46
48
  const num = () => faker.number.int({ min: 0, max: 9999 }).toLocaleString();
@@ -55,6 +57,7 @@ const text = {
55
57
  ' - [ ] state',
56
58
  ' - [ ] indent',
57
59
  ' - [x] style',
60
+ '',
58
61
  ),
59
62
 
60
63
  list: str(
@@ -63,6 +66,7 @@ const text = {
63
66
  '- new york',
64
67
  '- london',
65
68
  '- tokyo',
69
+ '',
66
70
  ),
67
71
 
68
72
  numbered: str(
@@ -87,8 +91,8 @@ const text = {
87
91
  '',
88
92
  ' return () => <div>Test</div>;',
89
93
  '};',
94
+ '```',
90
95
  '',
91
- '```'
92
96
  ),
93
97
 
94
98
  links: str(
@@ -103,11 +107,11 @@ const text = {
103
107
  table: str(
104
108
  '# Table',
105
109
  '',
106
- `| ${faker.lorem.word().padStart(8)} | ${faker.lorem.word().padStart(8)} | ${faker.lorem.word().padStart(8)} |`,
107
- '|----------|----------|----------|',
108
- `| ${num().padStart(8)} | ${num().padStart(8)} | ${num().padStart(8)} |`,
109
- `| ${num().padStart(8)} | ${num().padStart(8)} | ${num().padStart(8)} |`,
110
- `| ${num().padStart(8)} | ${num().padStart(8)} | ${num().padStart(8)} |`,
110
+ `| ${faker.lorem.word().padStart(12)} | ${faker.lorem.word().padStart(12)} | ${faker.lorem.word().padStart(12)} |`,
111
+ `|-${''.padStart(12, '-')}-|-${''.padStart(12, '-')}-|-${''.padStart(12, '-')}-|`,
112
+ `| ${num().padStart(12)} | ${num().padStart(12)} | ${num().padStart(12)} |`,
113
+ `| ${num().padStart(12)} | ${num().padStart(12)} | ${num().padStart(12)} |`,
114
+ `| ${num().padStart(12)} | ${num().padStart(12)} | ${num().padStart(12)} |`,
111
115
  '', // TODO(burdon): Possible GFM parsing bug if no newline?
112
116
  ),
113
117
 
@@ -147,7 +151,6 @@ const document = str(
147
151
  text.table,
148
152
  '---',
149
153
  text.image,
150
- '',
151
154
  text.footer,
152
155
  );
153
156
 
@@ -162,7 +165,7 @@ const links = [
162
165
  const hover =
163
166
  'rounded-sm text-base text-primary-600 hover:text-primary-500 dark:text-primary-300 hover:dark:text-primary-200';
164
167
 
165
- const onHover: TooltipOptions['onHover'] = (el, url) => {
168
+ const onHoverLinkTooltip: LinkOptions['onHover'] = (el, url) => {
166
169
  const web = new URL(url);
167
170
  createRoot(el).render(
168
171
  <StrictMode>
@@ -174,24 +177,44 @@ const onHover: TooltipOptions['onHover'] = (el, url) => {
174
177
  );
175
178
  };
176
179
 
177
- const onRender: LinkOptions['onRender'] = (el, url) => {
180
+ const Key: FC<{ char: string }> = ({ char }) => (
181
+ <span className='flex justify-center items-center w-[24px] h-[24px] rounded text-xs bg-neutral-200 text-black'>
182
+ {char}
183
+ </span>
184
+ );
185
+
186
+ const onCommentsHover: CommentsOptions['onHover'] = (el, shortcut) => {
187
+ createRoot(el).render(
188
+ <StrictMode>
189
+ <div className='flex items-center gap-2 px-2 py-2 bg-neutral-700 text-white text-xs rounded'>
190
+ <div>Create comment</div>
191
+ <div className='flex gap-1'>
192
+ {keySymbols(parseShortcut(shortcut)).map((char) => (
193
+ <Key key={char} char={char} />
194
+ ))}
195
+ </div>
196
+ </div>
197
+ </StrictMode>,
198
+ );
199
+ };
200
+
201
+ const onRenderLink: LinkOptions['onRender'] = (el, url) => {
178
202
  createRoot(el).render(
179
203
  <StrictMode>
180
204
  <a href={url} target='_blank' rel='noreferrer' className={hover}>
181
- <ArrowSquareOut weight='bold' className={mx(getSize(4), 'inline-block leading-none mis-1 mb-1')} />
205
+ <ArrowSquareOut weight='bold' className={mx(getSize(4), 'inline-block leading-none mis-1 mb-[2px]')} />
182
206
  </a>
183
207
  </StrictMode>,
184
208
  );
185
209
  };
186
210
 
187
- // TODO(burdon): Pass in model.
188
- const Story = ({
189
- text,
190
- automerge,
191
- ...props
192
- }: { text?: string; automerge?: boolean } & Pick<TextEditorProps, 'readonly' | 'extensions' | 'slots'>) => {
193
- const ref = useRef<TextEditorRef>(null);
194
- const [item] = useState({ text: new TextObject(text, undefined, undefined, { useAutomergeBackend: automerge }) });
211
+ type StoryProps = {
212
+ text?: string;
213
+ automerge?: boolean;
214
+ } & Pick<TextEditorProps, 'comments' | 'readonly' | 'extensions' | 'slots'>;
215
+
216
+ const Story = ({ text, automerge, ...props }: StoryProps) => {
217
+ const [item] = useState({ text: new TextObject(text, undefined, undefined, { automerge }) });
195
218
  const model = useTextModel({ text: item.text });
196
219
  if (!model) {
197
220
  return null;
@@ -199,10 +222,9 @@ const Story = ({
199
222
 
200
223
  return (
201
224
  <div className={mx(fixedInsetFlexLayout, groupSurface)}>
202
- <div className='flex justify-center overflow-y-scroll'>
203
- <div className='flex flex-col w-[800px] py-16'>
204
- <MarkdownEditor ref={ref} model={model} {...props} />
205
- <div className='flex shrink-0 h-[300px]'></div>
225
+ <div className='flex h-full justify-center'>
226
+ <div className='flex flex-col h-full w-[800px]'>
227
+ <MarkdownEditor model={model} {...props} />
206
228
  </div>
207
229
  </div>
208
230
  </div>
@@ -221,11 +243,11 @@ const extensions = [
221
243
  onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
222
244
  }),
223
245
  code(),
246
+ hr(),
224
247
  image(),
225
- link({ onRender }),
248
+ link({ onRender: onRenderLink, onHover: onHoverLinkTooltip }),
226
249
  table(),
227
250
  tasklist(),
228
- tooltip({ onHover }),
229
251
  ];
230
252
 
231
253
  export const Default = {
@@ -236,12 +258,37 @@ export const Readonly = {
236
258
  render: () => <Story text={document} extensions={extensions} readonly />,
237
259
  };
238
260
 
239
- export const Tooltips = {
240
- render: () => <Story text={str(text.links, text.footer)} extensions={[tooltip({ onHover })]} />,
261
+ const large = faker.helpers.multiple(() => faker.lorem.paragraph({ min: 8, max: 16 }), { count: 20 }).join('\n\n');
262
+
263
+ export const Large = {
264
+ render: () => <Story text={str('# Large Document', '', large)} extensions={[]} />,
265
+ };
266
+
267
+ export const Empty = {
268
+ render: () => <Story />,
269
+ };
270
+
271
+ export const NoExtensions = {
272
+ render: () => <Story text={document} />,
273
+ };
274
+
275
+ // TODO(burdon): Cursor bug if no newline after BR (cursor down just loops back to start of each paragraph).
276
+ export const HorizontalRule = {
277
+ render: () => (
278
+ <Story
279
+ text={str('# Horizontal Rule', '', text.paragraphs, '---', '', text.paragraphs, '---', '', text.paragraphs)}
280
+ extensions={[hr()]}
281
+ />
282
+ ),
241
283
  };
242
284
 
243
285
  export const Links = {
244
- render: () => <Story text={str(text.links, text.footer)} extensions={[link({ onRender })]} />,
286
+ render: () => (
287
+ <Story
288
+ text={str(text.links, text.footer)}
289
+ extensions={[link({ onHover: onHoverLinkTooltip, onRender: onRenderLink })]}
290
+ />
291
+ ),
245
292
  };
246
293
 
247
294
  export const Code = {
@@ -256,18 +303,15 @@ export const Image = {
256
303
  render: () => <Story text={str(text.image, text.footer)} readonly extensions={[image()]} />,
257
304
  };
258
305
 
259
- export const TaskList = {
306
+ export const Tasklist = {
307
+ render: () => <Story text={str(text.tasks, '', text.list, text.footer)} extensions={[tasklist()]} />,
308
+ };
309
+
310
+ export const Outliner = {
260
311
  render: () => (
261
312
  <Story
262
- text={str(text.tasks, '', text.list, text.footer)}
263
- extensions={[
264
- tasklist(),
265
- listener({
266
- onChange: (text) => {
267
- console.log(text);
268
- },
269
- }),
270
- ]}
313
+ text={str('# Outliner', '', 'Block', ': this is a block', ': with multiple lines', text.footer)}
314
+ extensions={[outliner()]}
271
315
  />
272
316
  ),
273
317
  };
@@ -277,7 +321,7 @@ export const Autocomplete = {
277
321
  <Story
278
322
  text={str('# Autocomplete', '', 'Press CTRL-SPACE', text.footer)}
279
323
  extensions={[
280
- link({ onRender }),
324
+ link({ onRender: onRenderLink }),
281
325
  autocomplete({
282
326
  onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
283
327
  }),
@@ -301,50 +345,59 @@ export const Mention = {
301
345
  ),
302
346
  };
303
347
 
304
- const mark = () => `[^${PublicKey.random().toHex()}]`;
305
348
  export const Comments = {
306
- render: () => (
307
- <Story
308
- text={str(text.paragraphs, mark(), '', mark(), text.footer)}
309
- extensions={[
310
- comments({
311
- onCreate: () => PublicKey.random().toHex(),
312
- onUpdate: (info) => {
313
- // console.log('update', info);
314
- },
315
- }),
316
- highlight(),
317
- ]}
318
- />
319
- ),
349
+ render: () => {
350
+ const [commentRanges, setCommentRanges] = useState<CommentRange[]>([]);
351
+
352
+ return (
353
+ <Story
354
+ text={str('# Comments', '', text.paragraphs, text.footer)}
355
+ comments={commentRanges}
356
+ extensions={[
357
+ comments({
358
+ onHover: onCommentsHover,
359
+ onCreate: (range) => {
360
+ const id = PublicKey.random().toHex();
361
+ setCommentRanges((commentRanges) => [...commentRanges, { id, cursor: range }]);
362
+ return id;
363
+ },
364
+ onSelect: (state) => {
365
+ const debug = false;
366
+ if (debug) {
367
+ console.log(
368
+ 'update',
369
+ JSON.stringify({
370
+ active: state.active?.slice(0, 8),
371
+ closest: state.closest?.slice(0, 8),
372
+ ranges: state.ranges.length,
373
+ }),
374
+ );
375
+ }
376
+ },
377
+ }),
378
+ ]}
379
+ />
380
+ );
381
+ },
320
382
  };
321
383
 
322
- export const Diagnostics = {
384
+ const typewriterItems = localStorage.getItem('dxos.org/plugin/markdown/typewriter')?.split(',');
385
+
386
+ export const Typewriter = {
323
387
  render: () => (
324
388
  <Story
325
- text={document}
326
- extensions={[
327
- // Cursor moved.
328
- EditorView.updateListener.of((update) => {
329
- console.log('update', update.view.state.selection.main.head);
330
- }),
331
- ]}
389
+ text={str('# Typewriter', '', text.paragraphs, text.footer)}
390
+ extensions={[typewriter({ items: typewriterItems })]}
332
391
  />
333
392
  ),
334
393
  };
335
394
 
336
- export const Demo = {
337
- render: () => <Story text={str(text.paragraphs, text.footer)} extensions={[demo()]} />,
338
- };
339
-
340
395
  export const Blast = {
341
396
  render: () => (
342
397
  <Story
343
- text={str(text.paragraphs, text.code, text.paragraphs)}
398
+ text={str('# Blast', '', text.paragraphs, text.code, text.paragraphs)}
344
399
  extensions={[
345
- demo({
346
- items: localStorage.getItem('dxos.composer.extension.demo')?.split(','),
347
- }),
400
+ typewriter({ items: typewriterItems }),
348
401
  blast(
349
402
  defaultsDeep(
350
403
  {
@@ -362,6 +415,16 @@ export const Blast = {
362
415
  ),
363
416
  };
364
417
 
365
- export const NoExtensions = {
366
- render: () => <Story text={document} />,
418
+ export const Diagnostics = {
419
+ render: () => (
420
+ <Story
421
+ text={document}
422
+ extensions={[
423
+ // Cursor moved.
424
+ EditorView.updateListener.of((update) => {
425
+ console.log('update', update.view.state.selection.main.head);
426
+ }),
427
+ ]}
428
+ />
429
+ ),
367
430
  };
@@ -4,15 +4,14 @@
4
4
 
5
5
  import '@dxosTheme';
6
6
 
7
- import defaultsDeep from 'lodash.defaultsdeep';
8
- import React, { useRef, useState } from 'react';
7
+ import React, { useState } from 'react';
9
8
 
10
9
  import { TextObject } from '@dxos/echo-schema';
11
10
  import { fixedInsetFlexLayout, groupSurface, mx } from '@dxos/react-ui-theme';
12
11
  import { withTheme } from '@dxos/storybook-utils';
13
12
 
14
- import { defaultSlots, TextEditor, type TextEditorProps, type TextEditorRef, type TextEditorSlots } from './TextEditor';
15
- import { textTheme } from './themes';
13
+ import { TextEditor, type TextEditorProps } from './TextEditor';
14
+ import { listener } from '../../extensions';
16
15
  import { useTextModel } from '../../hooks';
17
16
 
18
17
  const initialText = [
@@ -29,9 +28,8 @@ const Story = ({
29
28
  text,
30
29
  automerge,
31
30
  ...props
32
- }: { text?: string; automerge?: boolean } & Pick<TextEditorProps, 'extensions' | 'slots'>) => {
33
- const ref = useRef<TextEditorRef>(null);
34
- const [item] = useState({ text: new TextObject(text, undefined, undefined, { useAutomergeBackend: automerge }) });
31
+ }: { text?: string; automerge?: boolean } & Pick<TextEditorProps, 'extensions' | 'placeholder' | 'slots'>) => {
32
+ const [item] = useState({ text: new TextObject(text, undefined, undefined, { automerge }) });
35
33
  const model = useTextModel({ text: item.text });
36
34
  if (!model) {
37
35
  return null;
@@ -39,10 +37,9 @@ const Story = ({
39
37
 
40
38
  return (
41
39
  <div className={mx(fixedInsetFlexLayout, groupSurface)}>
42
- <div className='flex justify-center overflow-y-scroll'>
40
+ <div className='flex justify-center'>
43
41
  <div className='flex flex-col w-[800px] py-16'>
44
- <TextEditor ref={ref} model={model} {...props} />
45
- <div className='flex shrink-0 h-[300px]'></div>
42
+ <TextEditor model={model} {...props} />
46
43
  </div>
47
44
  </div>
48
45
  </div>
@@ -57,37 +54,19 @@ export default {
57
54
  };
58
55
 
59
56
  export const Default = {
60
- render: () => (
61
- <Story
62
- slots={defaultsDeep(
63
- { editor: { theme: textTheme, placeholder: 'Enter text...' } } satisfies TextEditorSlots,
64
- defaultSlots,
65
- )}
66
- />
67
- ),
57
+ render: () => <Story placeholder='Enter text...' />,
68
58
  };
69
59
 
70
60
  export const Text = {
71
- render: () => (
72
- <Story
73
- text={initialText}
74
- slots={defaultsDeep(
75
- { editor: { theme: textTheme, placeholder: 'Enter text...' } } satisfies TextEditorSlots,
76
- defaultSlots,
77
- )}
78
- />
79
- ),
61
+ render: () => <Story text={initialText} placeholder='Enter text...' />,
80
62
  };
81
63
 
82
64
  export const Automerge = {
65
+ render: () => <Story text={initialText} placeholder='Enter text...' automerge />,
66
+ };
67
+
68
+ export const Listener = {
83
69
  render: () => (
84
- <Story
85
- automerge
86
- text={initialText}
87
- slots={defaultsDeep(
88
- { editor: { theme: textTheme, placeholder: 'Enter text...' } } satisfies TextEditorSlots,
89
- defaultSlots,
90
- )}
91
- />
70
+ <Story placeholder='Enter text...' extensions={[listener({ onChange: (text) => console.log(text) })]} />
92
71
  ),
93
72
  };