@dxos/react-ui-editor 0.4.10-main.fa5a270 → 0.4.10-main.fd8ea31

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 (45) hide show
  1. package/dist/lib/browser/index.mjs +707 -694
  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/TextEditor.d.ts.map +1 -1
  5. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  7. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  8. package/dist/types/src/extensions/automerge/automerge.d.ts +1 -1
  9. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  10. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +1 -1
  11. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  12. package/dist/types/src/extensions/automerge/cursor.d.ts +2 -2
  13. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  14. package/dist/types/src/extensions/automerge/sync.d.ts +1 -1
  15. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
  16. package/dist/types/src/extensions/automerge/update-automerge.d.ts +1 -1
  17. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
  18. package/dist/types/src/extensions/factories.d.ts +2 -3
  19. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  20. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  21. package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
  22. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  23. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  24. package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
  25. package/dist/types/src/hooks/index.d.ts +0 -1
  26. package/dist/types/src/hooks/index.d.ts.map +1 -1
  27. package/package.json +30 -29
  28. package/src/components/TextEditor/TextEditor.stories.tsx +21 -18
  29. package/src/components/TextEditor/TextEditor.tsx +6 -3
  30. package/src/components/Toolbar/Toolbar.stories.tsx +10 -9
  31. package/src/extensions/automerge/automerge.stories.tsx +7 -6
  32. package/src/extensions/automerge/automerge.ts +1 -1
  33. package/src/extensions/automerge/cursor.ts +4 -37
  34. package/src/extensions/automerge/sync.ts +1 -1
  35. package/src/extensions/automerge/update-automerge.ts +1 -1
  36. package/src/extensions/factories.ts +3 -4
  37. package/src/extensions/markdown/decorate.ts +90 -62
  38. package/src/extensions/markdown/formatting.ts +42 -35
  39. package/src/extensions/markdown/highlight.ts +3 -1
  40. package/src/extensions/markdown/table.ts +7 -6
  41. package/src/hooks/index.ts +0 -1
  42. package/src/hooks/useTextEditor.ts +1 -1
  43. package/dist/types/src/hooks/useDocAccessor.d.ts +0 -9
  44. package/dist/types/src/hooks/useDocAccessor.d.ts.map +0 -1
  45. package/src/hooks/useDocAccessor.ts +0 -27
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-editor",
3
- "version": "0.4.10-main.fa5a270",
3
+ "version": "0.4.10-main.fd8ea31",
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",
@@ -39,23 +39,23 @@
39
39
  "lodash.sortby": "^4.7.0",
40
40
  "react-dropzone": "^14.2.3",
41
41
  "style-mod": "^4.1.0",
42
- "@dxos/automerge": "0.4.10-main.fa5a270",
43
- "@dxos/context": "0.4.10-main.fa5a270",
44
- "@dxos/async": "0.4.10-main.fa5a270",
45
- "@dxos/echo-schema": "0.4.10-main.fa5a270",
46
- "@dxos/debug": "0.4.10-main.fa5a270",
47
- "@dxos/display-name": "0.4.10-main.fa5a270",
48
- "@dxos/invariant": "0.4.10-main.fa5a270",
49
- "@dxos/log": "0.4.10-main.fa5a270",
50
- "@dxos/react-async": "0.4.10-main.fa5a270",
51
- "@dxos/react-ui": "0.4.10-main.fa5a270",
52
- "@dxos/react-ui-theme": "0.4.10-main.fa5a270",
53
- "@dxos/util": "0.4.10-main.fa5a270",
54
- "@dxos/protocols": "0.4.10-main.fa5a270"
42
+ "@dxos/context": "0.4.10-main.fd8ea31",
43
+ "@dxos/automerge": "0.4.10-main.fd8ea31",
44
+ "@dxos/async": "0.4.10-main.fd8ea31",
45
+ "@dxos/debug": "0.4.10-main.fd8ea31",
46
+ "@dxos/display-name": "0.4.10-main.fd8ea31",
47
+ "@dxos/invariant": "0.4.10-main.fd8ea31",
48
+ "@dxos/echo-schema": "0.4.10-main.fd8ea31",
49
+ "@dxos/log": "0.4.10-main.fd8ea31",
50
+ "@dxos/protocols": "0.4.10-main.fd8ea31",
51
+ "@dxos/react-async": "0.4.10-main.fd8ea31",
52
+ "@dxos/react-ui-theme": "0.4.10-main.fd8ea31",
53
+ "@dxos/util": "0.4.10-main.fd8ea31",
54
+ "@dxos/react-ui": "0.4.10-main.fd8ea31"
55
55
  },
