@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.
- package/dist/lib/browser/index.mjs +707 -694
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts +2 -2
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +2 -3
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +0 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/package.json +30 -29
- package/src/components/TextEditor/TextEditor.stories.tsx +21 -18
- package/src/components/TextEditor/TextEditor.tsx +6 -3
- package/src/components/Toolbar/Toolbar.stories.tsx +10 -9
- package/src/extensions/automerge/automerge.stories.tsx +7 -6
- package/src/extensions/automerge/automerge.ts +1 -1
- package/src/extensions/automerge/cursor.ts +4 -37
- package/src/extensions/automerge/sync.ts +1 -1
- package/src/extensions/automerge/update-automerge.ts +1 -1
- package/src/extensions/factories.ts +3 -4
- package/src/extensions/markdown/decorate.ts +90 -62
- package/src/extensions/markdown/formatting.ts +42 -35
- package/src/extensions/markdown/highlight.ts +3 -1
- package/src/extensions/markdown/table.ts +7 -6
- package/src/hooks/index.ts +0 -1
- package/src/hooks/useTextEditor.ts +1 -1
- package/dist/types/src/hooks/useDocAccessor.d.ts +0 -9
- package/dist/types/src/hooks/useDocAccessor.d.ts.map +0 -1
- 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.
|
|
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/
|
|
43
|
-
"@dxos/
|
|
44
|
-
"@dxos/async": "0.4.10-main.
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/log": "0.4.10-main.
|
|
50
|
-
"@dxos/
|
|
51
|
-
"@dxos/react-
|
|
52
|
-
"@dxos/react-ui-theme": "0.4.10-main.
|
|
53
|
-
"@dxos/util": "0.4.10-main.
|
|
54
|
-
"@dxos/
|
|
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.
|
|
58
|
-
"@phosphor-icons/react": "^2.
|
|
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.
|
|
71
|
-
"@vitest/ui": "^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.
|
|
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.
|
|
81
|
-
"@
|
|
82
|
-
"@dxos/
|
|
83
|
-
"@dxos/echo-signals": "0.4.10-main.
|
|
84
|
-
"@dxos/
|
|
85
|
-
"@dxos/random": "0.4.10-main.
|
|
86
|
-
"@dxos/
|
|
87
|
-
"@dxos/react-
|
|
88
|
-
"@dxos/
|
|
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.
|
|
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 {
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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 {
|
|
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:
|
|
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
|
|
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
|
-
}, [
|
|
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 {
|
|
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,
|
|
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 [
|
|
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:
|
|
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
|
-
}, [
|
|
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 {
|
|
13
|
+
import { create, type Expando } from '@dxos/echo-schema';
|
|
13
14
|
import { type PublicKey } from '@dxos/keys';
|
|
14
|
-
import {
|
|
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
|
-
|
|
128
|
+
create({
|
|
128
129
|
type: 'test',
|
|
129
|
-
content:
|
|
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
|
|
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 = (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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();
|