@dxos/react-ui-editor 0.3.10 → 0.3.11-main.0ac3ef5

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 (215) hide show
  1. package/dist/lib/browser/index.mjs +1645 -1066
  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 +21 -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 +4 -0
  27. package/dist/types/src/extensions/automerge/index.d.ts.map +1 -0
  28. package/dist/types/src/{hooks/automerge/PatchSemaphore.d.ts → extensions/automerge/semaphore.d.ts} +5 -5
  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 +50 -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 +6 -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/table.d.ts.map +1 -0
  58. package/dist/types/src/extensions/tasklist.d.ts.map +1 -0
  59. package/dist/types/src/{components/TextEditor/extensions/demo.d.ts → extensions/typewriter.d.ts} +2 -3
  60. package/dist/types/src/extensions/typewriter.d.ts.map +1 -0
  61. package/dist/types/src/extensions/yjs/cursor.d.ts +4 -0
  62. package/dist/types/src/extensions/yjs/cursor.d.ts.map +1 -0
  63. package/dist/types/src/extensions/yjs/index.d.ts +2 -0
  64. package/dist/types/src/extensions/yjs/index.d.ts.map +1 -0
  65. package/dist/types/src/extensions/yjs/yjs.d.ts +4 -0
  66. package/dist/types/src/extensions/yjs/yjs.d.ts.map +1 -0
  67. package/dist/types/src/extensions/yjs/yjs.test.d.ts +2 -0
  68. package/dist/types/src/extensions/yjs/yjs.test.d.ts.map +1 -0
  69. package/dist/types/src/hooks/automerge.d.ts +3 -0
  70. package/dist/types/src/hooks/automerge.d.ts.map +1 -0
  71. package/dist/types/src/hooks/awareness-provider.d.ts +28 -0
  72. package/dist/types/src/hooks/awareness-provider.d.ts.map +1 -0
  73. package/dist/types/src/hooks/index.d.ts +2 -0
  74. package/dist/types/src/hooks/index.d.ts.map +1 -1
  75. package/dist/types/src/hooks/useTextModel.d.ts +15 -11
  76. package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
  77. package/dist/types/src/hooks/{yjs/space-provider.d.ts → yjs.d.ts} +8 -8
  78. package/dist/types/src/hooks/yjs.d.ts.map +1 -0
  79. package/dist/types/src/index.d.ts +6 -0
  80. package/dist/types/src/index.d.ts.map +1 -1
  81. package/dist/types/src/styles/cursors.d.ts.map +1 -0
  82. package/dist/types/src/styles/index.d.ts +1 -0
  83. package/dist/types/src/styles/index.d.ts.map +1 -1
  84. package/dist/types/src/styles/markdown.d.ts.map +1 -1
  85. package/dist/types/src/styles/tokens.d.ts +1 -0
  86. package/dist/types/src/styles/tokens.d.ts.map +1 -1
  87. package/dist/types/src/testing/replicator.d.ts +2 -2
  88. package/dist/types/src/testing/replicator.d.ts.map +1 -1
  89. package/dist/types/src/{components/TextEditor/themes → themes}/default.d.ts +5 -13
  90. package/dist/types/src/themes/default.d.ts.map +1 -0
  91. package/dist/types/src/themes/index.d.ts.map +1 -0
  92. package/dist/types/src/util.d.ts +5 -0
  93. package/dist/types/src/util.d.ts.map +1 -0
  94. package/package.json +26 -20
  95. package/src/components/TextEditor/MarkdownEditor.stories.tsx +140 -79
  96. package/src/components/TextEditor/TextEditor.stories.tsx +14 -35
  97. package/src/components/TextEditor/TextEditor.tsx +87 -79
  98. package/src/{hooks/automerge → components/TextEditor}/automerge.stories.tsx +67 -8
  99. package/src/components/TextEditor/codemirror.stories.ts +3 -2
  100. package/src/components/TextEditor/comments.stories.tsx +315 -0
  101. package/src/components/TextEditor/index.ts +0 -3
  102. package/src/{hooks/yjs → components/TextEditor}/yjs.stories.tsx +1 -1
  103. package/src/{components/TextEditor/extensions → extensions}/autocomplete.ts +18 -17
  104. package/src/extensions/automerge/automerge.ts +94 -0
  105. package/src/extensions/automerge/cursor.ts +52 -0
  106. package/src/extensions/automerge/defs.ts +62 -0
  107. package/src/extensions/automerge/index.ts +7 -0
  108. package/src/{hooks/automerge/PatchSemaphore.ts → extensions/automerge/semaphore.ts} +18 -15
  109. package/src/{hooks/automerge/translation/codemirror-to-automerge.ts → extensions/automerge/update-automerge.ts} +6 -7
  110. package/src/{hooks/automerge/translation/automerge-to-codemirror.ts → extensions/automerge/update-codemirror.ts} +14 -11
  111. package/src/extensions/awareness.ts +309 -0
  112. package/src/{components/TextEditor/extensions → extensions}/code.ts +25 -18
  113. package/src/extensions/comments.ts +325 -0
  114. package/src/extensions/cursor.ts +46 -0
  115. package/src/extensions/hr.ts +73 -0
  116. package/src/extensions/image.ts +87 -0
  117. package/src/{components/TextEditor/extensions → extensions}/index.ts +6 -3
  118. package/src/{components/TextEditor/extensions → extensions}/link.ts +116 -62
  119. package/src/extensions/listener.ts +35 -0
  120. package/src/{components/TextEditor/extensions → extensions}/markdown/highlight.ts +4 -16
  121. package/src/{components/TextEditor/extensions → extensions}/table.ts +23 -4
  122. package/src/{components/TextEditor/extensions → extensions}/tasklist.ts +3 -5
  123. package/src/{components/TextEditor/extensions/demo.ts → extensions/typewriter.ts} +2 -3
  124. package/src/extensions/yjs/cursor.ts +22 -0
  125. package/src/extensions/yjs/index.ts +5 -0
  126. package/src/extensions/yjs/yjs.test.ts +35 -0
  127. package/src/extensions/yjs/yjs.ts +16 -0
  128. package/src/hooks/automerge.ts +52 -0
  129. package/src/hooks/awareness-provider.ts +120 -0
  130. package/src/hooks/index.ts +2 -0
  131. package/src/hooks/useTextModel.ts +40 -79
  132. package/src/hooks/{yjs/space-provider.ts → yjs.ts} +49 -19
  133. package/src/index.ts +6 -0
  134. package/src/styles/index.ts +1 -0
  135. package/src/styles/markdown.ts +0 -2
  136. package/src/styles/tokens.ts +3 -0
  137. package/src/testing/replicator.ts +10 -16
  138. package/src/themes/default.ts +275 -0
  139. package/src/util.ts +18 -0
  140. package/dist/types/src/components/TextEditor/extensions/autocomplete.d.ts.map +0 -1
  141. package/dist/types/src/components/TextEditor/extensions/basic.d.ts.map +0 -1
  142. package/dist/types/src/components/TextEditor/extensions/blast.d.ts.map +0 -1
  143. package/dist/types/src/components/TextEditor/extensions/code.d.ts.map +0 -1
  144. package/dist/types/src/components/TextEditor/extensions/comments.d.ts +0 -18
  145. package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +0 -1
  146. package/dist/types/src/components/TextEditor/extensions/demo.d.ts.map +0 -1
  147. package/dist/types/src/components/TextEditor/extensions/experimental.d.ts +0 -10
  148. package/dist/types/src/components/TextEditor/extensions/experimental.d.ts.map +0 -1
  149. package/dist/types/src/components/TextEditor/extensions/highlight.d.ts +0 -24
  150. package/dist/types/src/components/TextEditor/extensions/highlight.d.ts.map +0 -1
  151. package/dist/types/src/components/TextEditor/extensions/image.d.ts.map +0 -1
  152. package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +0 -1
  153. package/dist/types/src/components/TextEditor/extensions/link.d.ts.map +0 -1
  154. package/dist/types/src/components/TextEditor/extensions/listener.d.ts +0 -9
  155. package/dist/types/src/components/TextEditor/extensions/listener.d.ts.map +0 -1
  156. package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts.map +0 -1
  157. package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts.map +0 -1
  158. package/dist/types/src/components/TextEditor/extensions/markdown/index.d.ts.map +0 -1
  159. package/dist/types/src/components/TextEditor/extensions/mention.d.ts.map +0 -1
  160. package/dist/types/src/components/TextEditor/extensions/table.d.ts.map +0 -1
  161. package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts.map +0 -1
  162. package/dist/types/src/components/TextEditor/extensions/tooltip.d.ts +0 -12
  163. package/dist/types/src/components/TextEditor/extensions/tooltip.d.ts.map +0 -1
  164. package/dist/types/src/components/TextEditor/themes/default.d.ts.map +0 -1
  165. package/dist/types/src/components/TextEditor/themes/index.d.ts.map +0 -1
  166. package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts.map +0 -1
  167. package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +0 -1
  168. package/dist/types/src/hooks/automerge/handle.d.ts +0 -9
  169. package/dist/types/src/hooks/automerge/handle.d.ts.map +0 -1
  170. package/dist/types/src/hooks/automerge/index.d.ts +0 -3
  171. package/dist/types/src/hooks/automerge/index.d.ts.map +0 -1
  172. package/dist/types/src/hooks/automerge/plugin.d.ts +0 -26
  173. package/dist/types/src/hooks/automerge/plugin.d.ts.map +0 -1
  174. package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts +0 -5
  175. package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts.map +0 -1
  176. package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts +0 -6
  177. package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts.map +0 -1
  178. package/dist/types/src/hooks/automerge/translation/index.d.ts +0 -3
  179. package/dist/types/src/hooks/automerge/translation/index.d.ts.map +0 -1
  180. package/dist/types/src/hooks/yjs/cursors.d.ts.map +0 -1
  181. package/dist/types/src/hooks/yjs/index.d.ts +0 -3
  182. package/dist/types/src/hooks/yjs/index.d.ts.map +0 -1
  183. package/dist/types/src/hooks/yjs/space-provider.d.ts.map +0 -1
  184. package/dist/types/src/hooks/yjs/yjs.stories.d.ts.map +0 -1
  185. package/src/components/TextEditor/extensions/comments.ts +0 -173
  186. package/src/components/TextEditor/extensions/experimental.tsx +0 -114
  187. package/src/components/TextEditor/extensions/highlight.ts +0 -128
  188. package/src/components/TextEditor/extensions/image.ts +0 -67
  189. package/src/components/TextEditor/extensions/listener.ts +0 -23
  190. package/src/components/TextEditor/extensions/tooltip.tsx +0 -61
  191. package/src/components/TextEditor/themes/default.ts +0 -279
  192. package/src/hooks/automerge/handle.ts +0 -14
  193. package/src/hooks/automerge/index.ts +0 -6
  194. package/src/hooks/automerge/plugin.ts +0 -134
  195. package/src/hooks/automerge/translation/index.ts +0 -6
  196. package/src/hooks/yjs/index.ts +0 -6
  197. /package/dist/types/src/{components/TextEditor/extensions → extensions}/autocomplete.d.ts +0 -0
  198. /package/dist/types/src/{components/TextEditor/extensions → extensions}/basic.d.ts +0 -0
  199. /package/dist/types/src/{components/TextEditor/extensions → extensions}/blast.d.ts +0 -0
  200. /package/dist/types/src/{components/TextEditor/extensions → extensions}/code.d.ts +0 -0
  201. /package/dist/types/src/{components/TextEditor/extensions → extensions}/image.d.ts +0 -0
  202. /package/dist/types/src/{components/TextEditor/extensions → extensions}/markdown/bundle.d.ts +0 -0
  203. /package/dist/types/src/{components/TextEditor/extensions → extensions}/markdown/index.d.ts +0 -0
  204. /package/dist/types/src/{components/TextEditor/extensions → extensions}/mention.d.ts +0 -0
  205. /package/dist/types/src/{components/TextEditor/extensions → extensions}/table.d.ts +0 -0
  206. /package/dist/types/src/{components/TextEditor/extensions → extensions}/tasklist.d.ts +0 -0
  207. /package/dist/types/src/{hooks/yjs → styles}/cursors.d.ts +0 -0
  208. /package/dist/types/src/{components/TextEditor/themes → themes}/index.d.ts +0 -0
  209. /package/src/{components/TextEditor/extensions → extensions}/basic.ts +0 -0
  210. /package/src/{components/TextEditor/extensions → extensions}/blast.ts +0 -0
  211. /package/src/{components/TextEditor/extensions → extensions}/markdown/bundle.ts +0 -0
  212. /package/src/{components/TextEditor/extensions → extensions}/markdown/index.ts +0 -0
  213. /package/src/{components/TextEditor/extensions → extensions}/mention.ts +0 -0
  214. /package/src/{hooks/yjs → styles}/cursors.ts +0 -0
  215. /package/src/{components/TextEditor/themes → themes}/index.ts +0 -0
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.0ac3ef5",
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",
@@ -32,24 +32,26 @@
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.0ac3ef5",
42
+ "@dxos/automerge": "0.3.11-main.0ac3ef5",
43
+ "@dxos/debug": "0.3.11-main.0ac3ef5",
44
+ "@dxos/context": "0.3.11-main.0ac3ef5",
45
+ "@dxos/display-name": "0.3.11-main.0ac3ef5",
46
+ "@dxos/invariant": "0.3.11-main.0ac3ef5",
47
+ "@dxos/echo-schema": "0.3.11-main.0ac3ef5",
48
+ "@dxos/log": "0.3.11-main.0ac3ef5",
49
+ "@dxos/react-async": "0.3.11-main.0ac3ef5",
50
+ "@dxos/protocols": "0.3.11-main.0ac3ef5",
51
+ "@dxos/react-ui": "0.3.11-main.0ac3ef5",
52
+ "@dxos/react-ui-theme": "0.3.11-main.0ac3ef5",
53
+ "@dxos/text-model": "0.3.11-main.0ac3ef5",
54
+ "@dxos/util": "0.3.11-main.0ac3ef5"
53
55
  },
