@dxos/react-ui-editor 0.3.11-main.a996413 → 0.3.11-main.afa73e0

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 (186) hide show
  1. package/dist/lib/browser/index.mjs +2014 -1648
  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 +16 -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 +20 -17
  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 -1
  11. package/dist/types/src/components/TextEditor/automerge.stories.d.ts.map +1 -0
  12. package/dist/types/src/components/TextEditor/comments.stories.d.ts +26 -0
  13. package/dist/types/src/components/TextEditor/comments.stories.d.ts.map +1 -0
  14. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
  15. package/dist/types/src/extensions/automerge/automerge.d.ts +9 -0
  16. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -0
  17. package/dist/types/src/extensions/automerge/cursor.d.ts +5 -0
  18. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -0
  19. package/dist/types/src/extensions/automerge/defs.d.ts +24 -0
  20. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -0
  21. package/dist/types/src/extensions/automerge/index.d.ts +3 -0
  22. package/dist/types/src/extensions/automerge/index.d.ts.map +1 -0
  23. package/dist/types/src/extensions/automerge/semaphore.d.ts +14 -0
  24. package/dist/types/src/extensions/automerge/semaphore.d.ts.map +1 -0
  25. package/dist/types/src/extensions/automerge/update-automerge.d.ts +5 -0
  26. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -0
  27. package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -0
  28. package/dist/types/src/extensions/awareness.d.ts +46 -0
  29. package/dist/types/src/extensions/awareness.d.ts.map +1 -0
  30. package/dist/types/src/extensions/basic.d.ts +4 -5
  31. package/dist/types/src/extensions/basic.d.ts.map +1 -1
  32. package/dist/types/src/extensions/comments.d.ts +32 -19
  33. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  34. package/dist/types/src/extensions/cursor.d.ts +25 -0
  35. package/dist/types/src/extensions/cursor.d.ts.map +1 -0
  36. package/dist/types/src/extensions/index.d.ts +4 -7
  37. package/dist/types/src/extensions/index.d.ts.map +1 -1
  38. package/dist/types/src/extensions/markdown/bundle.d.ts +3 -6
  39. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  40. package/dist/types/src/extensions/markdown/code.d.ts.map +1 -0
  41. package/dist/types/src/extensions/markdown/heading.d.ts +6 -0
  42. package/dist/types/src/extensions/markdown/heading.d.ts.map +1 -0
  43. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  44. package/dist/types/src/extensions/markdown/hr.d.ts.map +1 -0
  45. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -0
  46. package/dist/types/src/extensions/markdown/index.d.ts +7 -0
  47. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
  48. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -0
  49. package/dist/types/src/extensions/markdown/table.d.ts.map +1 -0
  50. package/dist/types/src/extensions/markdown/tasklist.d.ts.map +1 -0
  51. package/dist/types/src/extensions/mention.d.ts.map +1 -1
  52. package/dist/types/src/extensions/outliner.d.ts +4 -0
  53. package/dist/types/src/extensions/outliner.d.ts.map +1 -0
  54. package/dist/types/src/hooks/awareness-provider.d.ts +31 -0
  55. package/dist/types/src/hooks/awareness-provider.d.ts.map +1 -0
  56. package/dist/types/src/hooks/defs.d.ts +25 -0
  57. package/dist/types/src/hooks/defs.d.ts.map +1 -0
  58. package/dist/types/src/hooks/index.d.ts +3 -1
  59. package/dist/types/src/hooks/index.d.ts.map +1 -1
  60. package/dist/types/src/hooks/useTextEditor.d.ts +17 -0
  61. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -0
  62. package/dist/types/src/hooks/useTextModel.d.ts +2 -31
  63. package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
  64. package/dist/types/src/index.d.ts +3 -0
  65. package/dist/types/src/index.d.ts.map +1 -1
  66. package/dist/types/src/styles/cursors.d.ts.map +1 -0
  67. package/dist/types/src/styles/index.d.ts +1 -0
  68. package/dist/types/src/styles/index.d.ts.map +1 -1
  69. package/dist/types/src/styles/markdown.d.ts +2 -2
  70. package/dist/types/src/styles/markdown.d.ts.map +1 -1
  71. package/dist/types/src/styles/tokens.d.ts +1 -0
  72. package/dist/types/src/styles/tokens.d.ts.map +1 -1
  73. package/dist/types/src/themes/default.d.ts.map +1 -1
  74. package/dist/types/src/util.d.ts +7 -0
  75. package/dist/types/src/util.d.ts.map +1 -0
  76. package/package.json +34 -35
  77. package/src/components/TextEditor/MarkdownEditor.stories.tsx +82 -83
  78. package/src/components/TextEditor/TextEditor.stories.tsx +13 -34
  79. package/src/components/TextEditor/TextEditor.tsx +122 -93
  80. package/src/{hooks/automerge → components/TextEditor}/automerge.stories.tsx +66 -6
  81. package/src/components/TextEditor/comments.stories.tsx +357 -0
  82. package/src/extensions/autocomplete.ts +23 -19
  83. package/src/extensions/automerge/automerge.ts +88 -0
  84. package/src/extensions/automerge/cursor.ts +52 -0
  85. package/src/extensions/automerge/defs.ts +41 -0
  86. package/src/extensions/automerge/index.ts +6 -0
  87. package/src/{hooks → extensions}/automerge/semaphore.ts +34 -29
  88. package/src/{hooks → extensions}/automerge/update-automerge.ts +5 -6
  89. package/src/{hooks → extensions}/automerge/update-codemirror.ts +13 -5
  90. package/src/extensions/awareness.ts +310 -0
  91. package/src/extensions/basic.ts +22 -17
  92. package/src/extensions/comments.ts +252 -229
  93. package/src/extensions/cursor.ts +50 -0
  94. package/src/extensions/index.ts +4 -7
  95. package/src/extensions/markdown/bundle.ts +20 -30
  96. package/src/extensions/markdown/code.ts +127 -0
  97. package/src/extensions/markdown/heading.ts +59 -0
  98. package/src/extensions/markdown/highlight.ts +11 -26
  99. package/src/extensions/markdown/hr.ts +71 -0
  100. package/src/extensions/markdown/image.ts +87 -0
  101. package/src/extensions/markdown/index.ts +7 -0
  102. package/src/extensions/{link.ts → markdown/link.ts} +85 -88
  103. package/src/extensions/{table.ts → markdown/table.ts} +10 -4
  104. package/src/extensions/markdown/tasklist.ts +110 -0
  105. package/src/extensions/mention.ts +9 -2
  106. package/src/extensions/outliner.ts +12 -0
  107. package/src/hooks/awareness-provider.ts +124 -0
  108. package/src/hooks/defs.ts +42 -0
  109. package/src/hooks/index.ts +4 -1
  110. package/src/hooks/useTextEditor.ts +29 -0
  111. package/src/hooks/useTextModel.ts +30 -116
  112. package/src/index.ts +3 -0
  113. package/src/styles/index.ts +1 -0
  114. package/src/styles/markdown.ts +9 -12
  115. package/src/styles/tokens.ts +3 -0
  116. package/src/themes/default.ts +49 -78
  117. package/src/util.ts +41 -0
  118. package/dist/types/src/components/TextEditor/codemirror.stories.d.ts +0 -12
  119. package/dist/types/src/components/TextEditor/codemirror.stories.d.ts.map +0 -1
  120. package/dist/types/src/extensions/code.d.ts.map +0 -1
  121. package/dist/types/src/extensions/hr.d.ts.map +0 -1
  122. package/dist/types/src/extensions/image.d.ts.map +0 -1
  123. package/dist/types/src/extensions/link.d.ts.map +0 -1
  124. package/dist/types/src/extensions/mermaid.d.ts +0 -3
  125. package/dist/types/src/extensions/mermaid.d.ts.map +0 -1
  126. package/dist/types/src/extensions/table.d.ts.map +0 -1
  127. package/dist/types/src/extensions/tasklist.d.ts.map +0 -1
  128. package/dist/types/src/extensions/util.d.ts +0 -5
  129. package/dist/types/src/extensions/util.d.ts.map +0 -1
  130. package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +0 -1
  131. package/dist/types/src/hooks/automerge/handle.d.ts +0 -9
  132. package/dist/types/src/hooks/automerge/handle.d.ts.map +0 -1
  133. package/dist/types/src/hooks/automerge/index.d.ts +0 -3
  134. package/dist/types/src/hooks/automerge/index.d.ts.map +0 -1
  135. package/dist/types/src/hooks/automerge/plugin.d.ts +0 -26
  136. package/dist/types/src/hooks/automerge/plugin.d.ts.map +0 -1
  137. package/dist/types/src/hooks/automerge/semaphore.d.ts +0 -19
  138. package/dist/types/src/hooks/automerge/semaphore.d.ts.map +0 -1
  139. package/dist/types/src/hooks/automerge/update-automerge.d.ts +0 -6
  140. package/dist/types/src/hooks/automerge/update-automerge.d.ts.map +0 -1
  141. package/dist/types/src/hooks/automerge/update-codemirror.d.ts.map +0 -1
  142. package/dist/types/src/hooks/yjs/cursors.d.ts.map +0 -1
  143. package/dist/types/src/hooks/yjs/index.d.ts +0 -3
  144. package/dist/types/src/hooks/yjs/index.d.ts.map +0 -1
  145. package/dist/types/src/hooks/yjs/space-provider.d.ts +0 -27
  146. package/dist/types/src/hooks/yjs/space-provider.d.ts.map +0 -1
  147. package/dist/types/src/hooks/yjs/yjs.stories.d.ts +0 -12
  148. package/dist/types/src/hooks/yjs/yjs.stories.d.ts.map +0 -1
  149. package/dist/types/src/hooks/yjs/yjs.test.d.ts +0 -2
  150. package/dist/types/src/hooks/yjs/yjs.test.d.ts.map +0 -1
  151. package/dist/types/src/testing/index.d.ts +0 -3
  152. package/dist/types/src/testing/index.d.ts.map +0 -1
  153. package/dist/types/src/testing/proto/gen/schema.d.ts +0 -15
  154. package/dist/types/src/testing/proto/gen/schema.d.ts.map +0 -1
  155. package/dist/types/src/testing/proto/index.d.ts +0 -2
  156. package/dist/types/src/testing/proto/index.d.ts.map +0 -1
  157. package/dist/types/src/testing/replicator.d.ts +0 -45
  158. package/dist/types/src/testing/replicator.d.ts.map +0 -1
  159. package/src/components/TextEditor/codemirror.stories.ts +0 -114
  160. package/src/extensions/code.ts +0 -99
  161. package/src/extensions/hr.ts +0 -74
  162. package/src/extensions/image.ts +0 -69
  163. package/src/extensions/mermaid.ts +0 -11
  164. package/src/extensions/tasklist.ts +0 -121
  165. package/src/extensions/util.ts +0 -18
  166. package/src/hooks/automerge/handle.ts +0 -14
  167. package/src/hooks/automerge/index.ts +0 -6
  168. package/src/hooks/automerge/plugin.ts +0 -132
  169. package/src/hooks/yjs/index.ts +0 -6
  170. package/src/hooks/yjs/space-provider.ts +0 -126
  171. package/src/hooks/yjs/yjs.stories.tsx +0 -56
  172. package/src/hooks/yjs/yjs.test.ts +0 -59
  173. package/src/testing/index.ts +0 -6
  174. package/src/testing/proto/gen/schema.ts +0 -49
  175. package/src/testing/proto/index.ts +0 -5
  176. package/src/testing/proto/schema.proto +0 -15
  177. package/src/testing/replicator.ts +0 -189
  178. /package/dist/types/src/{hooks → extensions}/automerge/update-codemirror.d.ts +0 -0
  179. /package/dist/types/src/extensions/{code.d.ts → markdown/code.d.ts} +0 -0
  180. /package/dist/types/src/extensions/{hr.d.ts → markdown/hr.d.ts} +0 -0
  181. /package/dist/types/src/extensions/{image.d.ts → markdown/image.d.ts} +0 -0
  182. /package/dist/types/src/extensions/{link.d.ts → markdown/link.d.ts} +0 -0
  183. /package/dist/types/src/extensions/{table.d.ts → markdown/table.d.ts} +0 -0
  184. /package/dist/types/src/extensions/{tasklist.d.ts → markdown/tasklist.d.ts} +0 -0
  185. /package/dist/types/src/{hooks/yjs → styles}/cursors.d.ts +0 -0
  186. /package/src/{hooks/yjs → styles}/cursors.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-editor",