56
56
  "devDependencies": {
57
- "@automerge/automerge-repo-network-broadcastchannel": "^1.1.1",
58
- "@phosphor-icons/react": "^2.0.5",
57
+ "@automerge/automerge-repo-network-broadcastchannel": "^1.1.4",
58
+ "@phosphor-icons/react": "^2.1.5",
59
59
  "@preact/signals-react": "^1.3.8",
60
60
  "@testing-library/dom": "^8.17.1",
61
61
  "@testing-library/react": "^13.4.0",
@@ -67,31 +67,32 @@
67
67
  "@types/react": "^18.0.21",
68
68
  "@types/react-dom": "^18.0.6",
69
69
  "@types/react-test-renderer": "^17.0.2",
70
- "@vitest/browser": "^1.3.1",
71
- "@vitest/ui": "^1.3.1",
70
+ "@vitest/browser": "^1.5.0",
71
+ "@vitest/ui": "^1.5.0",
72
72
  "happy-dom": "^13.3.1",
73
73
  "jsdom": "^20.0.1",
74
74
  "react": "^18.2.0",
75
75
  "react-dom": "^18.2.0",
76
76
  "react-test-renderer": "^18.2.0",
77
- "vite": "^5.1.5",
77
+ "vite": "^5.2.9",
78
78
  "vite-plugin-top-level-await": "^1.4.1",
79
79
  "vite-plugin-wasm": "^3.3.0",
80
- "vitest": "^1.3.1",
81
- "@dxos/config": "0.4.10-main.fa5a270",
82
- "@dxos/keyboard": "0.4.10-main.fa5a270",
83
- "@dxos/echo-signals": "0.4.10-main.fa5a270",
84
- "@dxos/echo-typegen": "0.4.10-main.fa5a270",
85
- "@dxos/random": "0.4.10-main.fa5a270",
86
- "@dxos/react-client": "0.4.10-main.fa5a270",
87
- "@dxos/react-ui": "0.4.10-main.fa5a270",
88
- "@dxos/storybook-utils": "0.4.10-main.fa5a270"
80
+ "vitest": "^1.5.0",
81
+ "@braneframe/types": "0.4.10-main.fd8ea31",
82
+ "@dxos/config": "0.4.10-main.fd8ea31",
83
+ "@dxos/echo-signals": "0.4.10-main.fd8ea31",
84
+ "@dxos/keyboard": "0.4.10-main.fd8ea31",
85
+ "@dxos/random": "0.4.10-main.fd8ea31",
86
+ "@dxos/echo-typegen": "0.4.10-main.fd8ea31",
87
+ "@dxos/react-client": "0.4.10-main.fd8ea31",
88
+ "@dxos/react-ui": "0.4.10-main.fd8ea31",
89
+ "@dxos/storybook-utils": "0.4.10-main.fd8ea31"
89
90
  },
90
91
  "peerDependencies": {
91
92
  "@phosphor-icons/react": "^2.0.5",
92
93
  "react": "^18.2.0",
93
94
  "react-dom": "^18.2.0",
94
- "@dxos/react-client": "0.4.10-main.fa5a270"
95
+ "@dxos/react-client": "0.4.10-main.fd8ea31"
95
96
  },
