@dxos/react-ui-editor 0.3.11-main.f89c150 → 0.3.11-main.fc97a54

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