3
- "version": "0.3.11-main.a996413",
3
+ "version": "0.3.11-main.afa73e0",
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",
@@ -13,20 +13,20 @@
13
13
  "src"
14
14
  ],
15
15
  "dependencies": {
16
- "@codemirror/autocomplete": "^6.11.1",
17
- "@codemirror/commands": "^6.3.2",
18
- "@codemirror/lang-markdown": "^6.2.3",
19
- "@codemirror/language": "^6.9.3",
16
+ "@codemirror/autocomplete": "^6.12.0",
17
+ "@codemirror/commands": "^6.3.3",
18
+ "@codemirror/lang-markdown": "^6.2.4",
19
+ "@codemirror/language": "^6.10.0",
20
20
  "@codemirror/language-data": "^6.3.1",
21
21
  "@codemirror/lint": "^6.4.2",
22
22
  "@codemirror/search": "^6.5.5",
23
- "@codemirror/state": "^6.3.3",
23
+ "@codemirror/state": "^6.4.0",
24
24
  "@codemirror/theme-one-dark": "^6.1.2",
25
- "@codemirror/view": "^6.22.2",
25
+ "@codemirror/view": "^6.23.0",
26
26
  "@fluentui/react-tabster": "^9.16.1",
27
- "@lezer/common": "^1.1.1",
27
+ "@lezer/common": "^1.2.1",
28
28
  "@lezer/highlight": "^1.2.0",
29
- "@lezer/markdown": "^1.1.1",
29
+ "@lezer/markdown": "^1.2.0",
30
30
  "@replit/codemirror-vim": "^6.0.14",
31
31
  "codemirror": "6.0.1",
32
32
  "lib0": "^0.2.65",
@@ -35,26 +35,24 @@
35
35
  "lodash.pick": "^4.4.0",
36
36
  "lodash.sortby": "^4.7.0",
37
37
  "style-mod": "^4.1.0",
38
- "y-codemirror.next": "^0.3.2",
39
- "y-protocols": "^1.0.5",
40
- "yjs": "^13.6.10",
41
- "@dxos/async": "0.3.11-main.a996413",
42
- "@dxos/automerge": "0.3.11-main.a996413",
43
- "@dxos/display-name": "0.3.11-main.a996413",
44
- "@dxos/echo-schema": "0.3.11-main.a996413",
45
- "@dxos/debug": "0.3.11-main.a996413",
46
- "@dxos/invariant": "0.3.11-main.a996413",
47
- "@dxos/log": "0.3.11-main.a996413",
48
- "@dxos/protocols": "0.3.11-main.a996413",
49
- "@dxos/react-async": "0.3.11-main.a996413",
50
- "@dxos/react-ui": "0.3.11-main.a996413",
51
- "@dxos/react-ui-theme": "0.3.11-main.a996413",
52
- "@dxos/util": "0.3.11-main.a996413",
53
- "@dxos/text-model": "0.3.11-main.a996413"
38
+ "@dxos/context": "0.3.11-main.afa73e0",
39
+ "@dxos/async": "0.3.11-main.afa73e0",
40
+ "@dxos/debug": "0.3.11-main.afa73e0",
41
+ "@dxos/automerge": "0.3.11-main.afa73e0",
42
+ "@dxos/display-name": "0.3.11-main.afa73e0",
43
+ "@dxos/invariant": "0.3.11-main.afa73e0",
44
+ "@dxos/echo-schema": "0.3.11-main.afa73e0",
45
+ "@dxos/log": "0.3.11-main.afa73e0",
46
+ "@dxos/protocols": "0.3.11-main.afa73e0",
47
+ "@dxos/react-ui": "0.3.11-main.afa73e0",
48
+ "@dxos/react-async": "0.3.11-main.afa73e0",
49
+ "@dxos/react-ui-theme": "0.3.11-main.afa73e0",
50
+ "@dxos/text-model": "0.3.11-main.afa73e0",
51
+ "@dxos/util": "0.3.11-main.afa73e0"
54
52
  },
