@dxos/react-ui-editor 0.3.11-main.68db74e → 0.3.11-main.6901f09
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 +2651 -1060
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +13 -15
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +14 -6
- 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/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/{yjs.stories.d.ts → hooks.stories.d.ts} +13 -2
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +29 -0
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +25 -0
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar/index.d.ts +2 -0
- package/dist/types/src/components/Toolbar/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.spec.d.ts +2 -0
- package/dist/types/src/extensions/automerge/automerge.spec.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts +2 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/defs.d.ts +9 -11
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/index.d.ts +0 -1
- package/dist/types/src/extensions/automerge/index.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/semaphore.d.ts +8 -12
- package/dist/types/src/extensions/automerge/semaphore.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +2 -2
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness.d.ts +2 -2
- package/dist/types/src/extensions/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/basic.d.ts +4 -5
- package/dist/types/src/extensions/basic.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +40 -19
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/cursor.d.ts +3 -3
- package/dist/types/src/extensions/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +1 -7
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +3 -6
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/code.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts +57 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts +3 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/heading.d.ts +6 -0
- package/dist/types/src/extensions/markdown/heading.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/hr.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts +8 -0
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/tasklist.d.ts +3 -0
- package/dist/types/src/extensions/markdown/tasklist.d.ts.map +1 -0
- package/dist/types/src/extensions/mention.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner.d.ts +4 -0
- package/dist/types/src/extensions/outliner.d.ts.map +1 -0
- package/dist/types/src/hooks/awareness-provider.d.ts +7 -4
- package/dist/types/src/hooks/awareness-provider.d.ts.map +1 -1
- package/dist/types/src/hooks/defs.d.ts +25 -0
- package/dist/types/src/hooks/defs.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +4 -2
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useActionHandler.d.ts +4 -0
- package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -0
- package/dist/types/src/hooks/useEditorView.d.ts +17 -0
- package/dist/types/src/hooks/useEditorView.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextEditor.d.ts +39 -0
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextModel.d.ts +14 -27
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/markdown.d.ts +2 -2
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +2 -0
- package/dist/types/src/util.d.ts.map +1 -1
- package/package.json +47 -37
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +75 -84
- package/src/components/TextEditor/TextEditor.tsx +111 -75
- package/src/components/TextEditor/automerge.stories.tsx +1 -2
- package/src/components/TextEditor/hooks.stories.tsx +111 -0
- package/src/components/Toolbar/Toolbar.stories.tsx +102 -0
- package/src/components/Toolbar/Toolbar.tsx +245 -0
- package/src/components/Toolbar/index.ts +5 -0
- package/src/components/index.ts +1 -0
- package/src/extensions/autocomplete.ts +6 -3
- package/src/extensions/automerge/automerge.spec.tsx +76 -0
- package/src/extensions/automerge/automerge.test.ts +13 -0
- package/src/extensions/automerge/automerge.ts +54 -45
- package/src/extensions/automerge/cursor.ts +3 -3
- package/src/extensions/automerge/defs.ts +13 -34
- package/src/extensions/automerge/index.ts +0 -1
- package/src/extensions/automerge/semaphore.ts +33 -32
- package/src/extensions/automerge/update-automerge.ts +14 -8
- package/src/extensions/automerge/update-codemirror.ts +5 -5
- package/src/extensions/awareness.ts +22 -18
- package/src/extensions/basic.ts +17 -10
- package/src/extensions/blast.ts +4 -1
- package/src/extensions/comments.ts +328 -167
- package/src/extensions/cursor.ts +7 -3
- package/src/extensions/index.ts +1 -7
- package/src/extensions/markdown/bundle.ts +23 -28
- package/src/extensions/markdown/code.ts +150 -0
- package/src/extensions/markdown/formatting.test.ts +481 -0
- package/src/extensions/markdown/formatting.ts +1198 -0
- package/src/extensions/markdown/heading.ts +59 -0
- package/src/extensions/markdown/highlight.ts +9 -15
- package/src/extensions/markdown/hr.ts +71 -0
- package/src/extensions/markdown/index.ts +8 -0
- package/src/extensions/{link.ts → markdown/link.ts} +16 -7
- package/src/extensions/{tasklist.ts → markdown/tasklist.ts} +48 -33
- package/src/extensions/mention.ts +9 -2
- package/src/extensions/outliner.ts +12 -0
- package/src/hooks/awareness-provider.ts +24 -20
- package/src/hooks/defs.ts +42 -0
- package/src/hooks/index.ts +5 -2
- package/src/hooks/useActionHandler.ts +93 -0
- package/src/hooks/useEditorView.ts +29 -0
- package/src/hooks/useTextEditor.ts +153 -0
- package/src/hooks/useTextModel.ts +66 -56
- package/src/index.ts +1 -1
- package/src/styles/markdown.ts +9 -10
- package/src/themes/default.ts +11 -8
- package/src/util.ts +26 -3
- package/dist/types/src/components/TextEditor/codemirror.stories.d.ts +0 -12
- package/dist/types/src/components/TextEditor/codemirror.stories.d.ts.map +0 -1
- package/dist/types/src/components/TextEditor/comments.stories.d.ts +0 -26
- package/dist/types/src/components/TextEditor/comments.stories.d.ts.map +0 -1
- package/dist/types/src/components/TextEditor/yjs.stories.d.ts.map +0 -1
- package/dist/types/src/extensions/code.d.ts.map +0 -1
- package/dist/types/src/extensions/hr.d.ts.map +0 -1
- package/dist/types/src/extensions/image.d.ts.map +0 -1
- package/dist/types/src/extensions/link.d.ts.map +0 -1
- package/dist/types/src/extensions/table.d.ts.map +0 -1
- package/dist/types/src/extensions/tasklist.d.ts +0 -7
- package/dist/types/src/extensions/tasklist.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/cursor.d.ts +0 -4
- package/dist/types/src/extensions/yjs/cursor.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/index.d.ts +0 -2
- package/dist/types/src/extensions/yjs/index.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/yjs.d.ts +0 -4
- package/dist/types/src/extensions/yjs/yjs.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/yjs.test.d.ts +0 -2
- package/dist/types/src/extensions/yjs/yjs.test.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge.d.ts +0 -3
- package/dist/types/src/hooks/automerge.d.ts.map +0 -1
- package/dist/types/src/hooks/yjs.d.ts +0 -27
- package/dist/types/src/hooks/yjs.d.ts.map +0 -1
- package/dist/types/src/testing/index.d.ts +0 -3
- package/dist/types/src/testing/index.d.ts.map +0 -1
- package/dist/types/src/testing/proto/gen/schema.d.ts +0 -15
- package/dist/types/src/testing/proto/gen/schema.d.ts.map +0 -1
- package/dist/types/src/testing/proto/index.d.ts +0 -2
- package/dist/types/src/testing/proto/index.d.ts.map +0 -1
- package/dist/types/src/testing/replicator.d.ts +0 -45
- package/dist/types/src/testing/replicator.d.ts.map +0 -1
- package/src/components/TextEditor/codemirror.stories.ts +0 -115
- package/src/components/TextEditor/comments.stories.tsx +0 -315
- package/src/components/TextEditor/yjs.stories.tsx +0 -56
- package/src/extensions/code.ts +0 -106
- package/src/extensions/hr.ts +0 -73
- package/src/extensions/yjs/cursor.ts +0 -22
- package/src/extensions/yjs/index.ts +0 -5
- package/src/extensions/yjs/yjs.test.ts +0 -35
- package/src/extensions/yjs/yjs.ts +0 -16
- package/src/hooks/automerge.ts +0 -52
- package/src/hooks/yjs.ts +0 -156
- package/src/testing/index.ts +0 -6
- package/src/testing/proto/gen/schema.ts +0 -49
- package/src/testing/proto/index.ts +0 -5
- package/src/testing/proto/schema.proto +0 -15
- package/src/testing/replicator.ts +0 -184
- /package/dist/types/src/extensions/{code.d.ts → markdown/code.d.ts} +0 -0
- /package/dist/types/src/extensions/{hr.d.ts → markdown/hr.d.ts} +0 -0
- /package/dist/types/src/extensions/{image.d.ts → markdown/image.d.ts} +0 -0
- /package/dist/types/src/extensions/{link.d.ts → markdown/link.d.ts} +0 -0
- /package/dist/types/src/extensions/{table.d.ts → markdown/table.d.ts} +0 -0
- /package/src/extensions/{image.ts → markdown/image.ts} +0 -0
- /package/src/extensions/{table.ts → markdown/table.ts} +0 -0
|
@@ -7,74 +7,75 @@
|
|
|
7
7
|
import { type StateField } from '@codemirror/state';
|
|
8
8
|
import { type EditorView } from '@codemirror/view';
|
|
9
9
|
|
|
10
|
-
import { next as
|
|
10
|
+
import { next as A } from '@dxos/automerge/automerge';
|
|
11
11
|
|
|
12
12
|
import {
|
|
13
13
|
getLastHeads,
|
|
14
14
|
getPath,
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
isReconcile,
|
|
16
|
+
reconcileAnnotation,
|
|
17
17
|
updateHeads,
|
|
18
18
|
type IDocHandle,
|
|
19
|
-
type
|
|
19
|
+
type State,
|
|
20
20
|
} from './defs';
|
|
21
21
|
import { updateAutomerge } from './update-automerge';
|
|
22
22
|
import { updateCodeMirror } from './update-codemirror';
|
|
23
23
|
|
|
24
|
-
type Doc<T> = automerge.Doc<T>;
|
|
25
|
-
type Heads = automerge.Heads;
|
|
26
|
-
|
|
27
|
-
type ChangeFn = (atHeads: Heads, change: (doc: Doc<unknown>) => void) => Heads | undefined;
|
|
28
|
-
|
|
29
24
|
/**
|
|
30
|
-
*
|
|
25
|
+
* Implements three-way merge (on each mutation).
|
|
31
26
|
*/
|
|
32
27
|
export class PatchSemaphore {
|
|
33
|
-
_inReconcile = false;
|
|
34
|
-
_queue: Array<ChangeFn> = [];
|
|
28
|
+
private _inReconcile = false;
|
|
35
29
|
|
|
36
|
-
|
|
30
|
+
// prettier-ignore
|
|
31
|
+
constructor(
|
|
32
|
+
private readonly _handle: IDocHandle,
|
|
33
|
+
private readonly _state: StateField<State>
|
|
34
|
+
) {}
|
|
37
35
|
|
|
38
|
-
reconcile
|
|
39
|
-
if (this._inReconcile) {
|
|
40
|
-
|
|
36
|
+
reconcile(view: EditorView) {
|
|
37
|
+
if (!this._inReconcile) {
|
|
38
|
+
this._inReconcile = true;
|
|
39
|
+
this.doReconcile(view);
|
|
40
|
+
this._inReconcile = false;
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private doReconcile(view: EditorView) {
|
|
45
|
+
const path = getPath(view.state, this._state);
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
const oldHeads = getLastHeads(view.state, this.
|
|
47
|
+
// Get the heads before the unreconciled transactions are applied.
|
|
48
|
+
const oldHeads = getLastHeads(view.state, this._state);
|
|
46
49
|
let selection = view.state.selection;
|
|
47
50
|
|
|
48
51
|
// First undo all the unreconciled transactions.
|
|
49
|
-
const transactions = view.state.field(this.
|
|
52
|
+
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
50
53
|
const toInvert = transactions.slice().reverse();
|
|
51
|
-
for (const
|
|
52
|
-
const inverted =
|
|
54
|
+
for (const tr of toInvert) {
|
|
55
|
+
const inverted = tr.changes.invert(tr.startState.doc);
|
|
53
56
|
selection = selection.map(inverted);
|
|
54
57
|
view.dispatch({
|
|
55
58
|
changes: inverted,
|
|
56
|
-
annotations:
|
|
59
|
+
annotations: reconcileAnnotation.of(true),
|
|
57
60
|
});
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
// Apply the unreconciled transactions to the document.
|
|
61
|
-
let newHeads = updateAutomerge(this._field, handle, transactions, view.state);
|
|
62
|
-
|
|
63
64
|
// NOTE: null and undefined each come from automerge and repo respectively.
|
|
65
|
+
let newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
64
66
|
if (newHeads === null || newHeads === undefined) {
|
|
65
|
-
// TODO:
|
|
66
|
-
newHeads =
|
|
67
|
+
// TODO(alexjg): this is the call that's resetting the editor state on click.
|
|
68
|
+
newHeads = A.getHeads(this._handle.docSync()!);
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
// Now get the diff between the updated state of the document and the heads and apply that to the codemirror doc.
|
|
70
|
-
const diff =
|
|
72
|
+
const diff = A.equals(oldHeads, newHeads) ? [] : A.diff(this._handle.docSync()!, oldHeads, newHeads);
|
|
71
73
|
updateCodeMirror(view, selection, path, diff);
|
|
72
74
|
|
|
75
|
+
// Update automerge state.
|
|
73
76
|
view.dispatch({
|
|
74
77
|
effects: updateHeads(newHeads),
|
|
75
|
-
annotations:
|
|
78
|
+
annotations: reconcileAnnotation.of(false),
|
|
76
79
|
});
|
|
77
|
-
|
|
78
|
-
this._inReconcile = false;
|
|
79
|
-
};
|
|
80
|
+
}
|
|
80
81
|
}
|
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
// Ref: https://github.com/automerge/automerge-codemirror
|
|
5
5
|
//
|
|
6
6
|
|
|
7
|
-
import { type EditorState, type StateField, type
|
|
7
|
+
import { type EditorState, type StateField, type Transaction, type Text } from '@codemirror/state';
|
|
8
8
|
|
|
9
|
-
import { next as
|
|
9
|
+
import { next as A, type Heads } from '@dxos/automerge/automerge';
|
|
10
10
|
|
|
11
|
-
import { type IDocHandle, type
|
|
11
|
+
import { type IDocHandle, type State } from './defs';
|
|
12
12
|
|
|
13
13
|
export const updateAutomerge = (
|
|
14
|
-
field: StateField<
|
|
14
|
+
field: StateField<State>,
|
|
15
15
|
handle: IDocHandle,
|
|
16
16
|
transactions: Transaction[],
|
|
17
|
-
state: EditorState,
|
|
17
|
+
state: EditorState, // TODO(burdon): Just pass in the state field value?
|
|
18
18
|
): Heads | undefined => {
|
|
19
19
|
const { lastHeads, path } = state.field(field);
|
|
20
20
|
|
|
@@ -31,12 +31,18 @@ export const updateAutomerge = (
|
|
|
31
31
|
return undefined;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const newHeads = handle.changeAt(lastHeads, (doc:
|
|
34
|
+
const newHeads = handle.changeAt(lastHeads, (doc: A.Doc<unknown>) => {
|
|
35
|
+
const invertedTransactions: { from: number; del: number; insert: Text }[] = [];
|
|
35
36
|
for (const tr of transactions) {
|
|
36
|
-
tr.changes.iterChanges((fromA
|
|
37
|
-
|
|
37
|
+
tr.changes.iterChanges((fromA, toA, _fromB, _toB, insert) => {
|
|
38
|
+
invertedTransactions.push({ from: fromA, del: toA - fromA, insert });
|
|
38
39
|
});
|
|
39
40
|
}
|
|
41
|
+
|
|
42
|
+
// TODO(burdon): Hack to apply in reverse order to properly apply range.
|
|
43
|
+
invertedTransactions.reverse().forEach(({ from, del, insert }) => {
|
|
44
|
+
A.splice(doc, path.slice(), from, del, insert.toString());
|
|
45
|
+
});
|
|
40
46
|
});
|
|
41
47
|
|
|
42
48
|
return newHeads ?? undefined;
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
type SpliceTextPatch,
|
|
17
17
|
} from '@dxos/automerge/automerge';
|
|
18
18
|
|
|
19
|
-
import {
|
|
19
|
+
import { reconcileAnnotation } from './defs';
|
|
20
20
|
|
|
21
21
|
export const updateCodeMirror = (view: EditorView, selection: EditorSelection, target: Prop[], patches: Patch[]) => {
|
|
22
22
|
for (const patch of patches) {
|
|
@@ -26,14 +26,14 @@ export const updateCodeMirror = (view: EditorView, selection: EditorSelection, t
|
|
|
26
26
|
selection = selection.map(changeSet, 1);
|
|
27
27
|
view.dispatch({
|
|
28
28
|
changes: changeSet,
|
|
29
|
-
annotations:
|
|
29
|
+
annotations: reconcileAnnotation.of(false),
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
view.dispatch({
|
|
35
35
|
selection,
|
|
36
|
-
annotations:
|
|
36
|
+
annotations: reconcileAnnotation.of(false),
|
|
37
37
|
});
|
|
38
38
|
};
|
|
39
39
|
|
|
@@ -57,7 +57,7 @@ const handleInsert = (target: Prop[], patch: InsertPatch): Array<ChangeSpec> =>
|
|
|
57
57
|
return [];
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
const text = patch.values.map((
|
|
60
|
+
const text = patch.values.map((value) => (value ? value.toString() : '')).join('');
|
|
61
61
|
return [{ from: index, to: index, insert: text }];
|
|
62
62
|
};
|
|
63
63
|
|
|
@@ -88,7 +88,7 @@ const handlePut = (target: Prop[], patch: PutPatch, state: EditorState): Array<C
|
|
|
88
88
|
|
|
89
89
|
const length = state.doc.length;
|
|
90
90
|
if (typeof patch.value !== 'string') {
|
|
91
|
-
return []; // TODO(dmaretskyi): How to handle non
|
|
91
|
+
return []; // TODO(dmaretskyi): How to handle non-string values?
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
return [{ from: 0, to: length, insert: patch.value as any }];
|
|
@@ -24,8 +24,8 @@ export interface AwarenessProvider {
|
|
|
24
24
|
open(): void;
|
|
25
25
|
close(): void;
|
|
26
26
|
|
|
27
|
-
update(position: AwarenessPosition | undefined): void;
|
|
28
27
|
getRemoteStates(): AwarenessState[];
|
|
28
|
+
update(position: AwarenessPosition | undefined): void;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
const dummyProvider: AwarenessProvider = {
|
|
@@ -34,11 +34,11 @@ const dummyProvider: AwarenessProvider = {
|
|
|
34
34
|
open: () => {},
|
|
35
35
|
close: () => {},
|
|
36
36
|
|
|
37
|
-
update: () => {},
|
|
38
37
|
getRemoteStates: () => [],
|
|
38
|
+
update: () => {},
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
export const
|
|
41
|
+
export const awarenessProvider = Facet.define<AwarenessProvider, AwarenessProvider>({
|
|
42
42
|
combine: (providers) => providers[0] ?? dummyProvider,
|
|
43
43
|
});
|
|
44
44
|
|
|
@@ -66,10 +66,9 @@ export type AwarenessState = {
|
|
|
66
66
|
/**
|
|
67
67
|
* Extension provides presence information about other peers.
|
|
68
68
|
*/
|
|
69
|
-
// TODO(burdon): Why provide default?
|
|
70
69
|
export const awareness = (provider = dummyProvider): Extension => {
|
|
71
70
|
return [
|
|
72
|
-
|
|
71
|
+
awarenessProvider.of(provider),
|
|
73
72
|
ViewPlugin.fromClass(RemoteSelectionsDecorator, {
|
|
74
73
|
decorations: (value) => value.decorations,
|
|
75
74
|
}),
|
|
@@ -92,7 +91,7 @@ export class RemoteSelectionsDecorator implements PluginValue {
|
|
|
92
91
|
|
|
93
92
|
constructor(view: EditorView) {
|
|
94
93
|
this._cursorConverter = view.state.facet(Cursor.converter);
|
|
95
|
-
this._provider = view.state.facet(
|
|
94
|
+
this._provider = view.state.facet(awarenessProvider);
|
|
96
95
|
this._provider.open();
|
|
97
96
|
this._provider.remoteStateChange.on(this._ctx, () => {
|
|
98
97
|
view.dispatch({ annotations: [RemoteSelectionChangedAnnotation.of([])] });
|
|
@@ -208,7 +207,10 @@ export class RemoteSelectionsDecorator implements PluginValue {
|
|
|
208
207
|
}
|
|
209
208
|
|
|
210
209
|
class RemoteCaretWidget extends WidgetType {
|
|
211
|
-
constructor(
|
|
210
|
+
constructor(
|
|
211
|
+
private readonly _name: string,
|
|
212
|
+
private readonly _color: string,
|
|
213
|
+
) {
|
|
212
214
|
super();
|
|
213
215
|
}
|
|
214
216
|
|
|
@@ -265,39 +267,41 @@ const styles = EditorView.baseTheme({
|
|
|
265
267
|
marginRight: '-1px',
|
|
266
268
|
boxSizing: 'border-box',
|
|
267
269
|
display: 'inline',
|
|
270
|
+
cursor: 'pointer',
|
|
268
271
|
},
|
|
269
272
|
'.cm-collab-selectionCaretDot': {
|
|
270
273
|
borderRadius: '50%',
|
|
271
274
|
position: 'absolute',
|
|
272
|
-
width: '.
|
|
273
|
-
height: '.
|
|
274
|
-
top: '-.
|
|
275
|
-
left: '-.
|
|
275
|
+
width: '.5em',
|
|
276
|
+
height: '.5em',
|
|
277
|
+
top: '-.25em',
|
|
278
|
+
left: '-.25em',
|
|
276
279
|
backgroundColor: 'inherit',
|
|
277
280
|
transition: 'transform .3s ease-in-out',
|
|
278
281
|
boxSizing: 'border-box',
|
|
279
282
|
},
|
|
280
283
|
'.cm-collab-selectionCaret:hover > .cm-collab-selectionCaretDot': {
|
|
281
|
-
transformOrigin: 'bottom center',
|
|
282
284
|
transform: 'scale(0)',
|
|
285
|
+
transformOrigin: 'center',
|
|
283
286
|
},
|
|
284
287
|
'.cm-collab-selectionInfo': {
|
|
285
288
|
position: 'absolute',
|
|
286
|
-
|
|
287
|
-
|
|
289
|
+
transform: 'translate(-50%, 0)',
|
|
290
|
+
top: '-20px',
|
|
291
|
+
left: 0,
|
|
288
292
|
fontSize: '.75em',
|
|
289
|
-
fontFamily: 'serif',
|
|
293
|
+
fontFamily: 'sans-serif',
|
|
290
294
|
fontStyle: 'normal',
|
|
291
295
|
fontWeight: 'normal',
|
|
292
296
|
lineHeight: 'normal',
|
|
293
297
|
userSelect: 'none',
|
|
294
298
|
color: 'white',
|
|
295
|
-
|
|
296
|
-
paddingRight: '2px',
|
|
299
|
+
padding: '2px',
|
|
297
300
|
zIndex: 101,
|
|
298
301
|
transition: 'opacity .3s ease-in-out',
|
|
299
302
|
backgroundColor: 'inherit',
|
|
300
|
-
|
|
303
|
+
borderRadius: '2px',
|
|
304
|
+
// These should be separate.
|
|
301
305
|
opacity: 0,
|
|
302
306
|
transitionDelay: '0s',
|
|
303
307
|
whiteSpace: 'nowrap',
|
package/src/extensions/basic.ts
CHANGED
|
@@ -3,30 +3,37 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { closeBrackets } from '@codemirror/autocomplete';
|
|
6
|
+
import { history } from '@codemirror/commands';
|
|
6
7
|
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language';
|
|
7
8
|
import { type Extension } from '@codemirror/state';
|
|
8
9
|
import { oneDarkHighlightStyle } from '@codemirror/theme-one-dark';
|
|
9
|
-
import { drawSelection, EditorView, placeholder } from '@codemirror/view';
|
|
10
|
+
import { drawSelection, EditorView, highlightActiveLine, placeholder } from '@codemirror/view';
|
|
10
11
|
|
|
11
|
-
import type
|
|
12
|
+
import { type ThemeMode } from '@dxos/react-ui';
|
|
13
|
+
import { isNotFalsy } from '@dxos/util';
|
|
14
|
+
|
|
15
|
+
import { type TextEditorProps } from '../components';
|
|
12
16
|
|
|
13
17
|
export type BasicBundleOptions = {
|
|
14
|
-
readonly?: boolean;
|
|
15
18
|
themeMode?: ThemeMode;
|
|
16
|
-
|
|
17
|
-
};
|
|
19
|
+
} & Pick<TextEditorProps, 'placeholder' | 'lineWrapping'>;
|
|
18
20
|
|
|
19
|
-
export const
|
|
21
|
+
export const createBasicBundle = ({
|
|
22
|
+
themeMode,
|
|
23
|
+
placeholder: _placeholder,
|
|
24
|
+
lineWrapping = true,
|
|
25
|
+
}: BasicBundleOptions = {}): Extension[] =>
|
|
20
26
|
[
|
|
21
|
-
EditorView.lineWrapping,
|
|
27
|
+
lineWrapping && EditorView.lineWrapping,
|
|
22
28
|
|
|
23
|
-
// TODO(burdon): Compare with minimalSetup.
|
|
24
29
|
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
25
30
|
bracketMatching(),
|
|
26
31
|
closeBrackets(),
|
|
27
32
|
drawSelection(),
|
|
33
|
+
highlightActiveLine(),
|
|
34
|
+
history(),
|
|
28
35
|
_placeholder && placeholder(_placeholder),
|
|
29
36
|
|
|
30
|
-
//
|
|
37
|
+
// https://github.com/codemirror/theme-one-dark
|
|
31
38
|
themeMode === 'dark' ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
|
|
32
|
-
].filter(
|
|
39
|
+
].filter(isNotFalsy);
|
package/src/extensions/blast.ts
CHANGED
|
@@ -125,7 +125,10 @@ class Blaster {
|
|
|
125
125
|
|
|
126
126
|
_lastPoint = { x: 0, y: 0 };
|
|
127
127
|
|
|
128
|
-
constructor(
|
|
128
|
+
constructor(
|
|
129
|
+
private readonly _node: HTMLElement,
|
|
130
|
+
private readonly _options: BlastOptions,
|
|
131
|
+
) {
|
|
129
132
|
this._effect = this._options.effect === 1 ? new Effect1(_options) : new Effect2(_options);
|
|
130
133
|
}
|
|
131
134
|
|