@dxos/react-ui-editor 0.8.2-staging.7ac8446 → 0.8.3-main.672df60
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 +4505 -3151
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +6 -0
- package/dist/lib/browser/testing/index.mjs.map +7 -0
- package/dist/lib/node/index.cjs +3360 -1998
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +29 -0
- package/dist/lib/node/testing/index.cjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +4505 -3151
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +8 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +1 -1
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/blocks.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/formatting.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/headings.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/{comment.d.ts → image.d.ts} +4 -5
- package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/index.d.ts +1 -1
- package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/lists.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/search.d.ts +17 -0
- package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/util.d.ts +17 -25
- package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/{viewMode.d.ts → view-mode.d.ts} +5 -4
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -0
- package/dist/types/src/components/Popover/RefDropdownMenu.d.ts +21 -0
- package/dist/types/src/components/Popover/RefDropdownMenu.d.ts.map +1 -0
- package/dist/types/src/components/Popover/RefPopover.d.ts +21 -0
- package/dist/types/src/components/Popover/RefPopover.d.ts.map +1 -0
- package/dist/types/src/components/Popover/index.d.ts +3 -0
- package/dist/types/src/components/Popover/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/defaults.d.ts +3 -5
- package/dist/types/src/defaults.d.ts.map +1 -1
- package/dist/types/src/extensions/annotations.d.ts +4 -1
- package/dist/types/src/extensions/annotations.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete.d.ts +1 -2
- 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.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts.map +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/automerge/update-codemirror.d.ts +1 -1
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/blast.d.ts.map +1 -1
- package/dist/types/src/extensions/command/action.d.ts +17 -0
- package/dist/types/src/extensions/command/action.d.ts.map +1 -0
- package/dist/types/src/extensions/command/command.d.ts +4 -10
- package/dist/types/src/extensions/command/command.d.ts.map +1 -1
- package/dist/types/src/extensions/command/hint.d.ts +18 -4
- package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
- package/dist/types/src/extensions/command/index.d.ts +3 -0
- package/dist/types/src/extensions/command/index.d.ts.map +1 -1
- package/dist/types/src/extensions/command/menu.d.ts +6 -11
- package/dist/types/src/extensions/command/menu.d.ts.map +1 -1
- package/dist/types/src/extensions/command/state.d.ts +9 -11
- package/dist/types/src/extensions/command/state.d.ts.map +1 -1
- package/dist/types/src/extensions/command/typeahead.d.ts +17 -0
- package/dist/types/src/extensions/command/typeahead.d.ts.map +1 -0
- package/dist/types/src/extensions/comments.d.ts +9 -17
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +4 -0
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/hashtag.d.ts +3 -0
- package/dist/types/src/extensions/hashtag.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +4 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts +7 -0
- package/dist/types/src/extensions/json.d.ts.map +1 -0
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/{editorAction.d.ts → action.d.ts} +1 -1
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts +2 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/debug.d.ts +2 -2
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts +5 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts +3 -3
- 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/image.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts +4 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
- package/dist/types/src/extensions/mention.d.ts.map +1 -1
- package/dist/types/src/extensions/modes.d.ts +5 -5
- package/dist/types/src/extensions/modes.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/commands.d.ts +10 -0
- package/dist/types/src/extensions/outliner/commands.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.d.ts +5 -0
- package/dist/types/src/extensions/outliner/editor.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/index.d.ts +4 -0
- package/dist/types/src/extensions/outliner/index.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts +11 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/selection.d.ts +12 -0
- package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.d.ts +79 -0
- package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/index.d.ts +2 -0
- package/dist/types/src/extensions/preview/index.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/preview.d.ts +39 -0
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -0
- package/dist/types/src/extensions/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/typewriter.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/dist/types/src/hooks/useTextEditor.d.ts +2 -1
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/stories/Command.stories.d.ts +7 -0
- package/dist/types/src/stories/Command.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Comments.stories.d.ts +13 -0
- package/dist/types/src/stories/Comments.stories.d.ts.map +1 -0
- package/dist/types/src/stories/EditorToolbar.stories.d.ts +12 -0
- package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Experimental.stories.d.ts +16 -0
- package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Markdown.stories.d.ts +46 -0
- package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Outliner.stories.d.ts +26 -0
- package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Preview.stories.d.ts +10 -0
- package/dist/types/src/stories/Preview.stories.d.ts.map +1 -0
- package/dist/types/src/stories/TextEditor.stories.d.ts +55 -0
- package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -0
- package/dist/types/src/stories/components/EditorStory.d.ts +43 -0
- package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -0
- package/dist/types/src/stories/components/index.d.ts +3 -0
- package/dist/types/src/stories/components/index.d.ts.map +1 -0
- package/dist/types/src/stories/components/util.d.ts +38 -0
- package/dist/types/src/stories/components/util.d.ts.map +1 -0
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/styles/tokens.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/util.d.ts +2 -0
- package/dist/types/src/testing/util.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +5 -0
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util/cursor.d.ts.map +1 -1
- package/dist/types/src/util/debug.d.ts.map +1 -1
- package/dist/types/src/util/dom.d.ts.map +1 -1
- package/dist/types/src/util/facet.d.ts.map +1 -1
- package/dist/types/src/util/react.d.ts +6 -1
- package/dist/types/src/util/react.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +47 -30
- package/src/components/EditorToolbar/EditorToolbar.tsx +95 -72
- package/src/components/EditorToolbar/blocks.ts +27 -6
- package/src/components/EditorToolbar/formatting.ts +34 -7
- package/src/components/EditorToolbar/headings.ts +9 -8
- package/src/components/EditorToolbar/image.ts +16 -0
- package/src/components/EditorToolbar/index.ts +7 -1
- package/src/components/EditorToolbar/lists.ts +26 -7
- package/src/components/EditorToolbar/search.ts +19 -0
- package/src/components/EditorToolbar/util.ts +19 -20
- package/src/components/EditorToolbar/{viewMode.ts → view-mode.ts} +9 -8
- package/src/components/Popover/RefDropdownMenu.tsx +77 -0
- package/src/components/Popover/RefPopover.tsx +75 -0
- package/src/components/Popover/index.ts +6 -0
- package/src/components/index.ts +1 -0
- package/src/defaults.ts +12 -13
- package/src/extensions/annotations.ts +41 -64
- package/src/extensions/autocomplete.ts +5 -6
- package/src/extensions/automerge/automerge.stories.tsx +13 -24
- package/src/extensions/automerge/automerge.test.tsx +6 -5
- package/src/extensions/automerge/automerge.ts +2 -2
- package/src/extensions/automerge/defs.ts +1 -2
- package/src/extensions/automerge/sync.ts +7 -7
- package/src/extensions/automerge/update-automerge.ts +1 -1
- package/src/extensions/automerge/update-codemirror.ts +3 -4
- package/src/extensions/awareness/awareness-provider.ts +4 -4
- package/src/extensions/awareness/awareness.ts +7 -7
- package/src/extensions/blast.ts +9 -9
- package/src/extensions/command/action.ts +49 -0
- package/src/extensions/command/command.ts +7 -27
- package/src/extensions/command/hint.ts +36 -33
- package/src/extensions/command/index.ts +3 -0
- package/src/extensions/command/menu.ts +91 -54
- package/src/extensions/command/state.ts +41 -61
- package/src/extensions/command/typeahead.ts +116 -0
- package/src/extensions/comments.ts +11 -76
- package/src/extensions/factories.ts +13 -0
- package/src/extensions/folding.tsx +1 -1
- package/src/extensions/hashtag.tsx +68 -0
- package/src/extensions/index.ts +4 -0
- package/src/extensions/json.ts +57 -0
- package/src/extensions/markdown/bundle.ts +13 -9
- package/src/extensions/markdown/changes.ts +3 -2
- package/src/extensions/markdown/debug.ts +2 -2
- package/src/extensions/markdown/decorate.ts +19 -17
- package/src/extensions/markdown/formatting.ts +6 -6
- package/src/extensions/markdown/image.ts +14 -13
- package/src/extensions/markdown/index.ts +1 -1
- package/src/extensions/markdown/link.ts +33 -24
- package/src/extensions/markdown/styles.ts +4 -3
- package/src/extensions/markdown/table.ts +3 -3
- package/src/extensions/modes.ts +5 -6
- package/src/extensions/outliner/commands.ts +270 -0
- package/src/extensions/outliner/editor.test.ts +33 -0
- package/src/extensions/outliner/editor.ts +184 -0
- package/src/extensions/outliner/index.ts +7 -0
- package/src/extensions/outliner/outliner.test.ts +99 -0
- package/src/extensions/outliner/outliner.ts +169 -0
- package/src/extensions/outliner/selection.ts +50 -0
- package/src/extensions/outliner/tree.test.ts +164 -0
- package/src/extensions/outliner/tree.ts +315 -0
- package/src/extensions/preview/index.ts +5 -0
- package/src/extensions/preview/preview.ts +271 -0
- package/src/hooks/index.ts +0 -1
- package/src/hooks/useTextEditor.ts +4 -3
- package/src/stories/Command.stories.tsx +97 -0
- package/src/stories/Comments.stories.tsx +98 -0
- package/src/stories/EditorToolbar.stories.tsx +96 -0
- package/src/stories/Experimental.stories.tsx +86 -0
- package/src/stories/Markdown.stories.tsx +121 -0
- package/src/stories/Outliner.stories.tsx +120 -0
- package/src/stories/Preview.stories.tsx +149 -0
- package/src/stories/TextEditor.stories.tsx +256 -0
- package/src/stories/components/EditorStory.tsx +135 -0
- package/src/stories/components/index.ts +6 -0
- package/src/stories/components/util.tsx +231 -0
- package/src/styles/theme.ts +15 -5
- package/src/styles/tokens.ts +1 -2
- package/src/testing/index.ts +5 -0
- package/src/testing/util.ts +5 -0
- package/src/types.ts +7 -0
- package/src/util/react.tsx +20 -2
- package/dist/types/src/InputMode.stories.d.ts +0 -57
- package/dist/types/src/InputMode.stories.d.ts.map +0 -1
- package/dist/types/src/TextEditor.stories.d.ts +0 -115
- package/dist/types/src/TextEditor.stories.d.ts.map +0 -1
- package/dist/types/src/components/EditorToolbar/comment.d.ts.map +0 -1
- package/dist/types/src/components/EditorToolbar/viewMode.d.ts.map +0 -1
- package/dist/types/src/extensions/command/preview.d.ts +0 -12
- package/dist/types/src/extensions/command/preview.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/editorAction.d.ts.map +0 -1
- package/dist/types/src/fragments.d.ts +0 -3
- package/dist/types/src/fragments.d.ts.map +0 -1
- package/dist/types/src/hooks/useActionHandler.d.ts +0 -4
- package/dist/types/src/hooks/useActionHandler.d.ts.map +0 -1
- package/src/InputMode.stories.tsx +0 -124
- package/src/TextEditor.stories.tsx +0 -856
- package/src/components/EditorToolbar/comment.ts +0 -23
- package/src/extensions/command/preview.ts +0 -79
- package/src/fragments.ts +0 -19
- package/src/hooks/useActionHandler.ts +0 -12
- /package/src/extensions/markdown/{editorAction.ts → action.ts} +0 -0
@@ -4,10 +4,10 @@
|
|
4
4
|
// Ref: https://github.com/automerge/automerge-codemirror
|
5
5
|
//
|
6
6
|
|
7
|
+
import { next as A } from '@automerge/automerge';
|
7
8
|
import { type StateField } from '@codemirror/state';
|
8
9
|
import { type EditorView } from '@codemirror/view';
|
9
10
|
|
10
|
-
import { next as A } from '@dxos/automerge/automerge';
|
11
11
|
import { type IDocHandle } from '@dxos/react-client/echo';
|
12
12
|
|
13
13
|
import { getLastHeads, getPath, isReconcile, reconcileAnnotation, type State, updateHeads } from './defs';
|
@@ -26,7 +26,7 @@ export class Syncer {
|
|
26
26
|
private readonly _state: StateField<State>
|
27
27
|
) {}
|
28
28
|
|
29
|
-
reconcile(view: EditorView, editor: boolean) {
|
29
|
+
reconcile(view: EditorView, editor: boolean): void {
|
30
30
|
// TODO(burdon): Better way to do mutex?
|
31
31
|
if (this._pending) {
|
32
32
|
return;
|
@@ -41,7 +41,7 @@ export class Syncer {
|
|
41
41
|
this._pending = false;
|
42
42
|
}
|
43
43
|
|
44
|
-
onEditorChange(view: EditorView) {
|
44
|
+
onEditorChange(view: EditorView): void {
|
45
45
|
// Apply the unreconciled transactions to the document.
|
46
46
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
47
47
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
@@ -54,18 +54,18 @@ export class Syncer {
|
|
54
54
|
}
|
55
55
|
}
|
56
56
|
|
57
|
-
onAutomergeChange(view: EditorView) {
|
57
|
+
onAutomergeChange(view: EditorView): void {
|
58
58
|
// Get the diff between the updated state of the document and the heads and apply that to the codemirror doc.
|
59
59
|
const oldHeads = getLastHeads(view.state, this._state);
|
60
|
-
const newHeads = A.getHeads(this._handle.
|
61
|
-
const diff = A.equals(oldHeads, newHeads) ? [] : A.diff(this._handle.
|
60
|
+
const newHeads = A.getHeads(this._handle.doc()!);
|
61
|
+
const diff = A.equals(oldHeads, newHeads) ? [] : A.diff(this._handle.doc()!, oldHeads, newHeads);
|
62
62
|
|
63
63
|
const selection = view.state.selection;
|
64
64
|
const path = getPath(view.state, this._state);
|
65
65
|
updateCodeMirror(view, selection, path, diff);
|
66
66
|
|
67
67
|
// TODO(burdon): Test conflicts?
|
68
|
-
// A.getConflicts(this._handle.
|
68
|
+
// A.getConflicts(this._handle.doc()!, path[0]);
|
69
69
|
|
70
70
|
view.dispatch({
|
71
71
|
effects: updateHeads(newHeads),
|
@@ -4,9 +4,9 @@
|
|
4
4
|
// Ref: https://github.com/automerge/automerge-codemirror
|
5
5
|
//
|
6
6
|
|
7
|
+
import { next as A, type Heads } from '@automerge/automerge';
|
7
8
|
import { type EditorState, type StateField, type Transaction, type Text } from '@codemirror/state';
|
8
9
|
|
9
|
-
import { next as A, type Heads } from '@dxos/automerge/automerge';
|
10
10
|
import { type IDocHandle } from '@dxos/react-client/echo';
|
11
11
|
|
12
12
|
import { type State } from './defs';
|
@@ -4,9 +4,6 @@
|
|
4
4
|
// Ref: https://github.com/automerge/automerge-codemirror
|
5
5
|
//
|
6
6
|
|
7
|
-
import { ChangeSet, type ChangeSpec, type EditorSelection, type EditorState } from '@codemirror/state';
|
8
|
-
import { type EditorView } from '@codemirror/view';
|
9
|
-
|
10
7
|
import {
|
11
8
|
type DelPatch,
|
12
9
|
type InsertPatch,
|
@@ -14,7 +11,9 @@ import {
|
|
14
11
|
type Prop,
|
15
12
|
type PutPatch,
|
16
13
|
type SpliceTextPatch,
|
17
|
-
} from '@
|
14
|
+
} from '@automerge/automerge';
|
15
|
+
import { ChangeSet, type ChangeSpec, type EditorSelection, type EditorState } from '@codemirror/state';
|
16
|
+
import { type EditorView } from '@codemirror/view';
|
18
17
|
|
19
18
|
import { reconcileAnnotation } from './defs';
|
20
19
|
|
@@ -53,7 +53,7 @@ export class SpaceAwarenessProvider implements AwarenessProvider {
|
|
53
53
|
this._info = params.info;
|
54
54
|
}
|
55
55
|
|
56
|
-
open() {
|
56
|
+
open(): void {
|
57
57
|
this._ctx = new Context();
|
58
58
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
59
59
|
if (this._localState) {
|
@@ -92,7 +92,7 @@ export class SpaceAwarenessProvider implements AwarenessProvider {
|
|
92
92
|
});
|
93
93
|
}
|
94
94
|
|
95
|
-
close() {
|
95
|
+
close(): void {
|
96
96
|
void this._ctx?.dispose();
|
97
97
|
this._ctx = undefined;
|
98
98
|
this._postTask = undefined;
|
@@ -113,12 +113,12 @@ export class SpaceAwarenessProvider implements AwarenessProvider {
|
|
113
113
|
this._postTask.schedule();
|
114
114
|
}
|
115
115
|
|
116
|
-
private _handleQueryMessage() {
|
116
|
+
private _handleQueryMessage(): void {
|
117
117
|
invariant(this._postTask);
|
118
118
|
this._postTask.schedule();
|
119
119
|
}
|
120
120
|
|
121
|
-
private _handlePostMessage(message: ProtocolMessage) {
|
121
|
+
private _handlePostMessage(message: ProtocolMessage): void {
|
122
122
|
invariant(message.kind === 'post');
|
123
123
|
// TODO(wittjosiah): Is it helpful or confusing to show cursors for self on other devices?
|
124
124
|
this._remoteStates.set(message.state.peerId, message.state);
|
@@ -95,17 +95,17 @@ export class RemoteSelectionsDecorator implements PluginValue {
|
|
95
95
|
});
|
96
96
|
}
|
97
97
|
|
98
|
-
destroy() {
|
98
|
+
destroy(): void {
|
99
99
|
void this._ctx.dispose();
|
100
100
|
this._provider.close();
|
101
101
|
}
|
102
102
|
|
103
|
-
update(update: ViewUpdate) {
|
103
|
+
update(update: ViewUpdate): void {
|
104
104
|
this._updateLocalSelection(update.view);
|
105
105
|
this._updateRemoteSelections(update.view);
|
106
106
|
}
|
107
107
|
|
108
|
-
private _updateLocalSelection(view: EditorView) {
|
108
|
+
private _updateLocalSelection(view: EditorView): void {
|
109
109
|
const hasFocus = view.hasFocus && view.dom.ownerDocument.hasFocus();
|
110
110
|
const { anchor = undefined, head = undefined } = hasFocus ? view.state.selection.main : {};
|
111
111
|
if (this._lastAnchor === anchor && this._lastHead === head) {
|
@@ -125,7 +125,7 @@ export class RemoteSelectionsDecorator implements PluginValue {
|
|
125
125
|
);
|
126
126
|
}
|
127
127
|
|
128
|
-
private _updateRemoteSelections(view: EditorView) {
|
128
|
+
private _updateRemoteSelections(view: EditorView): void {
|
129
129
|
const decorations: Range<Decoration>[] = [
|
130
130
|
// TODO(burdon): Factor out for testing.
|
131
131
|
// {
|
@@ -239,11 +239,11 @@ class RemoteCaretWidget extends WidgetType {
|
|
239
239
|
return span;
|
240
240
|
}
|
241
241
|
|
242
|
-
override updateDOM() {
|
242
|
+
override updateDOM(): boolean {
|
243
243
|
return false;
|
244
244
|
}
|
245
245
|
|
246
|
-
override eq(widget: this) {
|
246
|
+
override eq(widget: this): boolean {
|
247
247
|
return widget._color === this._color;
|
248
248
|
}
|
249
249
|
|
@@ -251,7 +251,7 @@ class RemoteCaretWidget extends WidgetType {
|
|
251
251
|
return -1;
|
252
252
|
}
|
253
253
|
|
254
|
-
override ignoreEvent() {
|
254
|
+
override ignoreEvent(): boolean {
|
255
255
|
return true;
|
256
256
|
}
|
257
257
|
}
|
package/src/extensions/blast.ts
CHANGED
@@ -136,7 +136,7 @@ class Blaster {
|
|
136
136
|
return this._node;
|
137
137
|
}
|
138
138
|
|
139
|
-
initialize() {
|
139
|
+
initialize(): void {
|
140
140
|
// console.log('initialize');
|
141
141
|
invariant(!this._canvas && !this._ctx);
|
142
142
|
|
@@ -155,7 +155,7 @@ class Blaster {
|
|
155
155
|
this.resize();
|
156
156
|
}
|
157
157
|
|
158
|
-
destroy() {
|
158
|
+
destroy(): void {
|
159
159
|
this.stop();
|
160
160
|
// console.log('destroy');
|
161
161
|
if (this._canvas) {
|
@@ -165,7 +165,7 @@ class Blaster {
|
|
165
165
|
}
|
166
166
|
}
|
167
167
|
|
168
|
-
resize() {
|
168
|
+
resize(): void {
|
169
169
|
if (this._node.parentElement && this._canvas) {
|
170
170
|
const { offsetLeft: x, offsetTop: y, offsetWidth: width, offsetHeight: height } = this._node.parentElement;
|
171
171
|
this._canvas.style.top = `${y}px`;
|
@@ -175,20 +175,20 @@ class Blaster {
|
|
175
175
|
}
|
176
176
|
}
|
177
177
|
|
178
|
-
start() {
|
178
|
+
start(): void {
|
179
179
|
// console.log('start');
|
180
180
|
invariant(this._canvas && this._ctx);
|
181
181
|
this._running = true;
|
182
182
|
this.loop();
|
183
183
|
}
|
184
184
|
|
185
|
-
stop() {
|
185
|
+
stop(): void {
|
186
186
|
// console.log('stop');
|
187
187
|
this._running = false;
|
188
188
|
this._node.style.transform = 'translate(0px, 0px)';
|
189
189
|
}
|
190
190
|
|
191
|
-
loop() {
|
191
|
+
loop(): void {
|
192
192
|
if (!this._running || !this._canvas || !this._ctx) {
|
193
193
|
return;
|
194
194
|
}
|
@@ -230,7 +230,7 @@ class Blaster {
|
|
230
230
|
}
|
231
231
|
}, 100);
|
232
232
|
|
233
|
-
drawParticles() {
|
233
|
+
drawParticles(): void {
|
234
234
|
for (let i = this._particles.length; i--; i > 0) {
|
235
235
|
const particle = this._particles[i];
|
236
236
|
if (!particle) {
|
@@ -282,7 +282,7 @@ class Effect1 extends Effect {
|
|
282
282
|
};
|
283
283
|
}
|
284
284
|
|
285
|
-
update(ctx: CanvasRenderingContext2D, particle: Particle) {
|
285
|
+
update(ctx: CanvasRenderingContext2D, particle: Particle): void {
|
286
286
|
particle.vy += this._options.particleGravity;
|
287
287
|
particle.x += particle.vx;
|
288
288
|
particle.y += particle.vy;
|
@@ -313,7 +313,7 @@ class Effect2 extends Effect {
|
|
313
313
|
};
|
314
314
|
}
|
315
315
|
|
316
|
-
update(ctx: CanvasRenderingContext2D, particle: Particle) {
|
316
|
+
update(ctx: CanvasRenderingContext2D, particle: Particle): void {
|
317
317
|
particle.vy += this._options.particleGravity;
|
318
318
|
particle.x += particle.vx;
|
319
319
|
particle.y += particle.vy;
|
@@ -0,0 +1,49 @@
|
|
1
|
+
//
|
2
|
+
// Copyright 2025 DXOS.org
|
3
|
+
//
|
4
|
+
|
5
|
+
import { StateEffect } from '@codemirror/state';
|
6
|
+
import { type KeyBinding, type Command, type EditorView } from '@codemirror/view';
|
7
|
+
|
8
|
+
import { commandState } from './state';
|
9
|
+
|
10
|
+
export type Action =
|
11
|
+
| {
|
12
|
+
type: 'insert';
|
13
|
+
text: string;
|
14
|
+
}
|
15
|
+
| {
|
16
|
+
type: 'cancel';
|
17
|
+
};
|
18
|
+
|
19
|
+
export type ActionHandler = (action: Action) => void;
|
20
|
+
|
21
|
+
export const openEffect = StateEffect.define<{ pos: number; fullWidth?: boolean }>();
|
22
|
+
export const closeEffect = StateEffect.define<null>();
|
23
|
+
|
24
|
+
export const openCommand: Command = (view: EditorView) => {
|
25
|
+
if (view.state.field(commandState, false)) {
|
26
|
+
const selection = view.state.selection.main;
|
27
|
+
const line = view.state.doc.lineAt(selection.from);
|
28
|
+
if (line.from === selection.from && line.from === line.to) {
|
29
|
+
view.dispatch({ effects: openEffect.of({ pos: selection.anchor, fullWidth: true }) });
|
30
|
+
return true;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
return false;
|
35
|
+
};
|
36
|
+
|
37
|
+
export const closeCommand: Command = (view: EditorView) => {
|
38
|
+
if (view.state.field(commandState, false)) {
|
39
|
+
view.dispatch({ effects: closeEffect.of(null) });
|
40
|
+
return true;
|
41
|
+
}
|
42
|
+
|
43
|
+
return false;
|
44
|
+
};
|
45
|
+
|
46
|
+
export const commandKeyBindings: readonly KeyBinding[] = [
|
47
|
+
{ key: '/', run: openCommand },
|
48
|
+
{ key: 'Escape', run: closeCommand },
|
49
|
+
];
|
@@ -5,35 +5,23 @@
|
|
5
5
|
import { type Extension } from '@codemirror/state';
|
6
6
|
import { EditorView, keymap } from '@codemirror/view';
|
7
7
|
|
8
|
-
import {
|
9
|
-
import {
|
10
|
-
import {
|
11
|
-
import { closeEffect, commandConfig, commandKeyBindings, commandState } from './state';
|
8
|
+
import { closeEffect, commandKeyBindings } from './action';
|
9
|
+
import { hintViewPlugin, type HintOptions } from './hint';
|
10
|
+
import { commandConfig, commandState, type PopupOptions } from './state';
|
12
11
|
|
13
12
|
// TODO(burdon): Create knowledge base for CM notes and ideas.
|
14
13
|
// https://discuss.codemirror.net/t/inline-code-hints-like-vscode/5533/4
|
15
14
|
// https://github.com/saminzadeh/codemirror-extension-inline-suggestion
|
16
15
|
// https://github.com/ChromeDevTools/devtools-frontend/blob/main/front_end/ui/components/text_editor/config.ts#L370
|
17
16
|
|
18
|
-
|
19
|
-
export type CommandAction = {
|
20
|
-
insert?: string;
|
21
|
-
};
|
22
|
-
|
23
|
-
export type CommandOptions = {
|
24
|
-
onHint: () => string | undefined;
|
25
|
-
onRenderDialog: (el: HTMLElement, cb: (action?: CommandAction) => void) => void;
|
26
|
-
onRenderMenu: (el: HTMLElement, cb: () => void) => void;
|
27
|
-
} & Pick<PreviewOptions, 'onRenderPreview'>;
|
17
|
+
export type CommandOptions = Partial<PopupOptions & HintOptions>;
|
28
18
|
|
29
|
-
export const command = (options: CommandOptions): Extension => {
|
19
|
+
export const command = (options: CommandOptions = {}): Extension => {
|
30
20
|
return [
|
21
|
+
keymap.of(commandKeyBindings),
|
31
22
|
commandConfig.of(options),
|
32
23
|
commandState,
|
33
|
-
|
34
|
-
preview(options),
|
35
|
-
floatingMenu(options),
|
36
|
-
hintViewPlugin(options),
|
24
|
+
options.onHint ? hintViewPlugin({ onHint: options.onHint }) : [],
|
37
25
|
EditorView.focusChangeEffect.of((_, focusing) => {
|
38
26
|
return focusing ? closeEffect.of(null) : null;
|
39
27
|
}),
|
@@ -41,14 +29,6 @@ export const command = (options: CommandOptions): Extension => {
|
|
41
29
|
'.cm-tooltip': {
|
42
30
|
background: 'transparent',
|
43
31
|
},
|
44
|
-
'.cm-preview': {
|
45
|
-
marginLeft: '-1rem',
|
46
|
-
marginRight: '-1rem',
|
47
|
-
padding: '1rem',
|
48
|
-
borderRadius: '1rem',
|
49
|
-
background: 'var(--dx-modalSurface)',
|
50
|
-
border: '1px solid var(--dx-separator)',
|
51
|
-
},
|
52
32
|
}),
|
53
33
|
];
|
54
34
|
};
|
@@ -5,16 +5,48 @@
|
|
5
5
|
import { RangeSetBuilder } from '@codemirror/state';
|
6
6
|
import { Decoration, EditorView, ViewPlugin, type ViewUpdate, WidgetType } from '@codemirror/view';
|
7
7
|
|
8
|
-
import { type CommandOptions } from './command';
|
9
8
|
import { commandState } from './state';
|
10
9
|
import { clientRectsFor, flattenRect } from '../../util';
|
11
10
|
|
12
|
-
|
11
|
+
export type HintOptions = {
|
12
|
+
onHint: () => string | undefined;
|
13
|
+
};
|
14
|
+
|
15
|
+
export const hintViewPlugin = ({ onHint }: HintOptions) =>
|
16
|
+
ViewPlugin.fromClass(
|
17
|
+
class {
|
18
|
+
decorations = Decoration.none;
|
19
|
+
update(update: ViewUpdate) {
|
20
|
+
const builder = new RangeSetBuilder<Decoration>();
|
21
|
+
const cState = update.view.state.field(commandState, false);
|
22
|
+
if (!cState?.tooltip) {
|
23
|
+
const selection = update.view.state.selection.main;
|
24
|
+
const line = update.view.state.doc.lineAt(selection.from);
|
25
|
+
// Only show if blank line.
|
26
|
+
// TODO(burdon): Clashes with placeholder if pos === 0.
|
27
|
+
// TODO(burdon): Show after delay or if blank line above?
|
28
|
+
if (selection.from === selection.to && line.from === line.to) {
|
29
|
+
const hint = onHint();
|
30
|
+
if (hint) {
|
31
|
+
builder.add(selection.from, selection.to, Decoration.widget({ widget: new Hint(hint) }));
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
this.decorations = builder.finish();
|
37
|
+
}
|
38
|
+
},
|
39
|
+
{
|
40
|
+
provide: (plugin) => [EditorView.decorations.of((view) => view.plugin(plugin)?.decorations ?? Decoration.none)],
|
41
|
+
},
|
42
|
+
);
|
43
|
+
|
44
|
+
export class Hint extends WidgetType {
|
13
45
|
constructor(readonly content: string | HTMLElement) {
|
14
46
|
super();
|
15
47
|
}
|
16
48
|
|
17
|
-
toDOM() {
|
49
|
+
toDOM(): HTMLSpanElement {
|
18
50
|
const wrap = document.createElement('span');
|
19
51
|
wrap.className = 'cm-placeholder';
|
20
52
|
wrap.style.pointerEvents = 'none';
|
@@ -44,36 +76,7 @@ class CommandHint extends WidgetType {
|
|
44
76
|
return rect;
|
45
77
|
}
|
46
78
|
|
47
|
-
override ignoreEvent() {
|
79
|
+
override ignoreEvent(): boolean {
|
48
80
|
return false;
|
49
81
|
}
|
50
82
|
}
|
51
|
-
|
52
|
-
export const hintViewPlugin = ({ onHint }: CommandOptions) =>
|
53
|
-
ViewPlugin.fromClass(
|
54
|
-
class {
|
55
|
-
deco = Decoration.none;
|
56
|
-
update(update: ViewUpdate) {
|
57
|
-
const builder = new RangeSetBuilder<Decoration>();
|
58
|
-
const cState = update.view.state.field(commandState, false);
|
59
|
-
if (!cState?.tooltip) {
|
60
|
-
const selection = update.view.state.selection.main;
|
61
|
-
const line = update.view.state.doc.lineAt(selection.from);
|
62
|
-
// Only show if blank line.
|
63
|
-
// TODO(burdon): Clashes with placeholder if pos === 0.
|
64
|
-
// TODO(burdon): Show after delay or if blank line above?
|
65
|
-
if (selection.from === selection.to && line.from === line.to) {
|
66
|
-
const hint = onHint();
|
67
|
-
if (hint) {
|
68
|
-
builder.add(selection.from, selection.to, Decoration.widget({ widget: new CommandHint(hint) }));
|
69
|
-
}
|
70
|
-
}
|
71
|
-
}
|
72
|
-
|
73
|
-
this.deco = builder.finish();
|
74
|
-
}
|
75
|
-
},
|
76
|
-
{
|
77
|
-
provide: (plugin) => [EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration.none)],
|
78
|
-
},
|
79
|
-
);
|
@@ -2,99 +2,136 @@
|
|
2
2
|
// Copyright 2024 DXOS.org
|
3
3
|
//
|
4
4
|
|
5
|
-
import {
|
5
|
+
import { EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';
|
6
6
|
|
7
|
-
import { type
|
8
|
-
import { closeEffect, openCommand, openEffect } from './state';
|
7
|
+
import { type CleanupFn, addEventListener } from '@dxos/async';
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
export
|
9
|
+
import { closeEffect, openEffect } from './action';
|
10
|
+
|
11
|
+
export type FloatingMenuOptions = {
|
12
|
+
icon?: string;
|
13
|
+
height?: number;
|
14
|
+
padding?: number;
|
15
|
+
};
|
16
|
+
|
17
|
+
export const floatingMenu = (options: FloatingMenuOptions = {}) => [
|
13
18
|
ViewPlugin.fromClass(
|
14
19
|
class {
|
15
|
-
button: HTMLElement;
|
16
20
|
view: EditorView;
|
17
|
-
|
21
|
+
tag: HTMLElement;
|
22
|
+
rafId?: number | null;
|
23
|
+
cleanup?: CleanupFn;
|
18
24
|
|
19
25
|
constructor(view: EditorView) {
|
20
26
|
this.view = view;
|
21
27
|
|
22
|
-
// Position context
|
28
|
+
// Position context.
|
23
29
|
const container = view.scrollDOM;
|
24
30
|
if (getComputedStyle(container).position === 'static') {
|
25
31
|
container.style.position = 'relative';
|
26
32
|
}
|
27
33
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
34
|
+
{
|
35
|
+
const icon = document.createElement('dx-icon');
|
36
|
+
icon.setAttribute('icon', options.icon ?? 'ph--dots-three-vertical--regular');
|
37
|
+
|
38
|
+
const button = document.createElement('button');
|
39
|
+
button.appendChild(icon);
|
40
|
+
|
41
|
+
this.tag = document.createElement('dx-ref-tag');
|
42
|
+
this.tag.classList.add('cm-ref-tag');
|
43
|
+
this.tag.appendChild(button);
|
44
|
+
}
|
33
45
|
|
34
|
-
|
35
|
-
openCommand(view);
|
36
|
-
});
|
37
|
-
container.appendChild(this.button);
|
46
|
+
container.appendChild(this.tag);
|
38
47
|
|
39
48
|
// Listen for scroll events.
|
40
|
-
|
49
|
+
const handler = () => this.scheduleUpdate();
|
50
|
+
this.cleanup = addEventListener(container, 'scroll', handler);
|
41
51
|
this.scheduleUpdate();
|
42
52
|
}
|
43
53
|
|
54
|
+
destroy() {
|
55
|
+
this.cleanup?.();
|
56
|
+
this.tag.remove();
|
57
|
+
if (this.rafId != null) {
|
58
|
+
cancelAnimationFrame(this.rafId);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
44
62
|
update(update: ViewUpdate) {
|
63
|
+
this.tag.dataset.focused = update.view.hasFocus ? 'true' : 'false';
|
64
|
+
if (!update.view.hasFocus) {
|
65
|
+
return;
|
66
|
+
}
|
67
|
+
|
45
68
|
// TODO(burdon): Timer to fade in/out.
|
46
69
|
if (update.transactions.some((tr) => tr.effects.some((effect) => effect.is(openEffect)))) {
|
47
|
-
this.
|
70
|
+
this.tag.style.display = 'none';
|
71
|
+
this.tag.classList.add('opacity-10');
|
48
72
|
} else if (update.transactions.some((tr) => tr.effects.some((effect) => effect.is(closeEffect)))) {
|
49
|
-
this.
|
50
|
-
} else if (
|
73
|
+
this.tag.style.display = 'block';
|
74
|
+
} else if (
|
75
|
+
update.docChanged ||
|
76
|
+
update.focusChanged ||
|
77
|
+
update.geometryChanged ||
|
78
|
+
update.selectionSet ||
|
79
|
+
update.viewportChanged
|
80
|
+
) {
|
51
81
|
this.scheduleUpdate();
|
52
82
|
}
|
53
83
|
}
|
54
84
|
|
55
|
-
scheduleUpdate() {
|
56
|
-
if (this.rafId != null) {
|
57
|
-
cancelAnimationFrame(this.rafId);
|
58
|
-
}
|
59
|
-
this.rafId = requestAnimationFrame(() => this.updateButtonPosition());
|
60
|
-
}
|
61
|
-
|
62
85
|
updateButtonPosition() {
|
63
|
-
const
|
64
|
-
const lineBlock: BlockInfo = this.view.lineBlockAt(pos);
|
65
|
-
const domInfo = this.view.domAtPos(lineBlock.from);
|
66
|
-
|
67
|
-
// Find nearest HTMLElement for the line block
|
68
|
-
let node: Node | null = domInfo.node;
|
69
|
-
while (node && !(node instanceof HTMLElement)) {
|
70
|
-
node = node.parentNode;
|
71
|
-
}
|
86
|
+
const { x, width } = this.view.contentDOM.getBoundingClientRect();
|
72
87
|
|
73
|
-
|
74
|
-
|
88
|
+
const pos = this.view.state.selection.main.head;
|
89
|
+
const line = this.view.lineBlockAt(pos);
|
90
|
+
const coords = this.view.coordsAtPos(line.from);
|
91
|
+
if (!coords) {
|
75
92
|
return;
|
76
93
|
}
|
77
94
|
|
78
|
-
const
|
79
|
-
const
|
95
|
+
const lineHeight = coords.bottom - coords.top;
|
96
|
+
const dy = (lineHeight - (options.height ?? 32)) / 2;
|
80
97
|
|
81
|
-
|
82
|
-
const
|
83
|
-
const offsetLeft = this.view.scrollDOM.clientWidth + this.view.scrollDOM.scrollLeft - lineRect.x;
|
98
|
+
const offsetTop = coords.top + dy;
|
99
|
+
const offsetLeft = x + width + (options.padding ?? 8);
|
84
100
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
this.button.style.top = `${offsetTop}px`;
|
89
|
-
this.button.style.left = `${offsetLeft}px`;
|
90
|
-
this.button.style.display = 'block';
|
101
|
+
this.tag.style.top = `${offsetTop}px`;
|
102
|
+
this.tag.style.left = `${offsetLeft}px`;
|
103
|
+
this.tag.style.display = 'block';
|
91
104
|
}
|
92
105
|
|
93
|
-
|
94
|
-
this.button.remove();
|
106
|
+
scheduleUpdate() {
|
95
107
|
if (this.rafId != null) {
|
96
108
|
cancelAnimationFrame(this.rafId);
|
97
109
|
}
|
110
|
+
|
111
|
+
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
98
112
|
}
|
99
113
|
},
|
100
|
-
)
|
114
|
+
),
|
115
|
+
|
116
|
+
EditorView.theme({
|
117
|
+
'.cm-ref-tag': {
|
118
|
+
position: 'fixed',
|
119
|
+
padding: '0',
|
120
|
+
border: 'none',
|
121
|
+
opacity: '0',
|
122
|
+
},
|
123
|
+
'[data-has-focus] & .cm-ref-tag': {
|
124
|
+
opacity: '1',
|
125
|
+
},
|
126
|
+
'[data-is-attention-source] & .cm-ref-tag': {
|
127
|
+
opacity: '1',
|
128
|
+
},
|
129
|
+
'.cm-ref-tag button': {
|
130
|
+
display: 'grid',
|
131
|
+
alignItems: 'center',
|
132
|
+
justifyContent: 'center',
|
133
|
+
width: '2rem',
|
134
|
+
height: '2rem',
|
135
|
+
},
|
136
|
+
}),
|
137
|
+
];
|