55
53
  "devDependencies": {
56
- "@automerge/automerge-repo-network-broadcastchannel": "^1.0.19",
57
- "@faker-js/faker": "^8.0.2",
54
+ "@automerge/automerge-repo-network-broadcastchannel": "^1.1.0",
55
+ "@faker-js/faker": "^8.3.1",
58
56
  "@phosphor-icons/react": "^2.0.5",
59
57
  "@preact/signals-react": "^1.3.6",
60
58
  "@types/lodash.defaultsdeep": "^4.6.6",
@@ -66,23 +64,24 @@
66
64
  "deepsignal": "1.4.0-shallow.0",
67
65
  "react": "^18.2.0",
68
66
  "react-dom": "^18.2.0",
69
- "@dxos/echo-signals": "0.3.11-main.a996413",
70
- "@dxos/echo-typegen": "0.3.11-main.a996413",
71
- "@dxos/config": "0.3.11-main.a996413",
72
- "@dxos/react-client": "0.3.11-main.a996413",
73
- "@dxos/storybook-utils": "0.3.11-main.a996413",
74
- "@dxos/react-ui": "0.3.11-main.a996413"
67
+ "@dxos/config": "0.3.11-main.afa73e0",
68
+ "@dxos/echo-signals": "0.3.11-main.afa73e0",
69
+ "@dxos/keyboard": "0.3.11-main.afa73e0",
70
+ "@dxos/react-ui": "0.3.11-main.afa73e0",
71
+ "@dxos/react-client": "0.3.11-main.afa73e0",
72
+ "@dxos/echo-typegen": "0.3.11-main.afa73e0",
73
+ "@dxos/storybook-utils": "0.3.11-main.afa73e0"
75
74
  },