54
56
  "devDependencies": {
55
57
  "@automerge/automerge-repo-network-broadcastchannel": "^1.0.19",
@@ -58,22 +60,26 @@
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.0ac3ef5",
71
+ "@dxos/echo-signals": "0.3.11-main.0ac3ef5",
72
+ "@dxos/echo-typegen": "0.3.11-main.0ac3ef5",
73
+ "@dxos/keyboard": "0.3.11-main.0ac3ef5",
74
+ "@dxos/react-ui": "0.3.11-main.0ac3ef5",
75
+ "@dxos/storybook-utils": "0.3.11-main.0ac3ef5",
76
+ "@dxos/react-client": "0.3.11-main.0ac3ef5"
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.0ac3ef5"
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,
23
+ blast,
24
+ code,
25
+ comments,
26
+ defaultOptions,
27
+ hr,
28
+ image,
22
29
  listener,
23
30
  link,
31
+ mention,
32
+ table,
24
33
  tasklist,
25
- tooltip,
26
- type TooltipOptions,
34
+ typewriter,
35
+ type CommentsOptions,
27
36
  type LinkOptions,
28
- comments,
29
- table,
30
- image,
31
- mention,
32
- blast,
33
- demo,
34
- defaultOptions,
35
- highlight,
36
- code,
37
- } from './extensions';
38
- import { useTextModel } from '../../hooks';
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,7 +303,7 @@ 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 = {
260
307
  render: () => (
261
308
  <Story
262
309
  text={str(text.tasks, '', text.list, text.footer)}
@@ -277,7 +324,7 @@ export const Autocomplete = {
277
324
  <Story
278
325
  text={str('# Autocomplete', '', 'Press CTRL-SPACE', text.footer)}
279
326
  extensions={[
280
- link({ onRender }),
327
+ link({ onRender: onRenderLink }),
281
328
  autocomplete({
282
329
  onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
283
330
  }),
@@ -301,48 +348,52 @@ export const Mention = {
301
348
  ),
302
349
  };
303
350
 
304
- const mark = () => `[^${PublicKey.random().toHex()}]`;
305
351
  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
- ),
320
- };
321
-
322
- export const Diagnostics = {
323
- render: () => (
324
- <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
- ]}
332
- />
333
- ),
352
+ render: () => {
353
+ const [commentRanges, setCommentRanges] = useState<CommentRange[]>([]);
354
+
355
+ return (
356
+ <Story
357
+ text={str('# Comments', '', text.paragraphs, text.footer)}
358
+ comments={commentRanges}
359
+ extensions={[
360
+ comments({
361
+ onHover: onCommentsHover,
362
+ onCreate: (range) => {
363
+ const id = PublicKey.random().toHex();
364
+ setCommentRanges((commentRanges) => [...commentRanges, { id, cursor: range }]);
365
+ return id;
366
+ },
367
+ onSelect: (state) => {
368
+ const debug = false;
369
+ if (debug) {
370
+ console.log(
371
+ 'update',
372
+ JSON.stringify({
373
+ active: state.active?.slice(0, 8),
374
+ closest: state.closest?.slice(0, 8),
375
+ ranges: state.ranges.length,
376
+ }),
377
+ );
378
+ }
379
+ },
380
+ }),
381
+ ]}
382
+ />
383
+ );
384
+ },
334
385
  };
