@dxos/react-ui-editor 0.3.10-main.6ba804d → 0.3.10-main.74608f1
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 +126 -37
- 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.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts +10 -6
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/demo.d.ts +10 -0
- package/dist/types/src/components/TextEditor/extensions/demo.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts +1 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/listener.d.ts +4 -2
- package/dist/types/src/components/TextEditor/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts +3 -0
- package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts +8 -1
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/index.d.ts +1 -1
- package/dist/types/src/hooks/automerge/index.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/plugin.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts +5 -0
- package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts.map +1 -0
- package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts +6 -0
- package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts.map +1 -0
- package/dist/types/src/hooks/automerge/translation/index.d.ts +3 -0
- package/dist/types/src/hooks/automerge/translation/index.d.ts.map +1 -0
- package/package.json +20 -19
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +4 -2
- package/src/components/TextEditor/TextEditor.tsx +18 -4
- package/src/components/TextEditor/extensions/comments.ts +48 -31
- package/src/components/TextEditor/extensions/demo.ts +66 -0
- package/src/components/TextEditor/extensions/index.ts +1 -0
- package/src/components/TextEditor/extensions/listener.ts +2 -2
- package/src/components/TextEditor/extensions/markdown/bundle.ts +9 -6
- package/src/hooks/automerge/PatchSemaphore.ts +12 -9
- package/src/hooks/automerge/automerge.stories.tsx +3 -2
- package/src/hooks/automerge/index.ts +1 -1
- package/src/hooks/automerge/plugin.ts +1 -0
- package/src/hooks/automerge/{amToCodemirror.ts → translation/automerge-to-codemirror.ts} +10 -2
- package/src/hooks/automerge/{codeMirrorToAm.ts → translation/codemirror-to-automerge.ts} +7 -4
- package/src/hooks/automerge/translation/index.ts +6 -0
- package/dist/types/src/hooks/automerge/amToCodemirror.d.ts +0 -6
- package/dist/types/src/hooks/automerge/amToCodemirror.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge/codeMirrorToAm.d.ts +0 -7
- package/dist/types/src/hooks/automerge/codeMirrorToAm.d.ts.map +0 -1
|
@@ -54,8 +54,66 @@ var basicBundle = ({ themeMode, placeholder: _placeholder }) => [
|
|
|
54
54
|
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
|
|
55
55
|
].filter(Boolean);
|
|
56
56
|
|
|
57
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/demo.ts
|
|
58
|
+
import { keymap as keymap2 } from "@codemirror/view";
|
|
59
|
+
var defaultItems = [
|
|
60
|
+
"hello world!",
|
|
61
|
+
"this is a test.",
|
|
62
|
+
"this is [DXOS](https://dxos.org)"
|
|
63
|
+
];
|
|
64
|
+
var demo = ({ delay = 75, items = defaultItems } = {}) => {
|
|
65
|
+
let t;
|
|
66
|
+
let idx = 0;
|
|
67
|
+
return [
|
|
68
|
+
keymap2.of([
|
|
69
|
+
{
|
|
70
|
+
// Reset.
|
|
71
|
+
key: "alt-meta-'",
|
|
72
|
+
run: (view) => {
|
|
73
|
+
clearTimeout(t);
|
|
74
|
+
idx = 0;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
// Next prompt.
|
|
80
|
+
// TODO(burdon): Press 1-9 to select prompt?
|
|
81
|
+
key: "shift-meta-'",
|
|
82
|
+
run: (view) => {
|
|
83
|
+
clearTimeout(t);
|
|
84
|
+
const text = items[idx++];
|
|
85
|
+
if (idx === items?.length) {
|
|
86
|
+
idx = 0;
|
|
87
|
+
}
|
|
88
|
+
let i = 0;
|
|
89
|
+
const insert = (d = 0) => {
|
|
90
|
+
t = setTimeout(() => {
|
|
91
|
+
const pos = view.state.selection.main.head;
|
|
92
|
+
view.dispatch({
|
|
93
|
+
changes: {
|
|
94
|
+
from: pos,
|
|
95
|
+
insert: text[i++]
|
|
96
|
+
},
|
|
97
|
+
selection: {
|
|
98
|
+
anchor: pos + 1
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
if (i < text.length) {
|
|
102
|
+
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
103
|
+
}
|
|
104
|
+
}, d);
|
|
105
|
+
};
|
|
106
|
+
insert();
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
])
|
|
111
|
+
];
|
|
112
|
+
};
|
|
113
|
+
|
|
57
114
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts
|
|
58
|
-
import { Decoration, EditorView as EditorView2,
|
|
115
|
+
import { keymap as keymap3, Decoration, EditorView as EditorView2, MatchDecorator, ViewPlugin, WidgetType } from "@codemirror/view";
|
|
116
|
+
import { debounce } from "@dxos/async";
|
|
59
117
|
import { invariant } from "@dxos/invariant";
|
|
60
118
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts";
|
|
61
119
|
var BookmarkWidget = class extends WidgetType {
|
|
@@ -65,7 +123,7 @@ var BookmarkWidget = class extends WidgetType {
|
|
|
65
123
|
this._id = _id;
|
|
66
124
|
invariant(this._id, void 0, {
|
|
67
125
|
F: __dxlog_file,
|
|
68
|
-
L:
|
|
126
|
+
L: 41,
|
|
69
127
|
S: this,
|
|
70
128
|
A: [
|
|
71
129
|
"this._id",
|
|
@@ -76,7 +134,6 @@ var BookmarkWidget = class extends WidgetType {
|
|
|
76
134
|
eq(other) {
|
|
77
135
|
return this._id === other._id;
|
|
78
136
|
}
|
|
79
|
-
// TODO(burdon): Click to select.
|
|
80
137
|
toDOM() {
|
|
81
138
|
const span = document.createElement("span");
|
|
82
139
|
span.className = "cm-bookmark";
|
|
@@ -90,9 +147,13 @@ var styles = EditorView2.baseTheme({
|
|
|
90
147
|
margin: "4px",
|
|
91
148
|
padding: "4px",
|
|
92
149
|
backgroundColor: "yellow"
|
|
150
|
+
},
|
|
151
|
+
"& .cm-bookmark-selected": {
|
|
152
|
+
backgroundColor: "orange"
|
|
93
153
|
}
|
|
94
154
|
});
|
|
95
155
|
var comments = (options = {}) => {
|
|
156
|
+
let active;
|
|
96
157
|
const bookmarkMatcher = new MatchDecorator({
|
|
97
158
|
regexp: /\[\^(\w+)\]/g,
|
|
98
159
|
decoration: (match, view, pos) => {
|
|
@@ -116,10 +177,13 @@ var comments = (options = {}) => {
|
|
|
116
177
|
return view.plugin(plugin)?.bookmarks || Decoration.none;
|
|
117
178
|
})
|
|
118
179
|
});
|
|
180
|
+
const doUpdate = debounce((data) => {
|
|
181
|
+
options.onUpdate?.(data);
|
|
182
|
+
}, 200);
|
|
119
183
|
return [
|
|
120
|
-
|
|
184
|
+
keymap3.of([
|
|
121
185
|
{
|
|
122
|
-
key: options?.key ?? "
|
|
186
|
+
key: options?.key ?? "shift-meta-c",
|
|
123
187
|
run: (view) => {
|
|
124
188
|
const id = options.onCreate?.();
|
|
125
189
|
if (id) {
|
|
@@ -143,30 +207,40 @@ var comments = (options = {}) => {
|
|
|
143
207
|
bookmarks,
|
|
144
208
|
// Monitor cursor movement.
|
|
145
209
|
EditorView2.updateListener.of((update2) => {
|
|
210
|
+
active = void 0;
|
|
211
|
+
if (!options.onUpdate) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
146
214
|
const view = update2.view;
|
|
147
215
|
const pos = view.state.selection.main.head;
|
|
148
216
|
const decorations = [];
|
|
149
217
|
const rangeSet = view.plugin(bookmarks)?.bookmarks;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
218
|
+
let closest = Infinity;
|
|
219
|
+
const { from, to } = view.visibleRanges?.[0] ?? {
|
|
220
|
+
from: 0,
|
|
221
|
+
to: view.state.doc.length
|
|
222
|
+
};
|
|
223
|
+
rangeSet?.between(from, to, (from2, to2, value) => {
|
|
224
|
+
decorations.push({
|
|
225
|
+
from: from2,
|
|
226
|
+
to: to2,
|
|
227
|
+
value
|
|
228
|
+
});
|
|
229
|
+
const d = Math.min(Math.abs(pos - from2), Math.abs(pos - to2));
|
|
230
|
+
if (d < closest) {
|
|
231
|
+
active = value.spec.id;
|
|
232
|
+
closest = d;
|
|
157
233
|
}
|
|
158
234
|
});
|
|
159
235
|
if (decorations.length) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
});
|
|
169
|
-
}
|
|
236
|
+
doUpdate({
|
|
237
|
+
active,
|
|
238
|
+
items: decorations.map(({ from: from2, value: { spec: { id } } }) => ({
|
|
239
|
+
id,
|
|
240
|
+
pos: from2,
|
|
241
|
+
location: view.coordsAtPos(from2)
|
|
242
|
+
}))
|
|
243
|
+
});
|
|
170
244
|
}
|
|
171
245
|
}),
|
|
172
246
|
styles
|
|
@@ -262,7 +336,7 @@ var link = (options = {}) => {
|
|
|
262
336
|
|
|
263
337
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/listener.ts
|
|
264
338
|
import { StateField as StateField2 } from "@codemirror/state";
|
|
265
|
-
var listener = (onChange) => StateField2.define({
|
|
339
|
+
var listener = ({ onChange }) => StateField2.define({
|
|
266
340
|
create: () => null,
|
|
267
341
|
update: (_value, transaction) => {
|
|
268
342
|
if (transaction.docChanged && onChange) {
|
|
@@ -274,14 +348,14 @@ var listener = (onChange) => StateField2.define({
|
|
|
274
348
|
|
|
275
349
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/bundle.ts
|
|
276
350
|
import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
277
|
-
import { defaultKeymap, history, indentWithTab } from "@codemirror/commands";
|
|
351
|
+
import { defaultKeymap, history, historyKeymap, indentWithTab } from "@codemirror/commands";
|
|
278
352
|
import { markdownLanguage as markdownLanguage2, markdown } from "@codemirror/lang-markdown";
|
|
279
353
|
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
280
354
|
import { languages } from "@codemirror/language-data";
|
|
281
355
|
import { highlightSelectionMatches, searchKeymap } from "@codemirror/search";
|
|
282
356
|
import { EditorState } from "@codemirror/state";
|
|
283
357
|
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
284
|
-
import { crosshairCursor, drawSelection, dropCursor, EditorView as EditorView4, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, keymap as
|
|
358
|
+
import { crosshairCursor, drawSelection, dropCursor, EditorView as EditorView4, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, keymap as keymap4, placeholder as placeholder2, rectangularSelection } from "@codemirror/view";
|
|
285
359
|
|
|
286
360
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/highlight.ts
|
|
287
361
|
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
@@ -490,14 +564,17 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
490
564
|
history(),
|
|
491
565
|
indentOnInput(),
|
|
492
566
|
rectangularSelection(),
|
|
493
|
-
//
|
|
494
|
-
|
|
495
|
-
|
|
567
|
+
// https://codemirror.net/docs/ref/#view.keymap
|
|
568
|
+
keymap4.of([
|
|
569
|
+
// https://codemirror.net/docs/ref/#commands.defaultKeymap
|
|
496
570
|
...defaultKeymap,
|
|
497
|
-
//
|
|
498
|
-
|
|
499
|
-
//
|
|
571
|
+
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
572
|
+
...historyKeymap,
|
|
573
|
+
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
574
|
+
...closeBracketsKeymap,
|
|
575
|
+
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
500
576
|
...searchKeymap,
|
|
577
|
+
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
501
578
|
indentWithTab
|
|
502
579
|
]),
|
|
503
580
|
// Main extension.
|
|
@@ -926,6 +1003,15 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
926
1003
|
onKeyUp: handleKeyUp
|
|
927
1004
|
});
|
|
928
1005
|
});
|
|
1006
|
+
var maybeDebug = () => {
|
|
1007
|
+
const items = localStorage.getItem("dxos.composer.demo");
|
|
1008
|
+
if (items) {
|
|
1009
|
+
return demo({
|
|
1010
|
+
items: items.split(",")
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
return [];
|
|
1014
|
+
};
|
|
929
1015
|
var TextEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
930
1016
|
const { themeMode } = useThemeContext();
|
|
931
1017
|
const slots = defaultsDeep({}, _slots, defaultTextSlots);
|
|
@@ -936,6 +1022,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, .
|
|
|
936
1022
|
themeMode,
|
|
937
1023
|
placeholder: slots?.editor?.placeholder
|
|
938
1024
|
}),
|
|
1025
|
+
maybeDebug(),
|
|
939
1026
|
...extensions
|
|
940
1027
|
],
|
|
941
1028
|
slots,
|
|
@@ -952,6 +1039,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slot
|
|
|
952
1039
|
themeMode,
|
|
953
1040
|
placeholder: slots?.editor?.placeholder
|
|
954
1041
|
}),
|
|
1042
|
+
maybeDebug(),
|
|
955
1043
|
...extensions
|
|
956
1044
|
],
|
|
957
1045
|
slots,
|
|
@@ -991,9 +1079,9 @@ import * as automerge2 from "@dxos/automerge/automerge";
|
|
|
991
1079
|
// packages/ui/react-ui-editor/src/hooks/automerge/PatchSemaphore.ts
|
|
992
1080
|
import { next as automerge } from "@dxos/automerge/automerge";
|
|
993
1081
|
|
|
994
|
-
// packages/ui/react-ui-editor/src/hooks/automerge/
|
|
1082
|
+
// packages/ui/react-ui-editor/src/hooks/automerge/translation/automerge-to-codemirror.ts
|
|
995
1083
|
import { ChangeSet } from "@codemirror/state";
|
|
996
|
-
var
|
|
1084
|
+
var automergeToCodemirror = (view, selection, target, patches) => {
|
|
997
1085
|
for (const patch of patches) {
|
|
998
1086
|
const changeSpec = handlePatch(patch, target, view.state);
|
|
999
1087
|
if (changeSpec != null) {
|
|
@@ -1098,9 +1186,9 @@ var charPath = (textPath, candidatePath) => {
|
|
|
1098
1186
|
return null;
|
|
1099
1187
|
};
|
|
1100
1188
|
|
|
1101
|
-
// packages/ui/react-ui-editor/src/hooks/automerge/
|
|
1189
|
+
// packages/ui/react-ui-editor/src/hooks/automerge/translation/codemirror-to-automerge.ts
|
|
1102
1190
|
import { next as am } from "@dxos/automerge/automerge";
|
|
1103
|
-
var
|
|
1191
|
+
var codemirrorToAutomerge = (field, handle, transactions, state) => {
|
|
1104
1192
|
const { lastHeads, path } = state.field(field);
|
|
1105
1193
|
let hasChanges = false;
|
|
1106
1194
|
for (const tr of transactions) {
|
|
@@ -1144,12 +1232,12 @@ var PatchSemaphore = class {
|
|
|
1144
1232
|
annotations: reconcileAnnotationType.of(true)
|
|
1145
1233
|
});
|
|
1146
1234
|
}
|
|
1147
|
-
let newHeads =
|
|
1235
|
+
let newHeads = codemirrorToAutomerge(this._field, handle, transactions, view.state);
|
|
1148
1236
|
if (newHeads === null || newHeads === void 0) {
|
|
1149
1237
|
newHeads = automerge.getHeads(handle.docSync());
|
|
1150
1238
|
}
|
|
1151
1239
|
const diff = automerge.equals(oldHeads, newHeads) ? [] : automerge.diff(handle.docSync(), oldHeads, newHeads);
|
|
1152
|
-
|
|
1240
|
+
automergeToCodemirror(view, selection, path, diff);
|
|
1153
1241
|
view.dispatch({
|
|
1154
1242
|
effects: updateHeads(newHeads),
|
|
1155
1243
|
annotations: reconcileAnnotationType.of({})
|
|
@@ -1465,6 +1553,7 @@ export {
|
|
|
1465
1553
|
defaultSlots,
|
|
1466
1554
|
defaultTextSlots,
|
|
1467
1555
|
defaultTheme,
|
|
1556
|
+
demo,
|
|
1468
1557
|
link,
|
|
1469
1558
|
listener,
|
|
1470
1559
|
markdownBundle,
|