96
97
  "publishConfig": {
97
98
  "access": "public"
@@ -10,11 +10,13 @@ import defaultsDeep from 'lodash.defaultsdeep';
10
10
  import React, { type FC, type KeyboardEvent, StrictMode, useMemo, useRef, useState } from 'react';
11
11
  import { createRoot } from 'react-dom/client';
12
12
 
13
- import { TextObject } from '@dxos/echo-schema';
13
+ import { TextV0Type } from '@braneframe/types';
14
+ import { create } from '@dxos/echo-schema';
14
15
  import { keySymbols, parseShortcut } from '@dxos/keyboard';
15
16
  import { PublicKey } from '@dxos/keys';
16
17
  import { log } from '@dxos/log';
17
18
  import { faker } from '@dxos/random';
19
+ import { createDocAccessor, createEchoObject } from '@dxos/react-client/echo';
18
20
  import { Button, DensityProvider, Input, ThemeProvider, useThemeContext } from '@dxos/react-ui';
19
21
  import { baseSurface, defaultTx, getSize, mx, textBlockWidth } from '@dxos/react-ui-theme';
20
22
  import { withTheme } from '@dxos/storybook-utils';
@@ -49,7 +51,6 @@ import {
49
51
  type CommentsOptions,
50
52
  type SelectionState,
51
53
  } from '../../extensions';
52
- import { useDocAccessor } from '../../hooks';
53
54
  import translations from '../../translations';
54
55
 
55
56
  faker.seed(101);
@@ -65,11 +66,11 @@ const text = {
65
66
  //
66
67
  '## Tasks',
67
68
  '',
68
- '- [x] decorator',
69
- '- [ ] checkbox',
70
- ' - [ ] state',
71
- ' - [ ] indent',
72
- ' - [x] style',
69
+ `- [x] ${faker.lorem.sentences()}`,
70
+ `- [ ] ${faker.lorem.sentences()}`,
71
+ ` - [ ] ${faker.lorem.sentences()}`,
72
+ ` - [ ] ${faker.lorem.sentences()}`,
73
+ ` - [x] ${faker.lorem.sentences()}`,
73
74
  '',
74
75
  ),
75
76
 
@@ -77,9 +78,9 @@ const text = {
77
78
  //
78
79
  '## List',
79
80
  '',
80
- '- new york',
81
- '- london',
82
- '- tokyo',
81
+ `- ${faker.lorem.sentences()}`,
82
+ `- ${faker.lorem.sentences()}`,
83
+ `- ${faker.lorem.sentences()}`,
83
84
  '',
84
85
  ),
85
86
 
@@ -87,9 +88,9 @@ const text = {
87
88
  //
88
89
  '## Numbered',
89
90
  '',
90
- '1. one',
91
- '2. two',
92
- '3. three',
91
+ `1. ${faker.lorem.sentences()}`,
92
+ `2. ${faker.lorem.sentences()}`,
93
+ `3. ${faker.lorem.sentences()}`,
93
94
  '',
94
95
  ),
95
96
 
@@ -241,7 +242,7 @@ type StoryProps = {
241
242
  comments?: Comment[];
242
243
  readonly?: boolean;
243
244
  placeholder?: string;
244
- } & Pick<TextEditorProps, 'extensions'>;
245
+ } & Pick<TextEditorProps, 'selection' | 'extensions'>;
245
246
 
246
247
  const Story = ({
247
248
  id = 'editor-' + PublicKey.random().toHex().slice(0, 8),
@@ -252,7 +253,7 @@ const Story = ({
252
253
  placeholder = 'New document.',
253
254
  ...props
254
255
  }: StoryProps) => {
255
- const { accessor } = useDocAccessor(new TextObject(text));
256
+ const [object] = useState(createEchoObject(create(TextV0Type, { content: text ?? '' })));
256
257
 
257
258
  const viewRef = useRef<EditorView>(null);
258
259
  useComments(viewRef.current, id, comments);
@@ -268,10 +269,10 @@ const Story = ({
268
269
  editor: { className: 'min-bs-dvh px-8 bg-white dark:bg-black' },
269
270
  },
270
271
  }),
271
- createDataExtensions({ id, text: accessor }),
272
+ createDataExtensions({ id, text: createDocAccessor(object, ['content']) }),
272
273
  _extensions,
273
274
  ],
274
- [_extensions],
275
+ [_extensions, object],
275
276
  );
276
277
 