76
75
  "peerDependencies": {
77
76
  "@phosphor-icons/react": "^2.0.5",
78
77
  "react": "^18.2.0",
79
78
  "react-dom": "^18.2.0",
80
- "@dxos/react-client": "0.3.11-main.a996413"
79
+ "@dxos/react-client": "0.3.11-main.afa73e0"
81
80
  },
82
81
  "publishConfig": {
83
82
  "access": "public"
84
83
  },
85
84
  "scripts": {
86
- "prebuild": "dxtype src/testing/proto/schema.proto src/testing/proto/gen/schema.ts"
85
+ "test": "true"
87
86
  }
88
87
  }
@@ -4,7 +4,7 @@
4
4
 
5
5
  import '@dxosTheme';
6
6
 
7
- import { EditorView } from '@codemirror/view';
7
+ import { type 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';
@@ -12,11 +12,12 @@ import React, { type FC, StrictMode, useRef, 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
23
  blast,
@@ -25,7 +26,6 @@ import {
25
26
  defaultOptions,
26
27
  hr,
27
28
  image,
28
- listener,
29
29
  link,
30
30
  mention,
31
31
  table,
@@ -33,9 +33,10 @@ import {
33
33
  typewriter,
34
34
  type CommentsOptions,
35
35
  type LinkOptions,
36
- mermaid,
36
+ useComments,
37
+ heading,
37
38
  } from '../../extensions';
38
- import { type CommentRange, useTextModel } from '../../hooks';
39
+ import { type Comment, useTextModel } from '../../hooks';
39
40
 
40
41
  // Extensions:
41
42
  // TODO(burdon): Table of contents.
@@ -55,8 +56,8 @@ const text = {
55
56
  '- [x] decorator',
56
57
  '- [ ] checkbox',
57
58
  ' - [ ] state',
58
- ' - [ ] indent',
59
- ' - [x] style',
59
+ ' - [ ] indent',
60
+ ' - [x] style',
60
61
  '',
61
62
  ),
62
63
 
@@ -82,7 +83,7 @@ const text = {
82
83
  '## Code',
83
84
  '',
84
85
  '```',
85
- 'const x = 100;',
86
+ '$ ls -las',
86
87
  '```',
87
88
  '',
88
89
  '```tsx',
@@ -123,8 +124,6 @@ const text = {
123
124
 
124
125
  paragraphs: str(...faker.helpers.multiple(() => [faker.lorem.paragraph(), ''], { count: 3 }).flat()),
125
126
 
126
- mermaid: str('```mermaid', 'graph TD;', 'A-->B;', 'A-->C;', 'B-->D;', 'C-->D;', '```'),
127
-
128
127
  footer: str('', '', '', '', '')
129
128
  };
130
129
 
@@ -164,6 +163,8 @@ const links = [
164
163
  { label: 'StackEdit', apply: '[StackEdit](https://stackedit.io/app)' },
165
164
  ];
166
165
 
166
+ const names = ['adam', 'alice', 'alison', 'bob', 'carol', 'charlie', 'sayuri', 'shoko'];
167
+
167
168
  const hover =
168
169
  'rounded-sm text-base text-primary-600 hover:text-primary-500 dark:text-primary-300 hover:dark:text-primary-200';
169
170
 
@@ -185,15 +186,15 @@ const Key: FC<{ char: string }> = ({ char }) => (
185
186
  </span>
186
187
  );
187
188
 
188
- const onCommentsHover: CommentsOptions['onHover'] = (el) => {
189
+ const onCommentsHover: CommentsOptions['onHover'] = (el, shortcut) => {
189
190
  createRoot(el).render(
190
191
  <StrictMode>
191
192
  <div className='flex items-center gap-2 px-2 py-2 bg-neutral-700 text-white text-xs rounded'>
192
193
  <div>Create comment</div>
193
- {/* TODO(burdon): Unify shortcuts. */}
194
194
  <div className='flex gap-1'>
195
- <Key char='⌘' />
196
- <Key char="'" />
195
+ {keySymbols(parseShortcut(shortcut)).map((char) => (
196
+ <Key key={char} char={char} />
197
+ ))}
197
198
  </div>
198
199
  </div>
199
200
  </StrictMode>,
@@ -204,7 +205,7 @@ const onRenderLink: LinkOptions['onRender'] = (el, url) => {
204
205
  createRoot(el).render(
205
206
  <StrictMode>
206
207
  <a href={url} target='_blank' rel='noreferrer' className={hover}>
207
- <ArrowSquareOut weight='bold' className={mx(getSize(4), 'inline-block leading-none mis-1 mb-1')} />
208
+ <ArrowSquareOut weight='bold' className={mx(getSize(4), 'inline-block leading-none mis-1 mb-[2px]')} />
208
209
  </a>
209
210
  </StrictMode>,
210
211
  );
@@ -212,23 +213,24 @@ const onRenderLink: LinkOptions['onRender'] = (el, url) => {
212
213
 
213
214
  type StoryProps = {
214
215
  text?: string;
216
+ comments?: Comment[];
215
217
  automerge?: boolean;
216
- } & Pick<TextEditorProps, 'comments' | 'readonly' | 'extensions' | 'slots'>;
218
+ } & Pick<TextEditorProps, 'readonly' | 'placeholder' | 'slots' | 'extensions'>;
217
219
 
218
- const Story = ({ text, automerge, ...props }: StoryProps) => {
219
- const ref = useRef<TextEditorRef>(null);
220
+ const Story = ({ text, comments, automerge, placeholder = 'New document.', ...props }: StoryProps) => {
220
221
  const [item] = useState({ text: new TextObject(text, undefined, undefined, { automerge }) });
222
+ const view = useRef<EditorView>(null);
221
223
  const model = useTextModel({ text: item.text });
224
+ useComments(view.current, comments);
222
225
  if (!model) {
223
226
  return null;
224
227
  }
225
228
 
226
229
  return (
227
230
  <div className={mx(fixedInsetFlexLayout, groupSurface)}>
228
- <div className='flex justify-center overflow-y-scroll'>
229
- <div className='flex flex-col w-[800px] py-16'>
230
- <MarkdownEditor ref={ref} model={model} {...props} />
231
- <div className='flex shrink-0 h-[300px]'></div>
231
+ <div className='flex h-full justify-center'>
232
+ <div className='flex flex-col h-full w-[800px]'>
233
+ <MarkdownEditor ref={view} model={model} placeholder={placeholder} {...props} />
232
234
  </div>
233
235
  </div>
234
236
  </div>
@@ -242,38 +244,42 @@ export default {
242
244
  render: Story,
243
245
  };
244
246
 
245
- const extensions = [
247
+ const defaults = [
246
248
  autocomplete({
247
249
  onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
248
250
  }),
249
251
  code(),
252
+ heading(),
250
253
  hr(),
251
254
  image(),
252
255
  link({ onRender: onRenderLink, onHover: onHoverLinkTooltip }),
256
+ // mention({
257
+ // onSearch: (text) => names.filter((name) => name.toLowerCase().startsWith(text.toLowerCase())),
258
+ // }),
253
259
  table(),
254
260
  tasklist(),
255
261
  ];
256
262
 
257
263
  export const Default = {
258
- render: () => <Story text={document} extensions={extensions} />,
264
+ render: () => <Story text={document} extensions={defaults} />,
259
265
  };
260
266
 
261
267
  export const Readonly = {
262
- render: () => <Story text={document} extensions={extensions} readonly />,
268
+ render: () => <Story text={document} extensions={defaults} readonly />,
263
269
  };
264
270
 
265
271
  export const NoExtensions = {
266
272
  render: () => <Story text={document} />,
267
273
  };
268
274
 
269
- // TODO(burdon): Cursor bug if no newline after BR (cursor down just loops back to start of each paragraph).
270
- export const HorizontalRule = {
271
- render: () => (
272
- <Story
273
- text={str('# Horizontal Rule', '', text.paragraphs, '---', '', text.paragraphs, '---', '', text.paragraphs)}
274
- extensions={[hr()]}
275
- />
276
- ),
275
+ const large = faker.helpers.multiple(() => faker.lorem.paragraph({ min: 8, max: 16 }), { count: 20 }).join('\n\n');
276
+
277
+ export const Empty = {
278
+ render: () => <Story />,
279
+ };
280
+
281
+ export const Scrolling = {
282
+ render: () => <Story text={str('# Large Document', '', large)} extensions={[]} />,
277
283
  };
278
284
 
279
285
  export const Links = {
@@ -286,37 +292,36 @@ export const Links = {
286
292
  };
287
293
 
288
294
  export const Code = {
289
- render: () => <Story text={str(text.code, text.footer)} extensions={[code()]} readonly />,
290
- };
291
-
292
- export const Table = {
293
- render: () => <Story text={str(text.table, text.footer)} extensions={[table()]} />,
295
+ render: () => <Story text={str(text.code, text.footer)} extensions={[code()]} />,
294
296
  };
295
297
 
296
298
  export const Image = {
297
- render: () => <Story text={str(text.image, text.footer)} readonly extensions={[image()]} />,
299
+ render: () => <Story text={str(text.image, text.footer)} extensions={[image()]} />,
298
300
  };
299
301
 
300
- export const Tasklist = {
302
+ export const Lists = {
301
303
  render: () => (
302
- <Story
303
- text={str(text.tasks, '', text.list, text.footer)}
304
- extensions={[
305
- tasklist(),
306
- listener({
307
- onChange: (text) => {
308
- console.log(text);
309
- },
310
- }),
311
- ]}
312
- />
304
+ <Story text={str(text.tasks, '', text.list, '', text.numbered, text.footer)} extensions={[tasklist()]} />
313
305
  ),
314
306
  };
315
307
 
308
+ export const Table = {
309
+ render: () => <Story text={str(text.table, text.footer)} extensions={[table()]} />,
310
+ };
311
+
312
+ // export const Outliner = {
313
+ // render: () => (
314
+ // <Story
315
+ // text={str('# Outliner', '', 'Block', ': this is a block', ': with multiple lines', text.footer)}
316
+ // extensions={[outliner()]}
317
+ // />
318
+ // ),
319
+ // };
320
+
316
321
  export const Autocomplete = {
317
322
  render: () => (
318
323
  <Story
319
- text={str('# Autocomplete', '', 'Press CTRL-SPACE', text.footer)}
324
+ text={str('# Autocomplete', '', 'Press Ctrl-Space...', text.footer)}
320
325
  extensions={[
321
326
  link({ onRender: onRenderLink }),
322
327
  autocomplete({
@@ -327,8 +332,6 @@ export const Autocomplete = {
327
332
  ),
328
333
  };
329
334
 
330
- const names = ['adam', 'alice', 'alison', 'bob', 'carol', 'charlie', 'sayuri', 'shoko'];
331
-
332
335
  export const Mention = {
333
336
  render: () => (
334
337
  <Story
@@ -342,24 +345,20 @@ export const Mention = {
342
345
  ),
343
346
  };
344
347
 
345
- export const Mermaid = {
346
- render: () => <Story text={str('# Mermaid', '', text.mermaid, text.footer)} extensions={[code(), mermaid()]} />,
347
- };
348
-
349
348
  export const Comments = {
350
349
  render: () => {
351
- const [commentsStates, setCommentStates] = useState<CommentRange[]>([]);
350
+ const [commentRanges, setCommentRanges] = useState<Comment[]>([]);
352
351
 
353
352
  return (
354
353
  <Story
355
354
  text={str('# Comments', '', text.paragraphs, text.footer)}
356
- comments={commentsStates}
355
+ comments={commentRanges}
357
356
  extensions={[
358
357
  comments({
359
358
  onHover: onCommentsHover,
360
- onCreate: (relPos) => {
359
+ onCreate: (range) => {
361
360
  const id = PublicKey.random().toHex();
362
- setCommentStates((comments) => [...comments, { id, cursor: relPos }]);
361
+ setCommentRanges((commentRanges) => [...commentRanges, { id, cursor: range }]);
363
362
  return id;
364
363
  },
365
364
  onSelect: (state) => {
@@ -368,9 +367,9 @@ export const Comments = {
368
367
  console.log(
369
368
  'update',
370
369
  JSON.stringify({
371
- active: state.active?.slice(0, 8),
372
- closest: state.closest?.slice(0, 8),
373
- ranges: state.ranges.length,
370
+ comments: state.comments.length,
371
+ active: state.selection.current?.slice(0, 8),
372
+ closest: state.selection.closest?.slice(0, 8),
374
373
  }),
375
374
  );
376
375
  }
@@ -382,8 +381,24 @@ export const Comments = {
382
381
  },
383
382
  };
384
383
 
384
+ export const HorizontalRule = {
385
+ render: () => (
386
+ <Story
387
+ text={str('# Horizontal Rule', '', text.paragraphs, '---', text.paragraphs, '---', text.paragraphs)}
388
+ extensions={[hr()]}
389
+ />
390
+ ),
391
+ };
392
+
393
+ const typewriterItems = localStorage.getItem('dxos.org/plugin/markdown/typewriter')?.split(',');
394
+
385
395
  export const Typewriter = {
386
- render: () => <Story text={str('# Typewriter', '', text.paragraphs, text.footer)} extensions={[typewriter()]} />,
396
+ render: () => (
397
+ <Story
398
+ text={str('# Typewriter', '', text.paragraphs, text.footer)}
399
+ extensions={[typewriter({ items: typewriterItems })]}
400
+ />
401
+ ),
387
402
  };
388
403
 
389
404
  export const Blast = {
@@ -391,9 +406,7 @@ export const Blast = {
391
406
  <Story
392
407
  text={str('# Blast', '', text.paragraphs, text.code, text.paragraphs)}
393
408
  extensions={[
394
- typewriter({
395
- items: localStorage.getItem('dxos.composer.extension.demo')?.split(','),
396
- }),
409
+ typewriter({ items: typewriterItems }),
397
410
  blast(
398
411
  defaultsDeep(
399
412
  {
@@ -410,17 +423,3 @@ export const Blast = {
410
423
  />
411
424
  ),
412
425
  };
413
-
414
- export const Diagnostics = {
415
- render: () => (
416
- <Story
417
- text={document}
418
- extensions={[
419
- // Cursor moved.
420
- EditorView.updateListener.of((update) => {
421
- console.log('update', update.view.state.selection.main.head);
422
- }),
423
- ]}
424
- />
425
- ),
426
- };
@@ -4,16 +4,15 @@
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';
13
+ import { TextEditor, type TextEditorProps } from './TextEditor';
14
+ import { listener } from '../../extensions';
15
15
  import { useTextModel } from '../../hooks';
16
- import { textTheme } from '../../themes';
17
16
 
18
17
  const initialText = [
19
18
  '# TextEditor',
@@ -29,8 +28,7 @@ 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);
31
+ }: { text?: string; automerge?: boolean } & Pick<TextEditorProps, 'extensions' | 'placeholder' | 'slots'>) => {
34
32
  const [item] = useState({ text: new TextObject(text, undefined, undefined, { automerge }) });
35
33
  const model = useTextModel({ text: item.text });
36
34
  if (!model) {
@@ -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
  };