@dxos/react-ui-editor 0.6.12-staging.e11e696 → 0.6.13-main.041e8aa
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-AZWYO7TE.mjs → chunk-CIQSMP7K.mjs} +3 -3
- package/dist/lib/browser/{chunk-AZWYO7TE.mjs.map → chunk-CIQSMP7K.mjs.map} +2 -2
- package/dist/lib/browser/index.mjs +80 -81
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/state/index.mjs +1 -1
- package/dist/lib/node/{chunk-5RSKGJRI.cjs → chunk-GZWIENFM.cjs} +6 -6
- package/dist/lib/node/{chunk-5RSKGJRI.cjs.map → chunk-GZWIENFM.cjs.map} +2 -2
- package/dist/lib/node/index.cjs +108 -108
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/state/index.cjs +7 -7
- package/dist/lib/node/state/index.cjs.map +1 -1
- package/dist/lib/node-esm/{chunk-RCIWLRIY.mjs → chunk-GP5RCZ3X.mjs} +3 -3
- package/dist/lib/node-esm/{chunk-RCIWLRIY.mjs.map → chunk-GP5RCZ3X.mjs.map} +2 -2
- package/dist/lib/node-esm/index.mjs +80 -81
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/state/index.mjs +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts +1 -0
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/state/state.d.ts +2 -2
- package/dist/types/src/state/state.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +6 -0
- package/dist/types/src/util.d.ts.map +1 -1
- package/package.json +28 -24
- package/src/extensions/command/hint.ts +1 -1
- package/src/extensions/comments.ts +7 -2
- package/src/extensions/listener.ts +1 -0
- package/src/hooks/useTextEditor.ts +28 -30
- package/src/state/state.ts +6 -3
- package/src/util.ts +10 -0
@@ -20,8 +20,8 @@ import { log } from '@dxos/log';
|
|
20
20
|
import { getProviderValue, isNotFalsy, type MaybeProvider } from '@dxos/util';
|
21
21
|
|
22
22
|
import { editorInputMode } from '../extensions';
|
23
|
-
import { type EditorSelection,
|
24
|
-
import {
|
23
|
+
import { type EditorSelection, documentId, createEditorStateTransaction } from '../state';
|
24
|
+
import { debugDispatcher } from '../util';
|
25
25
|
|
26
26
|
export type UseTextEditor = {
|
27
27
|
// TODO(burdon): Rename.
|
@@ -67,8 +67,6 @@ export const useTextEditor = (
|
|
67
67
|
|
68
68
|
// NOTE: Increments by 2 in strict mode.
|
69
69
|
const [instanceId] = useState(() => `text-editor-${++instanceCount}`);
|
70
|
-
// Callback once view is created.
|
71
|
-
const onUpdate = useRef<() => void>();
|
72
70
|
const [view, setView] = useState<EditorView>();
|
73
71
|
const parentRef = useRef<HTMLDivElement>(null);
|
74
72
|
|
@@ -89,22 +87,28 @@ export const useTextEditor = (
|
|
89
87
|
}
|
90
88
|
|
91
89
|
// https://codemirror.net/docs/ref/#state.EditorStateConfig
|
92
|
-
// NOTE: Don't set selection here in case it is invalid (and crashes the state); dispatch below.
|
93
90
|
const state = EditorState.create({
|
94
91
|
doc: initialValue,
|
95
92
|
selection: initialSelection,
|
96
93
|
extensions: [
|
97
94
|
id && documentId.of(id),
|
98
|
-
|
95
|
+
extensions,
|
96
|
+
// NOTE: This doesn't catch errors in keymap functions.
|
99
97
|
EditorView.exceptionSink.of((err) => {
|
100
98
|
log.catch(err);
|
101
99
|
}),
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
}
|
100
|
+
// TODO(burdon): Factor out debug inspector.
|
101
|
+
// ViewPlugin.fromClass(
|
102
|
+
// class {
|
103
|
+
// constructor(_view: EditorView) {
|
104
|
+
// log('construct', { id });
|
105
|
+
// }
|
106
|
+
//
|
107
|
+
// destroy() {
|
108
|
+
// log('destroy', { id });
|
109
|
+
// }
|
110
|
+
// },
|
111
|
+
// ),
|
108
112
|
].filter(isNotFalsy),
|
109
113
|
});
|
110
114
|
|
@@ -112,20 +116,16 @@ export const useTextEditor = (
|
|
112
116
|
view = new EditorView({
|
113
117
|
parent: parentRef.current,
|
114
118
|
state,
|
115
|
-
|
116
|
-
|
117
|
-
dispatchTransactions: (trs, view) => {
|
118
|
-
if (debug) {
|
119
|
-
logChanges(trs);
|
120
|
-
}
|
121
|
-
view.update(trs);
|
122
|
-
},
|
119
|
+
scrollTo: scrollTo ? EditorView.scrollIntoView(scrollTo, { yMargin: 96 }) : undefined,
|
120
|
+
dispatchTransactions: debug ? debugDispatcher : undefined,
|
123
121
|
});
|
124
122
|
|
125
|
-
// Move to end of line after document loaded.
|
126
|
-
if (
|
123
|
+
// Move to end of line after document loaded (unless selection is specified).
|
124
|
+
if (moveToEndOfLine && !initialSelection) {
|
127
125
|
const { to } = view.state.doc.lineAt(0);
|
128
|
-
|
126
|
+
if (to) {
|
127
|
+
view.dispatch({ selection: { anchor: to } });
|
128
|
+
}
|
129
129
|
}
|
130
130
|
|
131
131
|
setView(view);
|
@@ -139,18 +139,16 @@ export const useTextEditor = (
|
|
139
139
|
|
140
140
|
useEffect(() => {
|
141
141
|
if (view) {
|
142
|
-
// NOTE: Set selection after first update (since content may rerender on focus).
|
143
|
-
onUpdate.current = () => {
|
144
|
-
onUpdate.current = undefined;
|
145
|
-
view.dispatch(createEditorStateTransaction({ scrollTo, selection }));
|
146
|
-
};
|
147
|
-
|
148
142
|
// Remove tabster attribute (rely on custom keymap).
|
149
143
|
if (view.state.facet(editorInputMode).noTabster) {
|
150
144
|
parentRef.current?.removeAttribute('data-tabster');
|
151
145
|
}
|
146
|
+
|
147
|
+
if (scrollTo || selection) {
|
148
|
+
view.dispatch(createEditorStateTransaction(view.state, { scrollTo, selection }));
|
149
|
+
}
|
152
150
|
}
|
153
|
-
}, [view,
|
151
|
+
}, [view, scrollTo, selection]);
|
154
152
|
|
155
153
|
useEffect(() => {
|
156
154
|
if (view && autoFocus) {
|
package/src/state/state.ts
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
// Copyright 2024 DXOS.org
|
3
3
|
//
|
4
4
|
|
5
|
-
import { type Extension, Transaction, type TransactionSpec } from '@codemirror/state';
|
5
|
+
import { type EditorState, type Extension, Transaction, type TransactionSpec } from '@codemirror/state';
|
6
6
|
import { EditorView, keymap } from '@codemirror/view';
|
7
7
|
|
8
8
|
import { debounce } from '@dxos/async';
|
@@ -42,7 +42,10 @@ export const localStorageStateStoreAdapter: EditorStateOptions = {
|
|
42
42
|
},
|
43
43
|
};
|
44
44
|
|
45
|
-
export const createEditorStateTransaction = (
|
45
|
+
export const createEditorStateTransaction = (
|
46
|
+
state: EditorState,
|
47
|
+
{ scrollTo, selection }: EditorSelectionState,
|
48
|
+
): TransactionSpec => {
|
46
49
|
return {
|
47
50
|
selection,
|
48
51
|
scrollIntoView: !scrollTo,
|
@@ -87,7 +90,7 @@ export const state = ({ getState, setState }: Partial<EditorStateOptions> = {}):
|
|
87
90
|
run: (view) => {
|
88
91
|
const state = getState(view.state.facet(documentId));
|
89
92
|
if (state) {
|
90
|
-
view.dispatch(createEditorStateTransaction(state));
|
93
|
+
view.dispatch(createEditorStateTransaction(view.state, state));
|
91
94
|
}
|
92
95
|
return true;
|
93
96
|
},
|
package/src/util.ts
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
//
|
4
4
|
|
5
5
|
import type { Transaction } from '@codemirror/state';
|
6
|
+
import { type EditorView } from '@codemirror/view';
|
6
7
|
|
7
8
|
import { log } from '@dxos/log';
|
8
9
|
|
@@ -19,6 +20,15 @@ export const callbackWrapper = <T extends Function>(fn: T): T =>
|
|
19
20
|
}
|
20
21
|
}) as unknown as T;
|
21
22
|
|
23
|
+
/**
|
24
|
+
* Log all changes before dispatching them to the view.
|
25
|
+
* https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
26
|
+
*/
|
27
|
+
export const debugDispatcher = (trs: readonly Transaction[], view: EditorView) => {
|
28
|
+
logChanges(trs);
|
29
|
+
view.update(trs);
|
30
|
+
};
|
31
|
+
|
22
32
|
export const logChanges = (trs: readonly Transaction[]) => {
|
23
33
|
const changes = trs
|
24
34
|
.flatMap((tr) => {
|