277
278
  return (
@@ -294,11 +295,13 @@ export default {
294
295
  parameters: { translations, layout: 'fullscreen' },
295
296
  };
296
297
 
298
+ // TODO(burdon): Test invalid inputs (e.g., selection).
299
+
297
300
  const defaults = [
298
301
  autocomplete({
299
302
  onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
300
303
  }),
301
- decorateMarkdown({ renderLinkButton }),
304
+ decorateMarkdown({ renderLinkButton, selectionChangeDelay: 100 }),
302
305
  formattingKeymap(),
303
306
  image(),
304
307
  table(),
@@ -16,6 +16,7 @@ import React, {
16
16
  } from 'react';
17
17
 
18
18
  import { log } from '@dxos/log';
19
+ import { useDefaultValue } from '@dxos/react-ui';
19
20
  import { isNotFalsy } from '@dxos/util';
20
21
 
21
22
  import { documentId, editorMode, focusEvent } from '../../extensions';
@@ -51,12 +52,13 @@ export const TextEditor = forwardRef<EditorView | null, TextEditorProps>(
51
52
  (
52
53
  {
53
54
  id,
55
+ // TODO(wittjosiah): Rename initialText?
54
56
  doc,
55
57
  selection,
56
58
  extensions,
57
59
  className,
58
60
  autoFocus,
59
- scrollTo = EditorView.scrollIntoView(0, { yMargin: 0 }),
61
+ scrollTo: propsScrollTo,
60
62
  moveToEndOfLine,
61
63
  debug,
62
64
  dataTestId,
@@ -65,6 +67,7 @@ export const TextEditor = forwardRef<EditorView | null, TextEditorProps>(
65
67
  ) => {
66
68
  // NOTE: Increments by 2 in strict mode.
67
69
  const [instanceId] = useState(() => `text-editor-${++instanceCount}`);
70
+ const scrollTo = useDefaultValue(propsScrollTo, EditorView.scrollIntoView(0, { yMargin: 0 }));
68
71
 
69
72
  // TODO(burdon): Make tabster optional.
70
73
  const tabsterDOMAttribute = useFocusableGroup({ tabBehavior: 'limited' });
@@ -90,10 +93,10 @@ export const TextEditor = forwardRef<EditorView | null, TextEditorProps>(
90
93
  //
91
94
  // EditorState
92
95
  // https://codemirror.net/docs/ref/#state.EditorStateConfig
96
+ // NOTE: Don't set selection here in case it is invalid (and crashes the state); dispatch below.
93
97
  //
94
98
  const state = EditorState.create({
95
99
  doc,
96
- selection,
97
100
  extensions: [
98
101
  id && documentId.of(id),
99
102
  // TODO(burdon): NOTE: Doesn't catch errors in keymap functions.
@@ -150,7 +153,7 @@ export const TextEditor = forwardRef<EditorView | null, TextEditorProps>(
150
153
  log('destroy', { id, instanceId });
151
154
  view?.destroy();
152
155
  };
153
- }, [doc, selection, extensions]);
156
+ }, [id, selection, scrollTo, editorMode, extensions]);
154
157
 
155
158
  // Focus editor on Enter (e.g., when tabbing to this component).
156
159
  const handleKeyUp = useCallback<KeyboardEventHandler<HTMLDivElement>>(
@@ -6,9 +6,11 @@ import '@dxosTheme';
6
6
 
7
7
  import React, { type FC, useState } from 'react';
8
8
 
9
- import { TextObject } from '@dxos/echo-schema';
9
+ import { TextV0Type } from '@braneframe/types';
10
+ import { create } from '@dxos/echo-schema';
10
11
  import { PublicKey } from '@dxos/keys';
11
12
  import { faker } from '@dxos/random';
13
+ import { createDocAccessor } from '@dxos/react-client/echo';
12
14
  import { Tooltip, useThemeContext } from '@dxos/react-ui';
13
15
  import { textBlockWidth } from '@dxos/react-ui-theme';
14
16
  import { withTheme } from '@dxos/storybook-utils';
@@ -28,26 +30,25 @@ import {
28
30
  useComments,
29
31
  useFormattingState,
30
32
  } from '../../extensions';
31
- import { useActionHandler, useDocAccessor, useTextEditor } from '../../hooks';
33
+ import { useActionHandler, useTextEditor } from '../../hooks';
32
34
  import translations from '../../translations';
33
35
 
34
36
  faker.seed(101);
35
37
 
36
38
  const Story: FC<{ content: string }> = ({ content }) => {
37
39
  const { themeMode } = useThemeContext();
38
- const [item] = useState({ text: new TextObject(content) });
39
- const { id, doc, accessor } = useDocAccessor(item.text);
40
+ const [text] = useState(create(TextV0Type, { content }));
40
41
  const [formattingState, formattingObserver] = useFormattingState();
41
42
  const { parentRef, view } = useTextEditor(() => {
42
43
  return {
43
- id,
44
- doc,
44
+ id: text.id,
45
+ doc: text.content,
45
46
  extensions: [
46
47
  formattingObserver,
47
48
  createBasicExtensions(),
48
49
  createMarkdownExtensions({ themeMode }),
49
50
  createThemeExtensions({ themeMode, slots: { editor: { className: 'p-2' } } }),
50
- createDataExtensions({ id, text: accessor }),
51
+ createDataExtensions({ id: text.id, text: createDocAccessor(text, ['content']) }),
51
52
  comments({
52
53
  onCreate: ({ cursor }) => {
53
54
  const id = PublicKey.random().toHex();
@@ -61,12 +62,12 @@ const Story: FC<{ content: string }> = ({ content }) => {
61
62
  table(),
62
63
  ],
63
64
  };
64
- }, [id, accessor, formattingObserver, themeMode]);
65
+ }, [text, formattingObserver, themeMode]);
65
66
 
66
67
  const handleAction = useActionHandler(view);
67
68
 
68
69
  const [_comments, setComments] = useState<Comment[]>([]);
69
- useComments(view, id, _comments);
70
+ useComments(view, text.id, _comments);
70
71
 
71
72
  return (
72
73
  <Tooltip.Provider>
@@ -8,10 +8,11 @@ import { BroadcastChannelNetworkAdapter } from '@automerge/automerge-repo-networ
8
8
  import '@preact/signals-react';
9
9
  import React, { useEffect, useMemo, useState } from 'react';
10
10
 
11
+ import { TextV0Type } from '@braneframe/types';
11
12
  import { Repo } from '@dxos/automerge/automerge-repo';
12
- import { createDocAccessor, Filter, DocAccessor } from '@dxos/echo-schema';
13
+ import { create, type Expando } from '@dxos/echo-schema';
13
14
  import { type PublicKey } from '@dxos/keys';
14
- import { Expando, TextObject, useSpace } from '@dxos/react-client/echo';
15
+ import { Filter, DocAccessor, createDocAccessor, useSpace } from '@dxos/react-client/echo';
15
16
  import { ClientRepeater } from '@dxos/react-client/testing';
16
17
  import { useThemeContext } from '@dxos/react-ui';
17
18
  import { withTheme } from '@dxos/storybook-utils';
@@ -97,9 +98,9 @@ const EchoStory = ({ spaceKey }: { spaceKey: PublicKey }) => {
97
98
  // const identity = useIdentity();
98
99
  const space = useSpace(spaceKey);
99
100
  const source = useMemo<DocAccessor | undefined>(() => {
100
- const { objects = [] } = space?.db.query(Filter.from({ type: 'test' })) ?? {};
101
+ const { objects = [] } = space?.db.query<Expando>(Filter.from({ type: 'test' })) ?? {};
101
102
  if (objects.length) {
102
- return createDocAccessor(objects[0].content);
103
+ return createDocAccessor(objects[0].content, ['content']);
103
104
  }
104
105
  }, [space]);
105
106
 
@@ -124,9 +125,9 @@ export const WithEcho = {
124
125
  createSpace
125
126
  onCreateSpace={async (space) => {
126
127
  space.db.add(
127
- new Expando({
128
+ create({
128
129
  type: 'test',
129
- content: new TextObject(initialContent),
130
+ content: create(TextV0Type, { content: initialContent }),
130
131
  }),
131
132
  );
132
133
  }}
@@ -8,7 +8,7 @@ import { StateField, type Extension } from '@codemirror/state';
8
8
  import { EditorView, ViewPlugin } from '@codemirror/view';
9
9
 
10
10
  import { next as A } from '@dxos/automerge/automerge';
11
- import { type DocAccessor } from '@dxos/echo-schema';
11
+ import { type DocAccessor } from '@dxos/react-client/echo';
12
12
 
13
13
  import { cursorConverter } from './cursor';
14
14
  import { updateHeadsEffect, isReconcile, type State } from './defs';
@@ -2,30 +2,16 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import get from 'lodash.get';
6
-
7
- import { next as A } from '@dxos/automerge/automerge';
8
- import { type DocAccessor } from '@dxos/echo-schema';
9
5
  import { log } from '@dxos/log';
6
+ import { toCursor, type DocAccessor, fromCursor } from '@dxos/react-client/echo';
10
7
 
11
8
  import { type CursorConverter } from '../cursor';
12
9
 
13
- export const cursorConverter = ({ handle, path }: DocAccessor): CursorConverter => ({
10
+ export const cursorConverter = (accessor: DocAccessor): CursorConverter => ({
14
11
  // TODO(burdon): Handle assoc to associate with a previous character.
15
12
  toCursor: (pos) => {
16
- const doc = handle.docSync();
17
- if (!doc) {
18
- return '';
19
- }
20
-
21
- const value = get(doc, path);
22
- if (typeof value === 'string' && value.length <= pos) {
23
- return 'end';
24
- }
25
-
26
13
  try {
27
- // NOTE: Slice is needed because getCursor mutates the array.
28
- return A.getCursor(doc, path.slice(), pos);
14
+ return toCursor(accessor, pos);
29
15
  } catch (err) {
30
16
  log.catch(err);
31
17
  return ''; // In case of invalid request (e.g., wrong document).
@@ -33,27 +19,8 @@ export const cursorConverter = ({ handle, path }: DocAccessor): CursorConverter
33
19
  },
34
20
 
35
21
  fromCursor: (cursor) => {
36
- if (cursor === '') {
37
- return 0;
38
- }
39
-
40
- const doc = handle.docSync();
41
- if (!doc) {
42
- return 0;
43
- }
44
-
45
- if (cursor === 'end') {
46
- const value = get(doc, path);
47
- if (typeof value === 'string') {
48
- return value.length;
49
- } else {
50
- return 0;
51
- }
52
- }
53
-
54
22
  try {
55
- // NOTE: Slice is needed because getCursor mutates the array.
56
- return A.getCursorPosition(doc, path.slice(), cursor);
23
+ return fromCursor(accessor, cursor);
57
24
  } catch (err) {
58
25
  log.catch(err);
59
26
  return 0; // In case of invalid request (e.g., wrong document).
@@ -8,7 +8,7 @@ import { type StateField } from '@codemirror/state';
8
8
  import { type EditorView } from '@codemirror/view';
9
9
 
10
10
  import { next as A } from '@dxos/automerge/automerge';
11
- import { type IDocHandle } from '@dxos/echo-schema';
11
+ import { type IDocHandle } from '@dxos/react-client/echo';
12
12
 
13
13
  import { getLastHeads, getPath, type State, reconcileAnnotation, updateHeads, isReconcile } from './defs';
14
14
  import { updateAutomerge } from './update-automerge';
@@ -7,7 +7,7 @@
7
7
  import { type EditorState, type StateField, type Transaction, type Text } from '@codemirror/state';
8
8
 
9
9
  import { next as A, type Heads } from '@dxos/automerge/automerge';
10
- import { type IDocHandle } from '@dxos/echo-schema';
10
+ import { type IDocHandle } from '@dxos/react-client/echo';
11
11
 
12
12
  import { type State } from './defs';
13
13
 
@@ -21,9 +21,8 @@ import {
21
21
  import defaultsDeep from 'lodash.defaultsdeep';
22
22
 
23
23
  import { generateName } from '@dxos/display-name';
24
- import { type DocAccessor } from '@dxos/echo-schema';
25
24
  import { log } from '@dxos/log';
26
- import { type Space } from '@dxos/react-client/echo';
25
+ import { type DocAccessor, type Space } from '@dxos/react-client/echo';
27
26
  import { type Identity } from '@dxos/react-client/halo';
28
27
  import { type ThemeMode } from '@dxos/react-ui';
29
28
  import { type HuePalette, hueTokens } from '@dxos/react-ui-theme';
@@ -162,14 +161,14 @@ export const createThemeExtensions = ({ theme, themeMode, slots: _slots }: Theme
162
161
 
163
162
  export type DataExtensionsProps = {
164
163
  id: string;
165
- text: DocAccessor;
164
+ text?: DocAccessor;
166
165
  space?: Space;
167
166
  identity?: Identity | null;
168
167
  };
169
168
 
170
169
  // TODO(burdon): Move out of react-ui-editor (remove echo deps).
171
170
  export const createDataExtensions = ({ id, text, space, identity }: DataExtensionsProps): Extension[] => {
172
- const extensions: Extension[] = [automerge(text)];
171
+ const extensions: Extension[] = text ? [automerge(text)] : [];
173
172
 
174
173
  if (space && identity) {
175
174
  const peerId = identity?.identityKey.toHex();