@dxos/react-ui-editor 0.8.4-main.dedc0f3 → 0.8.4-main.ead640a
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/{chunk-22UMM3QJ.mjs → chunk-HL3YF6WC.mjs} +2 -2
- package/dist/lib/browser/chunk-HL3YF6WC.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +5482 -5519
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +71 -1
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node-esm/{chunk-YXYQPV6R.mjs → chunk-YJZGD3LY.mjs} +2 -2
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +5482 -5519
- 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 +71 -1
- package/dist/lib/node-esm/testing/index.mjs.map +4 -4
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/components/Editor/Editor.d.ts +24 -9
- package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
- package/dist/types/src/components/Editor/Editor.stories.d.ts +27 -0
- package/dist/types/src/components/Editor/Editor.stories.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/util.d.ts +1 -1
- package/dist/types/src/components/index.d.ts +0 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/extensions/{autocomplete.d.ts → autocomplete/autocomplete.d.ts} +1 -1
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts +5 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts +13 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts +20 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts +10 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -0
- 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/sync.d.ts +2 -2
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/autoscroll.d.ts +2 -2
- package/dist/types/src/extensions/autoscroll.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +7 -2
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/focus.d.ts.map +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +2 -1
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts +1 -1
- package/dist/types/src/extensions/json.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/modes.d.ts +1 -1
- package/dist/types/src/extensions/modes.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/menu.d.ts +8 -0
- package/dist/types/src/extensions/outliner/menu.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/PopoverMenuProvider.d.ts +36 -0
- package/dist/types/src/extensions/popover/PopoverMenuProvider.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/index.d.ts +8 -0
- package/dist/types/src/extensions/popover/index.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/menu-presets.d.ts +4 -0
- package/dist/types/src/extensions/popover/menu-presets.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/menu.d.ts +24 -0
- package/dist/types/src/extensions/popover/menu.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/modal.d.ts +7 -0
- package/dist/types/src/extensions/popover/modal.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/popover.d.ts +47 -0
- package/dist/types/src/extensions/popover/popover.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/usePopoverMenu.d.ts +34 -0
- package/dist/types/src/extensions/popover/usePopoverMenu.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/util.d.ts +8 -0
- package/dist/types/src/extensions/popover/util.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/preview.d.ts +0 -2
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
- package/dist/types/src/extensions/state.d.ts +2 -0
- package/dist/types/src/extensions/state.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/streamer.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/xml-tags.d.ts +1 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +4 -8
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/stories/{Command.stories.d.ts → CommandDialog.stories.d.ts} +2 -3
- package/dist/types/src/stories/CommandDialog.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Comments.stories.d.ts +3 -4
- package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
- package/dist/types/src/stories/EditorToolbar.stories.d.ts +1 -2
- package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Experimental.stories.d.ts +3 -4
- package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Markdown.stories.d.ts +3 -4
- package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Outliner.stories.d.ts +0 -1
- package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
- package/dist/types/src/stories/{CommandMenu.stories.d.ts → Popover.stories.d.ts} +6 -6
- package/dist/types/src/stories/Popover.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Preview.stories.d.ts +3 -4
- package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Tags.stories.d.ts +0 -1
- package/dist/types/src/stories/Tags.stories.d.ts.map +1 -1
- package/dist/types/src/stories/TextEditor.stories.d.ts +3 -5
- package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/stories/components/EditorStory.d.ts +5 -5
- package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/testing/PreviewPopover.d.ts +20 -0
- package/dist/types/src/testing/PreviewPopover.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +1 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +1 -1
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +0 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +55 -52
- package/src/components/Editor/Editor.stories.tsx +69 -0
- package/src/components/Editor/Editor.tsx +57 -14
- package/src/components/EditorToolbar/EditorToolbar.tsx +1 -0
- package/src/components/index.ts +0 -1
- package/src/extensions/{autocomplete.ts → autocomplete/autocomplete.ts} +2 -1
- package/src/extensions/autocomplete/index.ts +8 -0
- package/src/extensions/autocomplete/match.ts +46 -0
- package/src/extensions/{command → autocomplete}/placeholder.ts +21 -17
- package/src/extensions/{command → autocomplete}/typeahead.ts +6 -48
- package/src/extensions/automerge/automerge.stories.tsx +8 -8
- package/src/extensions/automerge/automerge.ts +28 -9
- package/src/extensions/automerge/sync.ts +7 -3
- package/src/extensions/autoscroll.ts +43 -37
- package/src/extensions/factories.ts +41 -12
- package/src/extensions/focus.ts +5 -4
- package/src/extensions/folding.tsx +4 -6
- package/src/extensions/hashtag.tsx +2 -2
- package/src/extensions/index.ts +2 -1
- package/src/extensions/json.ts +1 -1
- package/src/extensions/markdown/bundle.ts +16 -4
- package/src/extensions/markdown/decorate.ts +1 -0
- package/src/extensions/markdown/link.ts +3 -0
- package/src/extensions/modes.ts +2 -2
- package/src/extensions/{command/floating-menu.ts → outliner/menu.ts} +15 -20
- package/src/extensions/outliner/outliner.ts +3 -3
- package/src/extensions/popover/PopoverMenuProvider.tsx +221 -0
- package/src/extensions/popover/index.ts +12 -0
- package/src/extensions/popover/menu-presets.ts +124 -0
- package/src/extensions/popover/menu.ts +67 -0
- package/src/extensions/popover/modal.ts +24 -0
- package/src/extensions/popover/popover.ts +291 -0
- package/src/extensions/popover/usePopoverMenu.ts +173 -0
- package/src/extensions/popover/util.ts +29 -0
- package/src/extensions/preview/index.ts +1 -1
- package/src/extensions/preview/preview.ts +0 -5
- package/src/extensions/selection.ts +2 -2
- package/src/extensions/state.ts +7 -0
- package/src/extensions/tags/streamer.ts +4 -5
- package/src/extensions/tags/xml-tags.ts +59 -1
- package/src/hooks/useTextEditor.ts +27 -39
- package/src/stories/{Command.stories.tsx → CommandDialog.stories.tsx} +10 -22
- package/src/stories/Comments.stories.tsx +5 -5
- package/src/stories/EditorToolbar.stories.tsx +6 -5
- package/src/stories/Experimental.stories.tsx +6 -6
- package/src/stories/Markdown.stories.tsx +5 -5
- package/src/stories/Outliner.stories.tsx +42 -26
- package/src/stories/Popover.stories.tsx +163 -0
- package/src/stories/Preview.stories.tsx +9 -9
- package/src/stories/Tags.stories.tsx +5 -5
- package/src/stories/TextEditor.stories.tsx +7 -32
- package/src/stories/components/EditorStory.tsx +7 -5
- package/src/styles/theme.ts +12 -10
- package/src/{components/Popover/RefDropdownMenu.tsx → testing/PreviewPopover.tsx} +20 -29
- package/src/testing/index.ts +1 -0
- package/src/types/types.ts +1 -1
- package/src/util/index.ts +0 -1
- package/dist/lib/browser/chunk-22UMM3QJ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YXYQPV6R.mjs.map +0 -7
- package/dist/types/src/components/Popover/CommandMenu.d.ts +0 -34
- package/dist/types/src/components/Popover/CommandMenu.d.ts.map +0 -1
- package/dist/types/src/components/Popover/RefDropdownMenu.d.ts +0 -14
- package/dist/types/src/components/Popover/RefDropdownMenu.d.ts.map +0 -1
- package/dist/types/src/components/Popover/RefPopover.d.ts +0 -37
- package/dist/types/src/components/Popover/RefPopover.d.ts.map +0 -1
- package/dist/types/src/components/Popover/index.d.ts +0 -4
- package/dist/types/src/components/Popover/index.d.ts.map +0 -1
- package/dist/types/src/extensions/autocomplete.d.ts.map +0 -1
- package/dist/types/src/extensions/command/action.d.ts +0 -17
- package/dist/types/src/extensions/command/action.d.ts.map +0 -1
- package/dist/types/src/extensions/command/command-menu.d.ts +0 -20
- package/dist/types/src/extensions/command/command-menu.d.ts.map +0 -1
- package/dist/types/src/extensions/command/command.d.ts +0 -6
- package/dist/types/src/extensions/command/command.d.ts.map +0 -1
- package/dist/types/src/extensions/command/floating-menu.d.ts +0 -7
- package/dist/types/src/extensions/command/floating-menu.d.ts.map +0 -1
- package/dist/types/src/extensions/command/hint.d.ts +0 -19
- package/dist/types/src/extensions/command/hint.d.ts.map +0 -1
- package/dist/types/src/extensions/command/index.d.ts +0 -7
- package/dist/types/src/extensions/command/index.d.ts.map +0 -1
- package/dist/types/src/extensions/command/placeholder.d.ts +0 -10
- package/dist/types/src/extensions/command/placeholder.d.ts.map +0 -1
- package/dist/types/src/extensions/command/state.d.ts +0 -16
- package/dist/types/src/extensions/command/state.d.ts.map +0 -1
- package/dist/types/src/extensions/command/typeahead.d.ts +0 -22
- package/dist/types/src/extensions/command/typeahead.d.ts.map +0 -1
- package/dist/types/src/extensions/command/useCommandMenu.d.ts +0 -26
- package/dist/types/src/extensions/command/useCommandMenu.d.ts.map +0 -1
- package/dist/types/src/stories/Command.stories.d.ts.map +0 -1
- package/dist/types/src/stories/CommandMenu.stories.d.ts.map +0 -1
- package/dist/types/src/util/domino.d.ts +0 -18
- package/dist/types/src/util/domino.d.ts.map +0 -1
- package/src/components/Popover/CommandMenu.tsx +0 -279
- package/src/components/Popover/RefPopover.tsx +0 -117
- package/src/components/Popover/index.ts +0 -7
- package/src/extensions/command/action.ts +0 -56
- package/src/extensions/command/command-menu.ts +0 -211
- package/src/extensions/command/command.ts +0 -34
- package/src/extensions/command/hint.ts +0 -103
- package/src/extensions/command/index.ts +0 -10
- package/src/extensions/command/state.ts +0 -90
- package/src/extensions/command/useCommandMenu.ts +0 -119
- package/src/stories/CommandMenu.stories.tsx +0 -160
- package/src/util/domino.ts +0 -51
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
//
|
|
6
6
|
|
|
7
7
|
import { next as A } from '@automerge/automerge';
|
|
8
|
-
import { type Extension, StateField } from '@codemirror/state';
|
|
8
|
+
import { type Extension, StateField, Transaction } from '@codemirror/state';
|
|
9
9
|
import { EditorView, ViewPlugin } from '@codemirror/view';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { DocAccessor } from '@dxos/react-client/echo';
|
|
12
12
|
|
|
13
13
|
import { Cursor } from '../../util';
|
|
14
|
+
import { initialSync } from '../state';
|
|
14
15
|
|
|
15
16
|
import { cursorConverter } from './cursor';
|
|
16
17
|
import { type State, isReconcile, updateHeadsEffect } from './defs';
|
|
@@ -18,11 +19,13 @@ import { Syncer } from './sync';
|
|
|
18
19
|
|
|
19
20
|
export const automerge = (accessor: DocAccessor): Extension => {
|
|
20
21
|
const syncState = StateField.define<State>({
|
|
21
|
-
create: () =>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
create: () => {
|
|
23
|
+
return {
|
|
24
|
+
path: accessor.path.slice(),
|
|
25
|
+
lastHeads: A.getHeads(accessor.handle.doc()!),
|
|
26
|
+
unreconciledTransactions: [],
|
|
27
|
+
};
|
|
28
|
+
},
|
|
26
29
|
|
|
27
30
|
update: (value, tr) => {
|
|
28
31
|
const result: State = {
|
|
@@ -64,6 +67,18 @@ export const automerge = (accessor: DocAccessor): Extension => {
|
|
|
64
67
|
class {
|
|
65
68
|
constructor(private readonly _view: EditorView) {
|
|
66
69
|
accessor.handle.addListener('change', this._handleChange);
|
|
70
|
+
|
|
71
|
+
requestAnimationFrame(() => {
|
|
72
|
+
const value = DocAccessor.getValue<string>(accessor);
|
|
73
|
+
const current = this._view.state.doc.toString();
|
|
74
|
+
if (value !== current) {
|
|
75
|
+
// TODO(burdon): This attempts to set the initial state, but creates problems.
|
|
76
|
+
// this._view.dispatch({
|
|
77
|
+
// changes: { from: 0, to: this._view.state.doc.length, insert: value },
|
|
78
|
+
// annotations: initialSync,
|
|
79
|
+
// });
|
|
80
|
+
}
|
|
81
|
+
});
|
|
67
82
|
}
|
|
68
83
|
|
|
69
84
|
destroy() {
|
|
@@ -77,9 +92,13 @@ export const automerge = (accessor: DocAccessor): Extension => {
|
|
|
77
92
|
),
|
|
78
93
|
|
|
79
94
|
// Reconcile local updates.
|
|
80
|
-
EditorView.updateListener.of(({ view, changes }) => {
|
|
95
|
+
EditorView.updateListener.of(({ view, changes, transactions }) => {
|
|
81
96
|
if (!changes.empty) {
|
|
82
|
-
|
|
97
|
+
// Only reconcile if it's not an initial sync (to avoid loops)
|
|
98
|
+
const isInitialSync = transactions.some((tr) => tr.annotation(Transaction.userEvent) === initialSync.value);
|
|
99
|
+
if (!isInitialSync) {
|
|
100
|
+
syncer.reconcile(view, true);
|
|
101
|
+
}
|
|
83
102
|
}
|
|
84
103
|
}),
|
|
85
104
|
];
|
|
@@ -8,6 +8,7 @@ import { next as A } from '@automerge/automerge';
|
|
|
8
8
|
import { type StateField } from '@codemirror/state';
|
|
9
9
|
import { type EditorView } from '@codemirror/view';
|
|
10
10
|
|
|
11
|
+
import { log } from '@dxos/log';
|
|
11
12
|
import { type IDocHandle } from '@dxos/react-client/echo';
|
|
12
13
|
|
|
13
14
|
import { type State, getLastHeads, getPath, isReconcile, reconcileAnnotation, updateHeads } from './defs';
|
|
@@ -27,7 +28,6 @@ export class Syncer {
|
|
|
27
28
|
) {}
|
|
28
29
|
|
|
29
30
|
reconcile(view: EditorView, editor: boolean): void {
|
|
30
|
-
// TODO(burdon): Better way to do mutex?
|
|
31
31
|
if (this._pending) {
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
@@ -41,7 +41,9 @@ export class Syncer {
|
|
|
41
41
|
this._pending = false;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
onEditorChange(view: EditorView): void {
|
|
44
|
+
private onEditorChange(view: EditorView): void {
|
|
45
|
+
log('onEditorChange');
|
|
46
|
+
|
|
45
47
|
// Apply the unreconciled transactions to the document.
|
|
46
48
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
47
49
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
@@ -54,7 +56,9 @@ export class Syncer {
|
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
onAutomergeChange(view: EditorView): void {
|
|
59
|
+
private onAutomergeChange(view: EditorView): void {
|
|
60
|
+
log('onAutomergeChange');
|
|
61
|
+
|
|
58
62
|
// Get the diff between the updated state of the document and the heads and apply that to the codemirror doc.
|
|
59
63
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
60
64
|
const newHeads = A.getHeads(this._handle.doc()!);
|
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
import { StateEffect } from '@codemirror/state';
|
|
6
6
|
import { EditorView, ViewPlugin } from '@codemirror/view';
|
|
7
7
|
|
|
8
|
-
import { Domino } from '
|
|
8
|
+
import { Domino } from '@dxos/react-ui';
|
|
9
9
|
|
|
10
10
|
const lineHeight = 24;
|
|
11
11
|
|
|
12
12
|
export const scrollToBottomEffect = StateEffect.define<any>();
|
|
13
13
|
|
|
14
14
|
export type AutoScrollOptions = {
|
|
15
|
-
overscroll
|
|
16
|
-
throttle
|
|
15
|
+
overscroll?: number;
|
|
16
|
+
throttle?: number;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -23,9 +23,10 @@ export type AutoScrollOptions = {
|
|
|
23
23
|
export const autoScroll = ({ overscroll = 4 * lineHeight, throttle = 2_000 }: Partial<AutoScrollOptions> = {}) => {
|
|
24
24
|
let isThrottled = false;
|
|
25
25
|
let isPinned = true;
|
|
26
|
-
let lastScrollTop = 0;
|
|
27
26
|
let timeout: NodeJS.Timeout | undefined;
|
|
28
|
-
let buttonContainer: HTMLDivElement;
|
|
27
|
+
let buttonContainer: HTMLDivElement | undefined;
|
|
28
|
+
let lastScrollTop = 0;
|
|
29
|
+
let scrollCounter = 0;
|
|
29
30
|
|
|
30
31
|
const hideScrollbar = (view: EditorView) => {
|
|
31
32
|
view.scrollDOM.classList.add('cm-hide-scrollbar');
|
|
@@ -37,6 +38,7 @@ export const autoScroll = ({ overscroll = 4 * lineHeight, throttle = 2_000 }: Pa
|
|
|
37
38
|
|
|
38
39
|
const scrollToBottom = (view: EditorView) => {
|
|
39
40
|
isPinned = true;
|
|
41
|
+
scrollCounter = 0;
|
|
40
42
|
buttonContainer?.classList.add('opacity-0');
|
|
41
43
|
requestAnimationFrame(() => {
|
|
42
44
|
hideScrollbar(view);
|
|
@@ -48,28 +50,6 @@ export const autoScroll = ({ overscroll = 4 * lineHeight, throttle = 2_000 }: Pa
|
|
|
48
50
|
};
|
|
49
51
|
|
|
50
52
|
return [
|
|
51
|
-
// Scroll button.
|
|
52
|
-
ViewPlugin.fromClass(
|
|
53
|
-
class {
|
|
54
|
-
constructor(view: EditorView) {
|
|
55
|
-
const scroller = view.scrollDOM.parentElement;
|
|
56
|
-
buttonContainer = Domino.of('div')
|
|
57
|
-
.classNames(true && 'cm-scroll-button transition-opacity duration-300 opacity-0')
|
|
58
|
-
.child(
|
|
59
|
-
Domino.of('button')
|
|
60
|
-
.classNames('dx-button bg-accentSurface')
|
|
61
|
-
.data('density', 'fine')
|
|
62
|
-
.child(Domino.of<any>('dx-icon').attr('icon', 'ph--arrow-down--regular'))
|
|
63
|
-
.on('click', () => {
|
|
64
|
-
scrollToBottom(view);
|
|
65
|
-
}),
|
|
66
|
-
)
|
|
67
|
-
.build();
|
|
68
|
-
scroller?.appendChild(buttonContainer);
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
),
|
|
72
|
-
|
|
73
53
|
// Update listener for logging when scrolling is needed.
|
|
74
54
|
EditorView.updateListener.of((update) => {
|
|
75
55
|
// Listen for effects.
|
|
@@ -81,14 +61,10 @@ export const autoScroll = ({ overscroll = 4 * lineHeight, throttle = 2_000 }: Pa
|
|
|
81
61
|
}
|
|
82
62
|
});
|
|
83
63
|
|
|
64
|
+
// Maybe scroll if doc changed and pinned.
|
|
84
65
|
if (update.docChanged && isPinned && !isThrottled) {
|
|
85
66
|
const distanceFromBottom = calcDistance(update.view.scrollDOM);
|
|
86
|
-
|
|
87
|
-
// Hide scrollbar even if not scrolling to bottom.
|
|
88
|
-
// hideScrollbar(update.view);
|
|
89
|
-
|
|
90
|
-
// Keep pinned.
|
|
91
|
-
if (distanceFromBottom > overscroll) {
|
|
67
|
+
if (distanceFromBottom >= overscroll) {
|
|
92
68
|
isThrottled = true;
|
|
93
69
|
requestAnimationFrame(() => {
|
|
94
70
|
scrollToBottom(update.view);
|
|
@@ -97,29 +73,60 @@ export const autoScroll = ({ overscroll = 4 * lineHeight, throttle = 2_000 }: Pa
|
|
|
97
73
|
// Reset throttle.
|
|
98
74
|
setTimeout(() => {
|
|
99
75
|
isThrottled = false;
|
|
76
|
+
scrollToBottom(update.view);
|
|
100
77
|
}, throttle);
|
|
101
78
|
}
|
|
102
79
|
}
|
|
103
80
|
}),
|
|
104
81
|
|
|
82
|
+
// Detect user scroll.
|
|
83
|
+
// NOTE: Multiple scroll events are triggered during programmatic smooth scrolling.
|
|
105
84
|
EditorView.domEventHandlers({
|
|
106
85
|
scroll: (event, view) => {
|
|
107
86
|
const scroller = view.scrollDOM;
|
|
87
|
+
// Suspect delta goes positive when rendering widgets, so count positive deltas.
|
|
88
|
+
// TODO(burdon): Detect user scroll directly (wheel, touch, keys, etc.)
|
|
89
|
+
if (lastScrollTop > scroller.scrollTop) {
|
|
90
|
+
scrollCounter++;
|
|
91
|
+
}
|
|
92
|
+
lastScrollTop = scroller.scrollTop;
|
|
108
93
|
const distanceFromBottom = calcDistance(scroller);
|
|
109
94
|
if (distanceFromBottom === 0) {
|
|
110
95
|
// Pin to bottom.
|
|
111
96
|
isPinned = true;
|
|
112
97
|
buttonContainer?.classList.add('opacity-0');
|
|
113
|
-
|
|
98
|
+
scrollCounter = 0;
|
|
99
|
+
} else if (scrollCounter > 3) {
|
|
114
100
|
// Break pin if user scrolls up.
|
|
115
101
|
isPinned = false;
|
|
116
102
|
buttonContainer?.classList.remove('opacity-0');
|
|
117
103
|
}
|
|
118
|
-
|
|
119
|
-
lastScrollTop = scroller.scrollTop;
|
|
120
104
|
},
|
|
121
105
|
}),
|
|
122
106
|
|
|
107
|
+
// Scroll button.
|
|
108
|
+
ViewPlugin.fromClass(
|
|
109
|
+
class {
|
|
110
|
+
constructor(view: EditorView) {
|
|
111
|
+
const scroller = view.scrollDOM.parentElement;
|
|
112
|
+
buttonContainer = Domino.of('div')
|
|
113
|
+
.classNames(true && 'cm-scroll-button transition-opacity duration-300 opacity-0')
|
|
114
|
+
.children(
|
|
115
|
+
Domino.of('button')
|
|
116
|
+
.classNames('dx-button bg-accentSurface')
|
|
117
|
+
.data('density', 'fine')
|
|
118
|
+
.children(Domino.of<any>('dx-icon').attributes({ icon: 'ph--arrow-down--regular' }))
|
|
119
|
+
.on('click', () => {
|
|
120
|
+
scrollToBottom(view);
|
|
121
|
+
}),
|
|
122
|
+
)
|
|
123
|
+
.build();
|
|
124
|
+
scroller?.appendChild(buttonContainer);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
),
|
|
128
|
+
|
|
129
|
+
// Styles.
|
|
123
130
|
EditorView.theme({
|
|
124
131
|
'.cm-scroller': {
|
|
125
132
|
paddingBottom: `${overscroll}px`,
|
|
@@ -132,7 +139,6 @@ export const autoScroll = ({ overscroll = 4 * lineHeight, throttle = 2_000 }: Pa
|
|
|
132
139
|
display: 'none',
|
|
133
140
|
},
|
|
134
141
|
|
|
135
|
-
// TODO(burdon): IconButton.
|
|
136
142
|
'.cm-scroll-button': {
|
|
137
143
|
position: 'absolute',
|
|
138
144
|
bottom: '0.5rem',
|
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
import { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete';
|
|
6
6
|
import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from '@codemirror/commands';
|
|
7
|
-
import {
|
|
7
|
+
import { HighlightStyle, bracketMatching, syntaxHighlighting } from '@codemirror/language';
|
|
8
8
|
import { searchKeymap } from '@codemirror/search';
|
|
9
|
-
import { EditorState, type Extension } from '@codemirror/state';
|
|
10
|
-
import { oneDarkHighlightStyle } from '@codemirror/theme-one-dark';
|
|
9
|
+
import { type ChangeSpec, EditorState, type Extension, type TransactionSpec } from '@codemirror/state';
|
|
11
10
|
import {
|
|
12
11
|
EditorView,
|
|
13
12
|
type KeyBinding,
|
|
@@ -20,6 +19,7 @@ import {
|
|
|
20
19
|
placeholder,
|
|
21
20
|
scrollPastEnd,
|
|
22
21
|
} from '@codemirror/view';
|
|
22
|
+
import { vscodeDarkStyle, vscodeLightStyle } from '@uiw/codemirror-theme-vscode';
|
|
23
23
|
import defaultsDeep from 'lodash.defaultsdeep';
|
|
24
24
|
import merge from 'lodash.merge';
|
|
25
25
|
|
|
@@ -29,7 +29,7 @@ import { type DocAccessor, type Space } from '@dxos/react-client/echo';
|
|
|
29
29
|
import { type Identity } from '@dxos/react-client/halo';
|
|
30
30
|
import { type ThemeMode } from '@dxos/react-ui';
|
|
31
31
|
import { type HuePalette } from '@dxos/react-ui-theme';
|
|
32
|
-
import { hexToHue,
|
|
32
|
+
import { hexToHue, isTruthy } from '@dxos/util';
|
|
33
33
|
|
|
34
34
|
import { editorGutter, editorMonospace } from '../defaults';
|
|
35
35
|
import { type ThemeStyles, defaultTheme } from '../styles';
|
|
@@ -42,7 +42,29 @@ import { focus } from './focus';
|
|
|
42
42
|
// Basic
|
|
43
43
|
//
|
|
44
44
|
|
|
45
|
-
export const
|
|
45
|
+
export const filterChars = (chars: RegExp) => {
|
|
46
|
+
return EditorState.transactionFilter.of((transaction) => {
|
|
47
|
+
if (!transaction.docChanged) return transaction;
|
|
48
|
+
|
|
49
|
+
const changes: ChangeSpec[] = [];
|
|
50
|
+
transaction.changes.iterChanges((fromA, toA, fromB, toB, text) => {
|
|
51
|
+
const inserted = text.toString();
|
|
52
|
+
const filtered = inserted.replace(chars, '');
|
|
53
|
+
if (inserted !== filtered) {
|
|
54
|
+
changes.push({
|
|
55
|
+
from: fromB,
|
|
56
|
+
to: toB,
|
|
57
|
+
insert: filtered,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
if (changes.length) {
|
|
63
|
+
return [transaction, { changes, sequential: true } as TransactionSpec];
|
|
64
|
+
}
|
|
65
|
+
return transaction;
|
|
66
|
+
});
|
|
67
|
+
};
|
|
46
68
|
|
|
47
69
|
/**
|
|
48
70
|
* https://codemirror.net/docs/extensions
|
|
@@ -70,6 +92,7 @@ export type BasicExtensionsOptions = {
|
|
|
70
92
|
/** If true user cannot edit the text, but they can still select and copy it. */
|
|
71
93
|
readOnly?: boolean;
|
|
72
94
|
search?: boolean;
|
|
95
|
+
/** NOTE: Do not use with stack sections. */
|
|
73
96
|
scrollPastEnd?: boolean;
|
|
74
97
|
standardKeymap?: boolean;
|
|
75
98
|
tabSize?: number;
|
|
@@ -139,9 +162,9 @@ export const createBasicExtensions = (_props?: BasicExtensionsOptions): Extensio
|
|
|
139
162
|
preventDefault: true,
|
|
140
163
|
run: () => true,
|
|
141
164
|
},
|
|
142
|
-
].filter(
|
|
165
|
+
].filter(isTruthy),
|
|
143
166
|
),
|
|
144
|
-
].filter(
|
|
167
|
+
].filter(isTruthy);
|
|
145
168
|
};
|
|
146
169
|
|
|
147
170
|
//
|
|
@@ -179,20 +202,26 @@ export const fullWidth: ThemeExtensionsOptions['slots'] = {
|
|
|
179
202
|
|
|
180
203
|
export const defaultThemeSlots = grow;
|
|
181
204
|
|
|
205
|
+
export const defaultStyles = {
|
|
206
|
+
dark: vscodeDarkStyle,
|
|
207
|
+
light: vscodeLightStyle,
|
|
208
|
+
};
|
|
209
|
+
|
|
182
210
|
/**
|
|
183
211
|
* https://codemirror.net/examples/styling
|
|
184
212
|
*/
|
|
185
213
|
export const createThemeExtensions = ({
|
|
186
214
|
themeMode,
|
|
187
215
|
styles,
|
|
188
|
-
syntaxHighlighting:
|
|
189
|
-
slots:
|
|
216
|
+
syntaxHighlighting: syntaxHighlightingProp,
|
|
217
|
+
slots: slotsParam,
|
|
190
218
|
}: ThemeExtensionsOptions = {}): Extension => {
|
|
191
|
-
const slots = defaultsDeep({},
|
|
219
|
+
const slots = defaultsDeep({}, slotsParam, defaultThemeSlots);
|
|
192
220
|
return [
|
|
193
221
|
EditorView.darkTheme.of(themeMode === 'dark'),
|
|
194
222
|
EditorView.baseTheme(styles ? merge({}, defaultTheme, styles) : defaultTheme),
|
|
195
|
-
|
|
223
|
+
syntaxHighlightingProp &&
|
|
224
|
+
syntaxHighlighting(HighlightStyle.define(themeMode === 'dark' ? defaultStyles.dark : defaultStyles.light)),
|
|
196
225
|
slots.editor?.className && EditorView.editorAttributes.of({ class: slots.editor.className }),
|
|
197
226
|
slots.content?.className && EditorView.contentAttributes.of({ class: slots.content.className }),
|
|
198
227
|
slots.scroll?.className &&
|
|
@@ -203,7 +232,7 @@ export const createThemeExtensions = ({
|
|
|
203
232
|
}
|
|
204
233
|
},
|
|
205
234
|
),
|
|
206
|
-
].filter(
|
|
235
|
+
].filter(isTruthy);
|
|
207
236
|
};
|
|
208
237
|
|
|
209
238
|
//
|
package/src/extensions/focus.ts
CHANGED
|
@@ -15,6 +15,7 @@ export const focusField = StateField.define<boolean>({
|
|
|
15
15
|
return effect.value;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
|
|
18
19
|
return value;
|
|
19
20
|
},
|
|
20
21
|
});
|
|
@@ -25,11 +26,11 @@ export const focusField = StateField.define<boolean>({
|
|
|
25
26
|
export const focus = [
|
|
26
27
|
focusField,
|
|
27
28
|
EditorView.domEventHandlers({
|
|
28
|
-
focus: (
|
|
29
|
-
|
|
29
|
+
focus: (_event, view) => {
|
|
30
|
+
requestAnimationFrame(() => view.dispatch({ effects: focusEffect.of(true) }));
|
|
30
31
|
},
|
|
31
|
-
blur: (
|
|
32
|
-
|
|
32
|
+
blur: (_event, view) => {
|
|
33
|
+
requestAnimationFrame(() => view.dispatch({ effects: focusEffect.of(false) }));
|
|
33
34
|
},
|
|
34
35
|
}),
|
|
35
36
|
];
|
|
@@ -7,16 +7,15 @@ import { type Extension } from '@codemirror/state';
|
|
|
7
7
|
import { EditorView } from '@codemirror/view';
|
|
8
8
|
import React from 'react';
|
|
9
9
|
|
|
10
|
-
import { Icon } from '@dxos/react-ui';
|
|
10
|
+
import { Domino, Icon } from '@dxos/react-ui';
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import { renderRoot } from '../util';
|
|
13
13
|
|
|
14
14
|
export type FoldingOptions = {};
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* https://codemirror.net/examples/gutter
|
|
18
18
|
*/
|
|
19
|
-
// TODO(burdon): Remember folding state (to state).
|
|
20
19
|
export const folding = (_props: FoldingOptions = {}): Extension => [
|
|
21
20
|
codeFolding({
|
|
22
21
|
placeholderDOM: () => {
|
|
@@ -25,10 +24,9 @@ export const folding = (_props: FoldingOptions = {}): Extension => [
|
|
|
25
24
|
}),
|
|
26
25
|
foldGutter({
|
|
27
26
|
markerDOM: (open) => {
|
|
28
|
-
// TODO(burdon): Use sprite directly.
|
|
29
|
-
const el = Domino.of('div').classNames('flex h-full items-center').build();
|
|
30
27
|
return renderRoot(
|
|
31
|
-
|
|
28
|
+
Domino.of('div').classNames('flex h-full items-center').build(),
|
|
29
|
+
// TODO(burdon): Use sprite directly.
|
|
32
30
|
<Icon icon='ph--caret-right--bold' size={3} classNames={['mx-3 cursor-pointer', open && 'rotate-90']} />,
|
|
33
31
|
);
|
|
34
32
|
},
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
WidgetType,
|
|
14
14
|
} from '@codemirror/view';
|
|
15
15
|
|
|
16
|
-
import {
|
|
16
|
+
import { getHashStyles, mx } from '@dxos/react-ui-theme';
|
|
17
17
|
|
|
18
18
|
class TagWidget extends WidgetType {
|
|
19
19
|
constructor(private _text: string) {
|
|
@@ -22,7 +22,7 @@ class TagWidget extends WidgetType {
|
|
|
22
22
|
|
|
23
23
|
toDOM(): HTMLSpanElement {
|
|
24
24
|
const span = document.createElement('span');
|
|
25
|
-
span.className = mx('cm-tag',
|
|
25
|
+
span.className = mx('cm-tag', getHashStyles(this._text).surface);
|
|
26
26
|
span.textContent = this._text;
|
|
27
27
|
return span;
|
|
28
28
|
}
|
package/src/extensions/index.ts
CHANGED
|
@@ -8,7 +8,6 @@ export * from './autoscroll';
|
|
|
8
8
|
export * from './automerge';
|
|
9
9
|
export * from './awareness';
|
|
10
10
|
export * from './blast';
|
|
11
|
-
export * from './command';
|
|
12
11
|
export * from './comments';
|
|
13
12
|
export * from './debug';
|
|
14
13
|
export * from './dnd';
|
|
@@ -22,7 +21,9 @@ export * from './markdown';
|
|
|
22
21
|
export * from './mention';
|
|
23
22
|
export * from './modes';
|
|
24
23
|
export * from './outliner';
|
|
24
|
+
export * from './popover';
|
|
25
25
|
export * from './preview';
|
|
26
26
|
export * from './selection';
|
|
27
|
+
export * from './state';
|
|
27
28
|
export * from './tags';
|
|
28
29
|
export * from './typewriter';
|
package/src/extensions/json.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { type LintSource, linter } from '@codemirror/lint';
|
|
|
7
7
|
import { type Extension } from '@codemirror/state';
|
|
8
8
|
import Ajv, { type ValidateFunction } from 'ajv';
|
|
9
9
|
|
|
10
|
-
import { type JsonSchemaType } from '@dxos/echo
|
|
10
|
+
import { type JsonSchemaType } from '@dxos/echo/internal';
|
|
11
11
|
|
|
12
12
|
export type JsonExtensionsOptions = {
|
|
13
13
|
schema?: JsonSchemaType;
|
|
@@ -4,14 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
import { completionKeymap } from '@codemirror/autocomplete';
|
|
6
6
|
import { defaultKeymap, indentWithTab } from '@codemirror/commands';
|
|
7
|
+
import { jsonLanguage } from '@codemirror/lang-json';
|
|
7
8
|
import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
|
|
8
|
-
import {
|
|
9
|
+
import { xml } from '@codemirror/lang-xml';
|
|
10
|
+
import { LanguageDescription, syntaxHighlighting } from '@codemirror/language';
|
|
9
11
|
import { languages } from '@codemirror/language-data';
|
|
10
12
|
import { type Extension } from '@codemirror/state';
|
|
11
13
|
import { keymap } from '@codemirror/view';
|
|
12
14
|
import { type MarkdownConfig } from '@lezer/markdown';
|
|
13
15
|
|
|
14
|
-
import {
|
|
16
|
+
import { isTruthy } from '@dxos/util';
|
|
15
17
|
|
|
16
18
|
import { markdownHighlightStyle, markdownTagsExtensions } from './highlight';
|
|
17
19
|
|
|
@@ -43,6 +45,7 @@ export const createMarkdownExtensions = (options: MarkdownBundleOptions = {}): E
|
|
|
43
45
|
base: markdownLanguage,
|
|
44
46
|
|
|
45
47
|
// Languages for syntax highlighting fenced code blocks.
|
|
48
|
+
defaultCodeLanguage: jsonLanguage,
|
|
46
49
|
codeLanguages: languages,
|
|
47
50
|
|
|
48
51
|
// Don't complete HTML tags.
|
|
@@ -66,12 +69,21 @@ export const createMarkdownExtensions = (options: MarkdownBundleOptions = {}): E
|
|
|
66
69
|
|
|
67
70
|
// https://codemirror.net/docs/ref/#commands.defaultKeymap
|
|
68
71
|
...defaultKeymap,
|
|
72
|
+
|
|
73
|
+
// TODO(burdon): Remove?
|
|
69
74
|
...completionKeymap,
|
|
70
|
-
].filter(
|
|
75
|
+
].filter(isTruthy),
|
|
71
76
|
),
|
|
72
77
|
];
|
|
73
78
|
};
|
|
74
79
|
|
|
80
|
+
const xmlLanguageDesc = LanguageDescription.of({
|
|
81
|
+
name: 'xml',
|
|
82
|
+
alias: ['html', 'xhtml'],
|
|
83
|
+
extensions: ['xml', 'xhtml'],
|
|
84
|
+
load: async () => xml(),
|
|
85
|
+
});
|
|
86
|
+
|
|
75
87
|
/**
|
|
76
88
|
* Default customizations.
|
|
77
89
|
* https://github.com/lezer-parser/markdown/blob/main/src/markdown.ts
|
|
@@ -89,5 +101,5 @@ const noSetExtHeading: MarkdownConfig = {
|
|
|
89
101
|
* Remove HTML and XML parsing.
|
|
90
102
|
*/
|
|
91
103
|
const noHtml: MarkdownConfig = {
|
|
92
|
-
remove: ['HTMLBlock', 'HTMLTag'],
|
|
104
|
+
// remove: ['HTMLBlock', 'HTMLTag'],
|
|
93
105
|
};
|
package/src/extensions/modes.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { singleValueFacet } from '../util';
|
|
|
11
11
|
|
|
12
12
|
export type EditorInputConfig = {
|
|
13
13
|
type?: string;
|
|
14
|
-
|
|
14
|
+
ignoreEscape?: boolean;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
export const editorInputMode = singleValueFacet<EditorInputConfig>({});
|
|
@@ -26,7 +26,7 @@ export const InputModeExtensions: { [mode: string]: Extension } = {
|
|
|
26
26
|
vim: [
|
|
27
27
|
// https://github.com/replit/codemirror-vim
|
|
28
28
|
vim(),
|
|
29
|
-
editorInputMode.of({ type: 'vim',
|
|
29
|
+
editorInputMode.of({ type: 'vim', ignoreEscape: true }),
|
|
30
30
|
keymap.of([
|
|
31
31
|
{
|
|
32
32
|
key: 'Alt-Escape',
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type Extension } from '@codemirror/state';
|
|
5
6
|
import { EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';
|
|
6
7
|
|
|
7
8
|
import { type CleanupFn, addEventListener } from '@dxos/async';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export type FloatingMenuOptions = {
|
|
10
|
+
export type MenuOptions = {
|
|
12
11
|
icon?: string;
|
|
13
12
|
height?: number;
|
|
14
13
|
padding?: number;
|
|
15
14
|
};
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
// TODO(burdon): Replace with popover.
|
|
17
|
+
export const menu = (options: MenuOptions = {}): Extension => [
|
|
18
18
|
ViewPlugin.fromClass(
|
|
19
19
|
class {
|
|
20
20
|
view: EditorView;
|
|
@@ -34,12 +34,10 @@ export const floatingMenu = (options: FloatingMenuOptions = {}) => [
|
|
|
34
34
|
{
|
|
35
35
|
const icon = document.createElement('dx-icon');
|
|
36
36
|
icon.setAttribute('icon', options.icon ?? 'ph--dots-three-vertical--regular');
|
|
37
|
-
const button = document.createElement('button');
|
|
38
|
-
button.appendChild(icon);
|
|
39
37
|
|
|
40
38
|
this.tag = document.createElement('dx-anchor');
|
|
41
|
-
this.tag.classList.add('cm-
|
|
42
|
-
this.tag.appendChild(
|
|
39
|
+
this.tag.classList.add('cm-popover-trigger');
|
|
40
|
+
this.tag.appendChild(icon);
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
container.appendChild(this.tag);
|
|
@@ -65,12 +63,12 @@ export const floatingMenu = (options: FloatingMenuOptions = {}) => [
|
|
|
65
63
|
}
|
|
66
64
|
|
|
67
65
|
// TODO(burdon): Timer to fade in/out.
|
|
68
|
-
if (update.transactions.some((tr) => tr.effects.some((effect) => effect.is(openEffect)))) {
|
|
66
|
+
/*if (update.transactions.some((tr) => tr.effects.some((effect) => effect.is(openEffect)))) {
|
|
69
67
|
this.tag.style.display = 'none';
|
|
70
68
|
this.tag.classList.add('opacity-10');
|
|
71
69
|
} else if (update.transactions.some((tr) => tr.effects.some((effect) => effect.is(closeEffect)))) {
|
|
72
|
-
this.tag.style.display = '
|
|
73
|
-
} else if (
|
|
70
|
+
this.tag.style.display = '';
|
|
71
|
+
} else */ if (
|
|
74
72
|
update.docChanged ||
|
|
75
73
|
update.focusChanged ||
|
|
76
74
|
update.geometryChanged ||
|
|
@@ -99,7 +97,7 @@ export const floatingMenu = (options: FloatingMenuOptions = {}) => [
|
|
|
99
97
|
|
|
100
98
|
this.tag.style.top = `${offsetTop}px`;
|
|
101
99
|
this.tag.style.left = `${offsetLeft}px`;
|
|
102
|
-
this.tag.style.display = '
|
|
100
|
+
this.tag.style.display = '';
|
|
103
101
|
}
|
|
104
102
|
|
|
105
103
|
scheduleUpdate() {
|
|
@@ -113,21 +111,18 @@ export const floatingMenu = (options: FloatingMenuOptions = {}) => [
|
|
|
113
111
|
),
|
|
114
112
|
|
|
115
113
|
EditorView.theme({
|
|
116
|
-
'.cm-
|
|
114
|
+
'.cm-popover-trigger': {
|
|
117
115
|
position: 'fixed',
|
|
118
116
|
padding: '0',
|
|
119
117
|
border: 'none',
|
|
120
118
|
opacity: '0',
|
|
121
|
-
},
|
|
122
|
-
'[data-has-focus] & .cm-ref-tag': {
|
|
123
|
-
opacity: '1',
|
|
124
|
-
},
|
|
125
|
-
'.cm-ref-tag button': {
|
|
126
119
|
display: 'grid',
|
|
127
|
-
|
|
128
|
-
justifyContent: 'center',
|
|
120
|
+
placeContent: 'center',
|
|
129
121
|
width: '2rem',
|
|
130
122
|
height: '2rem',
|
|
131
123
|
},
|
|
124
|
+
'&:focus-within .cm-popover-trigger': {
|
|
125
|
+
opacity: '1',
|
|
126
|
+
},
|
|
132
127
|
}),
|
|
133
128
|
];
|