335
386
 
336
- export const Demo = {
337
- render: () => <Story text={str(text.paragraphs, text.footer)} extensions={[demo()]} />,
387
+ export const Typewriter = {
388
+ render: () => <Story text={str('# Typewriter', '', text.paragraphs, text.footer)} extensions={[typewriter()]} />,
338
389
  };
339
390
 
340
391
  export const Blast = {
341
392
  render: () => (
342
393
  <Story
343
- text={str(text.paragraphs, text.code, text.paragraphs)}
394
+ text={str('# Blast', '', text.paragraphs, text.code, text.paragraphs)}
344
395
  extensions={[
345
- demo({
396
+ typewriter({
346
397
  items: localStorage.getItem('dxos.composer.extension.demo')?.split(','),
347
398
  }),
348
399
  blast(
@@ -362,6 +413,16 @@ export const Blast = {
362
413
  ),
363
414
  };
364
415
 
365
- export const NoExtensions = {
366
- render: () => <Story text={document} />,
416
+ export const Diagnostics = {
417
+ render: () => (
418
+ <Story
419
+ text={document}
420
+ extensions={[
421
+ // Cursor moved.
422
+ EditorView.updateListener.of((update) => {
423
+ console.log('update', update.view.state.selection.main.head);
424
+ }),
425
+ ]}
426
+ />
427
+ ),
367
428
  };
@@ -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
  };