@dxos/react-ui-editor 0.3.11-main.690ca41 → 0.3.11-main.695e6e6
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 +201 -334
- 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 +6 -2
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +12 -17
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +6 -6
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/comments.stories.d.ts +26 -0
- package/dist/types/src/components/TextEditor/comments.stories.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/yjs.stories.d.ts +1 -1
- package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/index.d.ts +1 -0
- package/dist/types/src/extensions/automerge/index.d.ts.map +1 -1
- package/dist/types/src/extensions/code.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +2 -2
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/{util → extensions}/cursor.d.ts +9 -1
- package/dist/types/src/extensions/cursor.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +1 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/yjs/cursor.d.ts +1 -1
- package/dist/types/src/extensions/yjs/cursor.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextModel.d.ts +0 -5
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/hooks/yjs.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/dist/types/src/util.d.ts.map +1 -0
- package/package.json +23 -22
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +19 -16
- package/src/components/TextEditor/TextEditor.stories.tsx +12 -46
- package/src/components/TextEditor/TextEditor.tsx +68 -64
- package/src/components/TextEditor/comments.stories.tsx +315 -0
- package/src/extensions/autocomplete.ts +18 -17
- package/src/extensions/automerge/automerge.ts +2 -2
- package/src/extensions/automerge/cursor.ts +2 -1
- package/src/extensions/automerge/index.ts +1 -0
- package/src/extensions/awareness.ts +25 -32
- package/src/extensions/code.ts +10 -2
- package/src/extensions/comments.ts +20 -115
- package/src/extensions/cursor.ts +46 -0
- package/src/extensions/hr.ts +2 -2
- package/src/extensions/image.ts +2 -2
- package/src/extensions/index.ts +1 -0
- package/src/extensions/link.ts +4 -4
- package/src/extensions/markdown/highlight.ts +0 -8
- package/src/extensions/table.ts +6 -3
- package/src/extensions/tasklist.ts +2 -2
- package/src/extensions/yjs/cursor.ts +2 -1
- package/src/extensions/yjs/yjs.ts +2 -2
- package/src/hooks/useTextModel.ts +4 -7
- package/src/hooks/yjs.ts +1 -23
- package/src/index.ts +2 -0
- package/src/styles/markdown.ts +0 -2
- package/src/themes/default.ts +17 -50
- package/dist/types/src/util/cursor.d.ts.map +0 -1
- package/dist/types/src/util/index.d.ts +0 -3
- package/dist/types/src/util/index.d.ts.map +0 -1
- package/dist/types/src/util/util.d.ts.map +0 -1
- package/src/util/cursor.ts +0 -29
- package/src/util/index.ts +0 -6
- /package/dist/types/src/{util/util.d.ts → util.d.ts} +0 -0
- /package/src/{util/util.ts → util.ts} +0 -0
|
@@ -11,40 +11,41 @@ import { EditorView as EditorView12 } from "@codemirror/view";
|
|
|
11
11
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
12
12
|
import { vim } from "@replit/codemirror-vim";
|
|
13
13
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
14
|
-
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from "react";
|
|
14
|
+
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState, useRef } from "react";
|
|
15
15
|
import { generateName } from "@dxos/display-name";
|
|
16
16
|
import { useThemeContext } from "@dxos/react-ui";
|
|
17
17
|
import { getColorForValue, inputSurface, mx as mx3 } from "@dxos/react-ui-theme";
|
|
18
18
|
|
|
19
19
|
// packages/ui/react-ui-editor/src/extensions/autocomplete.ts
|
|
20
20
|
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
21
|
+
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
21
22
|
import { keymap } from "@codemirror/view";
|
|
22
23
|
var autocomplete = ({ onSearch }) => {
|
|
23
24
|
return [
|
|
24
25
|
// https://codemirror.net/docs/ref/#view.keymap
|
|
25
26
|
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
|
27
|
+
// TODO(burdon): Set custom keymap.
|
|
26
28
|
keymap.of(completionKeymap),
|
|
27
29
|
// https://codemirror.net/examples/autocompletion
|
|
28
30
|
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
|
29
31
|
autocompletion({
|
|
30
|
-
|
|
31
|
-
// defaultKeymap: false,
|
|
32
|
+
defaultKeymap: false,
|
|
32
33
|
// Don't start unless key press.
|
|
33
|
-
activateOnTyping: false
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
from: match.from,
|
|
44
|
-
options: onSearch(match.text.toLowerCase())
|
|
45
|
-
};
|
|
34
|
+
activateOnTyping: false
|
|
35
|
+
}),
|
|
36
|
+
// TODO(burdon): Option to create new page?
|
|
37
|
+
// TODO(burdon): Optional decoration via addToOptions
|
|
38
|
+
markdownLanguage.data.of({
|
|
39
|
+
autocomplete: (context) => {
|
|
40
|
+
const match = context.matchBefore(/\w*/);
|
|
41
|
+
if (!match || match.from === match.to && !context.explicit) {
|
|
42
|
+
return null;
|
|
46
43
|
}
|
|
47
|
-
|
|
44
|
+
return {
|
|
45
|
+
from: match.from,
|
|
46
|
+
options: onSearch(match.text.toLowerCase())
|
|
47
|
+
};
|
|
48
|
+
}
|
|
48
49
|
})
|
|
49
50
|
];
|
|
50
51
|
};
|
|
@@ -273,30 +274,39 @@ var PatchSemaphore = class {
|
|
|
273
274
|
}
|
|
274
275
|
};
|
|
275
276
|
|
|
276
|
-
// packages/ui/react-ui-editor/src/
|
|
277
|
+
// packages/ui/react-ui-editor/src/extensions/cursor.ts
|
|
277
278
|
import { Facet } from "@codemirror/state";
|
|
278
|
-
var
|
|
279
|
+
var defaultCursorConverter = {
|
|
279
280
|
toCursor: (position) => position.toString(),
|
|
280
281
|
fromCursor: (cursor) => parseInt(cursor)
|
|
281
282
|
};
|
|
282
|
-
var
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
// packages/ui/react-ui-editor/src/util/util.ts
|
|
287
|
-
import { log } from "@dxos/log";
|
|
288
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/util.ts";
|
|
289
|
-
var callbackWrapper = (fn) => (...args) => {
|
|
290
|
-
try {
|
|
291
|
-
return fn(...args);
|
|
292
|
-
} catch (error) {
|
|
293
|
-
log.catch(error, void 0, {
|
|
294
|
-
F: __dxlog_file,
|
|
295
|
-
L: 16,
|
|
296
|
-
S: void 0,
|
|
297
|
-
C: (f, a) => f(...a)
|
|
283
|
+
var Cursor = class {
|
|
284
|
+
static {
|
|
285
|
+
this.converter = Facet.define({
|
|
286
|
+
combine: (providers) => providers[0] ?? defaultCursorConverter
|
|
298
287
|
});
|
|
299
288
|
}
|
|
289
|
+
static {
|
|
290
|
+
this.getCursorFromRange = (cursorConverter3, range) => {
|
|
291
|
+
const from = cursorConverter3.toCursor(range.from);
|
|
292
|
+
const to = cursorConverter3.toCursor(range.to, -1);
|
|
293
|
+
return [
|
|
294
|
+
from,
|
|
295
|
+
to
|
|
296
|
+
].join(":");
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
static {
|
|
300
|
+
this.getRangeFromCursor = (cursorConverter3, cursor) => {
|
|
301
|
+
const parts = cursor.split(":");
|
|
302
|
+
const from = cursorConverter3.fromCursor(parts[0]);
|
|
303
|
+
const to = cursorConverter3.fromCursor(parts[1]);
|
|
304
|
+
return from !== void 0 && to !== void 0 ? {
|
|
305
|
+
from,
|
|
306
|
+
to
|
|
307
|
+
} : void 0;
|
|
308
|
+
};
|
|
309
|
+
}
|
|
300
310
|
};
|
|
301
311
|
|
|
302
312
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
|
@@ -355,7 +365,7 @@ var automerge3 = ({ handle, path }) => {
|
|
|
355
365
|
});
|
|
356
366
|
return {
|
|
357
367
|
extension: [
|
|
358
|
-
|
|
368
|
+
Cursor.converter.of(cursorConverter(handle, path)),
|
|
359
369
|
semaphoreFacet.of(semaphore),
|
|
360
370
|
stateField,
|
|
361
371
|
viewPlugin
|
|
@@ -397,7 +407,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
397
407
|
this._ctx = new Context();
|
|
398
408
|
this._lastAnchor = void 0;
|
|
399
409
|
this._lastHead = void 0;
|
|
400
|
-
this._cursorConverter = view.state.facet(
|
|
410
|
+
this._cursorConverter = view.state.facet(Cursor.converter);
|
|
401
411
|
this._provider = view.state.facet(AwarenessProvider);
|
|
402
412
|
this._provider.open();
|
|
403
413
|
this._provider.remoteStateChange.on(this._ctx, () => {
|
|
@@ -452,7 +462,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
452
462
|
attributes: {
|
|
453
463
|
style: `background-color: ${lightColor}`
|
|
454
464
|
},
|
|
455
|
-
class: "cm-
|
|
465
|
+
class: "cm-collab-selection"
|
|
456
466
|
})
|
|
457
467
|
});
|
|
458
468
|
} else {
|
|
@@ -463,7 +473,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
463
473
|
attributes: {
|
|
464
474
|
style: `background-color: ${color}`
|
|
465
475
|
},
|
|
466
|
-
class: "cm-
|
|
476
|
+
class: "cm-collab-selection"
|
|
467
477
|
})
|
|
468
478
|
});
|
|
469
479
|
decorations.push({
|
|
@@ -473,7 +483,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
473
483
|
attributes: {
|
|
474
484
|
style: `background-color: ${color}`
|
|
475
485
|
},
|
|
476
|
-
class: "cm-
|
|
486
|
+
class: "cm-collab-selection"
|
|
477
487
|
})
|
|
478
488
|
});
|
|
479
489
|
for (let i = startLine.number + 1; i < endLine.number; i++) {
|
|
@@ -484,7 +494,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
484
494
|
value: Decoration.line({
|
|
485
495
|
attributes: {
|
|
486
496
|
style: `background-color: ${color}`,
|
|
487
|
-
class: "cm-
|
|
497
|
+
class: "cm-collab-selectionLine"
|
|
488
498
|
}
|
|
489
499
|
})
|
|
490
500
|
});
|
|
@@ -504,23 +514,21 @@ var RemoteSelectionsDecorator = class {
|
|
|
504
514
|
}
|
|
505
515
|
};
|
|
506
516
|
var RemoteCaretWidget = class extends WidgetType {
|
|
507
|
-
constructor(
|
|
517
|
+
constructor(_name, _color) {
|
|
508
518
|
super();
|
|
509
|
-
this.
|
|
510
|
-
this.
|
|
511
|
-
this.name = name;
|
|
512
|
-
this.color = color;
|
|
519
|
+
this._name = _name;
|
|
520
|
+
this._color = _color;
|
|
513
521
|
}
|
|
514
522
|
toDOM() {
|
|
515
523
|
const span = document.createElement("span");
|
|
516
|
-
span.className = "cm-
|
|
517
|
-
span.style.backgroundColor = this.
|
|
518
|
-
span.style.borderColor = this.
|
|
524
|
+
span.className = "cm-collab-selectionCaret";
|
|
525
|
+
span.style.backgroundColor = this._color;
|
|
526
|
+
span.style.borderColor = this._color;
|
|
519
527
|
const dot = document.createElement("div");
|
|
520
|
-
dot.className = "cm-
|
|
528
|
+
dot.className = "cm-collab-selectionCaretDot";
|
|
521
529
|
const info = document.createElement("div");
|
|
522
|
-
info.className = "cm-
|
|
523
|
-
info.innerText = this.
|
|
530
|
+
info.className = "cm-collab-selectionInfo";
|
|
531
|
+
info.innerText = this._name;
|
|
524
532
|
span.appendChild(document.createTextNode("\u2060"));
|
|
525
533
|
span.appendChild(dot);
|
|
526
534
|
span.appendChild(document.createTextNode("\u2060"));
|
|
@@ -528,15 +536,12 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
|
528
536
|
span.appendChild(document.createTextNode("\u2060"));
|
|
529
537
|
return span;
|
|
530
538
|
}
|
|
531
|
-
eq(widget) {
|
|
532
|
-
return widget.color === this.color;
|
|
533
|
-
}
|
|
534
|
-
compare(widget) {
|
|
535
|
-
return widget.color === this.color;
|
|
536
|
-
}
|
|
537
539
|
updateDOM() {
|
|
538
540
|
return false;
|
|
539
541
|
}
|
|
542
|
+
eq(widget) {
|
|
543
|
+
return widget._color === this._color;
|
|
544
|
+
}
|
|
540
545
|
get estimatedHeight() {
|
|
541
546
|
return -1;
|
|
542
547
|
}
|
|
@@ -545,12 +550,12 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
|
545
550
|
}
|
|
546
551
|
};
|
|
547
552
|
var styles = EditorView.baseTheme({
|
|
548
|
-
".cm-
|
|
549
|
-
".cm-
|
|
553
|
+
".cm-collab-selection": {},
|
|
554
|
+
".cm-collab-selectionLine": {
|
|
550
555
|
padding: 0,
|
|
551
556
|
margin: "0px 2px 0px 4px"
|
|
552
557
|
},
|
|
553
|
-
".cm-
|
|
558
|
+
".cm-collab-selectionCaret": {
|
|
554
559
|
position: "relative",
|
|
555
560
|
borderLeft: "1px solid black",
|
|
556
561
|
borderRight: "1px solid black",
|
|
@@ -559,7 +564,7 @@ var styles = EditorView.baseTheme({
|
|
|
559
564
|
boxSizing: "border-box",
|
|
560
565
|
display: "inline"
|
|
561
566
|
},
|
|
562
|
-
".cm-
|
|
567
|
+
".cm-collab-selectionCaretDot": {
|
|
563
568
|
borderRadius: "50%",
|
|
564
569
|
position: "absolute",
|
|
565
570
|
width: ".4em",
|
|
@@ -570,11 +575,11 @@ var styles = EditorView.baseTheme({
|
|
|
570
575
|
transition: "transform .3s ease-in-out",
|
|
571
576
|
boxSizing: "border-box"
|
|
572
577
|
},
|
|
573
|
-
".cm-
|
|
578
|
+
".cm-collab-selectionCaret:hover > .cm-collab-selectionCaretDot": {
|
|
574
579
|
transformOrigin: "bottom center",
|
|
575
580
|
transform: "scale(0)"
|
|
576
581
|
},
|
|
577
|
-
".cm-
|
|
582
|
+
".cm-collab-selectionInfo": {
|
|
578
583
|
position: "absolute",
|
|
579
584
|
top: "-1.05em",
|
|
580
585
|
left: "-1px",
|
|
@@ -595,7 +600,7 @@ var styles = EditorView.baseTheme({
|
|
|
595
600
|
transitionDelay: "0s",
|
|
596
601
|
whiteSpace: "nowrap"
|
|
597
602
|
},
|
|
598
|
-
".cm-
|
|
603
|
+
".cm-collab-selectionCaret:hover > .cm-collab-selectionInfo": {
|
|
599
604
|
opacity: 1,
|
|
600
605
|
transitionDelay: "0s"
|
|
601
606
|
}
|
|
@@ -622,7 +627,7 @@ var basicBundle = ({ readonly, themeMode, placeholder: _placeholder }) => [
|
|
|
622
627
|
import { EditorView as EditorView3, keymap as keymap2 } from "@codemirror/view";
|
|
623
628
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
624
629
|
import { invariant } from "@dxos/invariant";
|
|
625
|
-
var
|
|
630
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
|
626
631
|
var defaultOptions = {
|
|
627
632
|
effect: 2,
|
|
628
633
|
maxParticles: 200,
|
|
@@ -749,7 +754,7 @@ var Blaster = class {
|
|
|
749
754
|
}
|
|
750
755
|
initialize() {
|
|
751
756
|
invariant(!this._canvas && !this._ctx, void 0, {
|
|
752
|
-
F:
|
|
757
|
+
F: __dxlog_file,
|
|
753
758
|
L: 138,
|
|
754
759
|
S: this,
|
|
755
760
|
A: [
|
|
@@ -786,7 +791,7 @@ var Blaster = class {
|
|
|
786
791
|
}
|
|
787
792
|
start() {
|
|
788
793
|
invariant(this._canvas && this._ctx, void 0, {
|
|
789
|
-
F:
|
|
794
|
+
F: __dxlog_file,
|
|
790
795
|
L: 177,
|
|
791
796
|
S: this,
|
|
792
797
|
A: [
|
|
@@ -1056,7 +1061,7 @@ var getLineRange = (lines, from, to) => {
|
|
|
1056
1061
|
var code2 = () => {
|
|
1057
1062
|
const getDecorations = (view) => {
|
|
1058
1063
|
const decorations = [];
|
|
1059
|
-
if (view.state.readOnly) {
|
|
1064
|
+
if (!view.hasFocus || view.state.readOnly) {
|
|
1060
1065
|
const text = view.state.doc.sliceString(0);
|
|
1061
1066
|
const matches = text.matchAll(CODE_REGEX);
|
|
1062
1067
|
const blocks = view.viewportLineBlocks;
|
|
@@ -1075,10 +1080,15 @@ var code2 = () => {
|
|
|
1075
1080
|
return [
|
|
1076
1081
|
ViewPlugin3.fromClass(class {
|
|
1077
1082
|
constructor(view) {
|
|
1083
|
+
this.hasFocus = false;
|
|
1078
1084
|
this.decorations = getDecorations(view);
|
|
1079
1085
|
}
|
|
1080
1086
|
update(update2) {
|
|
1081
|
-
if (
|
|
1087
|
+
if (
|
|
1088
|
+
// TODO(burdon): Generalize for other extensions.
|
|
1089
|
+
this.hasFocus !== update2.view.hasFocus || update2.startState.readOnly !== update2.view.state.readOnly || update2.docChanged || update2.viewportChanged
|
|
1090
|
+
) {
|
|
1091
|
+
this.hasFocus = update2.view.hasFocus;
|
|
1082
1092
|
this.decorations = getDecorations(update2.view);
|
|
1083
1093
|
}
|
|
1084
1094
|
}
|
|
@@ -1091,23 +1101,32 @@ var code2 = () => {
|
|
|
1091
1101
|
|
|
1092
1102
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1093
1103
|
import { StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
1094
|
-
import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView5
|
|
1104
|
+
import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView5 } from "@codemirror/view";
|
|
1095
1105
|
import sortBy from "lodash.sortby";
|
|
1096
1106
|
import { debounce } from "@dxos/async";
|
|
1097
1107
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1098
1108
|
import { log as log2 } from "@dxos/log";
|
|
1099
1109
|
import { nonNullable } from "@dxos/util";
|
|
1110
|
+
|
|
1111
|
+
// packages/ui/react-ui-editor/src/util.ts
|
|
1112
|
+
import { log } from "@dxos/log";
|
|
1113
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
|
|
1114
|
+
var callbackWrapper = (fn) => (...args) => {
|
|
1115
|
+
try {
|
|
1116
|
+
return fn(...args);
|
|
1117
|
+
} catch (error) {
|
|
1118
|
+
log.catch(error, void 0, {
|
|
1119
|
+
F: __dxlog_file2,
|
|
1120
|
+
L: 16,
|
|
1121
|
+
S: void 0,
|
|
1122
|
+
C: (f, a) => f(...a)
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
};
|
|
1126
|
+
|
|
1127
|
+
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1100
1128
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
|
|
1101
1129
|
var styles3 = EditorView5.baseTheme({
|
|
1102
|
-
"& .cm-bookmark": {
|
|
1103
|
-
cursor: "pointer",
|
|
1104
|
-
margin: "4px",
|
|
1105
|
-
padding: "4px",
|
|
1106
|
-
backgroundColor: "yellow"
|
|
1107
|
-
},
|
|
1108
|
-
"& .cm-bookmark-selected": {
|
|
1109
|
-
backgroundColor: "orange"
|
|
1110
|
-
},
|
|
1111
1130
|
"& .cm-comment": {
|
|
1112
1131
|
backgroundColor: getToken("extend.colors.yellow.50")
|
|
1113
1132
|
},
|
|
@@ -1146,7 +1165,7 @@ var commentsStateField = StateField2.define({
|
|
|
1146
1165
|
ranges: []
|
|
1147
1166
|
}),
|
|
1148
1167
|
update: (value, tr) => {
|
|
1149
|
-
const cursorConverter3 = tr.state.facet(
|
|
1168
|
+
const cursorConverter3 = tr.state.facet(Cursor.converter);
|
|
1150
1169
|
for (const effect of tr.effects) {
|
|
1151
1170
|
if (effect.is(setSelection)) {
|
|
1152
1171
|
return {
|
|
@@ -1157,7 +1176,7 @@ var commentsStateField = StateField2.define({
|
|
|
1157
1176
|
if (effect.is(setCommentRange)) {
|
|
1158
1177
|
const { comments: comments2 } = effect.value;
|
|
1159
1178
|
const ranges = comments2.map((comment) => {
|
|
1160
|
-
const range = getRangeFromCursor(cursorConverter3, comment.cursor);
|
|
1179
|
+
const range = Cursor.getRangeFromCursor(cursorConverter3, comment.cursor);
|
|
1161
1180
|
return range && {
|
|
1162
1181
|
...comment,
|
|
1163
1182
|
...range
|
|
@@ -1195,42 +1214,14 @@ var highlightDecorations = EditorView5.decorations.compute([
|
|
|
1195
1214
|
}).filter(nonNullable) ?? [];
|
|
1196
1215
|
return Decoration3.set(decorations);
|
|
1197
1216
|
});
|
|
1198
|
-
var BookmarkWidget = class extends WidgetType2 {
|
|
1199
|
-
constructor(_anchor, _id, _handleClick) {
|
|
1200
|
-
super();
|
|
1201
|
-
this._anchor = _anchor;
|
|
1202
|
-
this._id = _id;
|
|
1203
|
-
this._handleClick = _handleClick;
|
|
1204
|
-
invariant2(this._id, void 0, {
|
|
1205
|
-
F: __dxlog_file3,
|
|
1206
|
-
L: 168,
|
|
1207
|
-
S: this,
|
|
1208
|
-
A: [
|
|
1209
|
-
"this._id",
|
|
1210
|
-
""
|
|
1211
|
-
]
|
|
1212
|
-
});
|
|
1213
|
-
}
|
|
1214
|
-
eq(other) {
|
|
1215
|
-
return this._anchor === other._anchor && this._id === other._id;
|
|
1216
|
-
}
|
|
1217
|
-
toDOM() {
|
|
1218
|
-
const span = document.createElement("span");
|
|
1219
|
-
span.className = "cm-bookmark";
|
|
1220
|
-
span.textContent = "\u203B";
|
|
1221
|
-
if (this._handleClick) {
|
|
1222
|
-
span.onclick = () => this._handleClick();
|
|
1223
|
-
}
|
|
1224
|
-
return span;
|
|
1225
|
-
}
|
|
1226
|
-
};
|
|
1227
1217
|
var comments = (options = {}) => {
|
|
1218
|
+
const { key: shortcut = "meta-'" } = options;
|
|
1228
1219
|
const handleSelect = debounce((state) => options.onSelect?.(state), 200);
|
|
1229
1220
|
const createCommentThread = (view) => {
|
|
1230
|
-
const cursorConverter3 = view.state.facet(
|
|
1221
|
+
const cursorConverter3 = view.state.facet(Cursor.converter);
|
|
1231
1222
|
invariant2(options.onCreate, void 0, {
|
|
1232
1223
|
F: __dxlog_file3,
|
|
1233
|
-
L:
|
|
1224
|
+
L: 177,
|
|
1234
1225
|
S: void 0,
|
|
1235
1226
|
A: [
|
|
1236
1227
|
"options.onCreate",
|
|
@@ -1241,12 +1232,12 @@ var comments = (options = {}) => {
|
|
|
1241
1232
|
if (from === to) {
|
|
1242
1233
|
return false;
|
|
1243
1234
|
}
|
|
1244
|
-
const
|
|
1235
|
+
const cursor = Cursor.getCursorFromRange(cursorConverter3, {
|
|
1245
1236
|
from,
|
|
1246
1237
|
to
|
|
1247
1238
|
});
|
|
1248
|
-
if (
|
|
1249
|
-
const id = callbackWrapper(options.onCreate)(
|
|
1239
|
+
if (cursor) {
|
|
1240
|
+
const id = callbackWrapper(options.onCreate)(cursor, view.coordsAtPos(from));
|
|
1250
1241
|
if (id) {
|
|
1251
1242
|
view.dispatch({
|
|
1252
1243
|
effects: setSelection.of({
|
|
@@ -1273,35 +1264,7 @@ var comments = (options = {}) => {
|
|
|
1273
1264
|
}
|
|
1274
1265
|
return false;
|
|
1275
1266
|
};
|
|
1276
|
-
const bookmarksViewPlugin = ViewPlugin4.fromClass(class BookmarkViewPlugin {
|
|
1277
|
-
static {
|
|
1278
|
-
// Match markdown footnotes (option).
|
|
1279
|
-
// https://www.markdownguide.org/extended-syntax/#footnotes
|
|
1280
|
-
this.bookmarkMatcher = new MatchDecorator({
|
|
1281
|
-
regexp: /\[\^(\w+)\]/g,
|
|
1282
|
-
decoration: (match, view, pos) => {
|
|
1283
|
-
const id = match[1];
|
|
1284
|
-
return Decoration3.replace({
|
|
1285
|
-
id,
|
|
1286
|
-
widget: new BookmarkWidget(pos, id)
|
|
1287
|
-
});
|
|
1288
|
-
}
|
|
1289
|
-
});
|
|
1290
|
-
}
|
|
1291
|
-
constructor(view) {
|
|
1292
|
-
this.bookmarks = BookmarkViewPlugin.bookmarkMatcher.createDeco(view);
|
|
1293
|
-
}
|
|
1294
|
-
update(update2) {
|
|
1295
|
-
this.bookmarks = BookmarkViewPlugin.bookmarkMatcher.updateDeco(update2, this.bookmarks);
|
|
1296
|
-
}
|
|
1297
|
-
}, {
|
|
1298
|
-
decorations: (instance) => instance.bookmarks,
|
|
1299
|
-
provide: (plugin) => EditorView5.atomicRanges.of((view) => {
|
|
1300
|
-
return view.plugin(plugin)?.bookmarks || Decoration3.none;
|
|
1301
|
-
})
|
|
1302
|
-
});
|
|
1303
1267
|
return [
|
|
1304
|
-
bookmarksViewPlugin,
|
|
1305
1268
|
commentsStateField,
|
|
1306
1269
|
highlightDecorations,
|
|
1307
1270
|
styles3,
|
|
@@ -1310,7 +1273,7 @@ var comments = (options = {}) => {
|
|
|
1310
1273
|
//
|
|
1311
1274
|
options.onCreate ? keymap3.of([
|
|
1312
1275
|
{
|
|
1313
|
-
key:
|
|
1276
|
+
key: shortcut,
|
|
1314
1277
|
run: callbackWrapper(createCommentThread)
|
|
1315
1278
|
}
|
|
1316
1279
|
]) : [],
|
|
@@ -1327,7 +1290,7 @@ var comments = (options = {}) => {
|
|
|
1327
1290
|
above: true,
|
|
1328
1291
|
create: () => {
|
|
1329
1292
|
const el = document.createElement("div");
|
|
1330
|
-
options.onHover?.(el);
|
|
1293
|
+
options.onHover?.(el, shortcut);
|
|
1331
1294
|
return {
|
|
1332
1295
|
dom: el,
|
|
1333
1296
|
offset: {
|
|
@@ -1348,27 +1311,27 @@ var comments = (options = {}) => {
|
|
|
1348
1311
|
// TODO(burdon): Is there a better (finer grained) way to do this?
|
|
1349
1312
|
//
|
|
1350
1313
|
EditorView5.updateListener.of(({ view, state, changes }) => {
|
|
1351
|
-
const cursorConverter3 = view.state.facet(
|
|
1314
|
+
const cursorConverter3 = view.state.facet(Cursor.converter);
|
|
1352
1315
|
{
|
|
1353
1316
|
let mod = false;
|
|
1354
1317
|
const { active, ranges } = state.field(commentsStateField);
|
|
1355
1318
|
changes.iterChanges((from, to, from2, to2) => {
|
|
1356
1319
|
ranges.forEach((range) => {
|
|
1357
1320
|
if (from2 === to2) {
|
|
1358
|
-
const newRange = getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1321
|
+
const newRange = Cursor.getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1359
1322
|
if (!newRange || newRange.to - newRange.from === 0) {
|
|
1360
1323
|
log2.info("deleted comment", {
|
|
1361
1324
|
thread: range.id
|
|
1362
1325
|
}, {
|
|
1363
1326
|
F: __dxlog_file3,
|
|
1364
|
-
L:
|
|
1327
|
+
L: 274,
|
|
1365
1328
|
S: void 0,
|
|
1366
1329
|
C: (f, a) => f(...a)
|
|
1367
1330
|
});
|
|
1368
1331
|
}
|
|
1369
1332
|
}
|
|
1370
1333
|
if (from <= range.to) {
|
|
1371
|
-
const newRange = getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1334
|
+
const newRange = Cursor.getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1372
1335
|
Object.assign(range, newRange);
|
|
1373
1336
|
mod = true;
|
|
1374
1337
|
}
|
|
@@ -1417,26 +1380,9 @@ var comments = (options = {}) => {
|
|
|
1417
1380
|
})
|
|
1418
1381
|
];
|
|
1419
1382
|
};
|
|
1420
|
-
var getCursorFromRange = (cursorConverter3, range) => {
|
|
1421
|
-
const from = cursorConverter3.toCursor(range.from);
|
|
1422
|
-
const to = cursorConverter3.toCursor(range.to, -1);
|
|
1423
|
-
return [
|
|
1424
|
-
from,
|
|
1425
|
-
to
|
|
1426
|
-
].join(":");
|
|
1427
|
-
};
|
|
1428
|
-
var getRangeFromCursor = (cursorConverter3, cursor) => {
|
|
1429
|
-
const parts = cursor.split(":");
|
|
1430
|
-
const from = cursorConverter3.fromCursor(parts[0]);
|
|
1431
|
-
const to = cursorConverter3.fromCursor(parts[1]);
|
|
1432
|
-
return from !== void 0 && to !== void 0 ? {
|
|
1433
|
-
from,
|
|
1434
|
-
to
|
|
1435
|
-
} : void 0;
|
|
1436
|
-
};
|
|
1437
1383
|
|
|
1438
1384
|
// packages/ui/react-ui-editor/src/extensions/hr.ts
|
|
1439
|
-
import { Decoration as Decoration4, EditorView as EditorView6, MatchDecorator
|
|
1385
|
+
import { Decoration as Decoration4, EditorView as EditorView6, MatchDecorator, ViewPlugin as ViewPlugin4, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
1440
1386
|
var styles4 = EditorView6.baseTheme({
|
|
1441
1387
|
"& .cm-hr": {
|
|
1442
1388
|
// TODO(burdon): ???
|
|
@@ -1444,7 +1390,7 @@ var styles4 = EditorView6.baseTheme({
|
|
|
1444
1390
|
borderBottom: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
1445
1391
|
}
|
|
1446
1392
|
});
|
|
1447
|
-
var HorizontalRuleWidget = class extends
|
|
1393
|
+
var HorizontalRuleWidget = class extends WidgetType2 {
|
|
1448
1394
|
constructor(_pos) {
|
|
1449
1395
|
super();
|
|
1450
1396
|
this._pos = _pos;
|
|
@@ -1458,7 +1404,7 @@ var HorizontalRuleWidget = class extends WidgetType3 {
|
|
|
1458
1404
|
return el;
|
|
1459
1405
|
}
|
|
1460
1406
|
};
|
|
1461
|
-
var placeholderMatcher = new
|
|
1407
|
+
var placeholderMatcher = new MatchDecorator({
|
|
1462
1408
|
regexp: /^---$/g,
|
|
1463
1409
|
decoration: (match, view, pos) => Decoration4.replace({
|
|
1464
1410
|
widget: new HorizontalRuleWidget(pos)
|
|
@@ -1466,7 +1412,7 @@ var placeholderMatcher = new MatchDecorator2({
|
|
|
1466
1412
|
});
|
|
1467
1413
|
var hr = () => [
|
|
1468
1414
|
styles4,
|
|
1469
|
-
|
|
1415
|
+
ViewPlugin4.fromClass(class {
|
|
1470
1416
|
constructor(view) {
|
|
1471
1417
|
this.rules = placeholderMatcher.createDeco(view);
|
|
1472
1418
|
}
|
|
@@ -1485,7 +1431,7 @@ var hr = () => [
|
|
|
1485
1431
|
// packages/ui/react-ui-editor/src/extensions/image.ts
|
|
1486
1432
|
import { syntaxTree } from "@codemirror/language";
|
|
1487
1433
|
import { StateField as StateField3 } from "@codemirror/state";
|
|
1488
|
-
import { Decoration as Decoration5, EditorView as EditorView7, WidgetType as
|
|
1434
|
+
import { Decoration as Decoration5, EditorView as EditorView7, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1489
1435
|
var image = (options = {}) => {
|
|
1490
1436
|
return StateField3.define({
|
|
1491
1437
|
create: (state) => {
|
|
@@ -1537,7 +1483,7 @@ var buildDecorations = (from, to, state) => {
|
|
|
1537
1483
|
});
|
|
1538
1484
|
return decorations;
|
|
1539
1485
|
};
|
|
1540
|
-
var ImageWidget = class extends
|
|
1486
|
+
var ImageWidget = class extends WidgetType3 {
|
|
1541
1487
|
constructor(_url) {
|
|
1542
1488
|
super();
|
|
1543
1489
|
this._url = _url;
|
|
@@ -1557,11 +1503,11 @@ var ImageWidget = class extends WidgetType4 {
|
|
|
1557
1503
|
// packages/ui/react-ui-editor/src/extensions/link.ts
|
|
1558
1504
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
1559
1505
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
1560
|
-
import { Decoration as Decoration6, WidgetType as
|
|
1506
|
+
import { Decoration as Decoration6, WidgetType as WidgetType4, hoverTooltip as hoverTooltip2, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
1561
1507
|
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
1562
1508
|
var link = (options = {}) => {
|
|
1563
1509
|
const extensions = [
|
|
1564
|
-
|
|
1510
|
+
ViewPlugin5.fromClass(class {
|
|
1565
1511
|
constructor(view) {
|
|
1566
1512
|
this.decorations = buildDecorations2(view, options);
|
|
1567
1513
|
}
|
|
@@ -1612,7 +1558,7 @@ var link = (options = {}) => {
|
|
|
1612
1558
|
}
|
|
1613
1559
|
return extensions;
|
|
1614
1560
|
};
|
|
1615
|
-
var LinkButton = class extends
|
|
1561
|
+
var LinkButton = class extends WidgetType4 {
|
|
1616
1562
|
constructor(_url, _onAttach) {
|
|
1617
1563
|
super();
|
|
1618
1564
|
this._url = _url;
|
|
@@ -1627,7 +1573,7 @@ var LinkButton = class extends WidgetType5 {
|
|
|
1627
1573
|
return el;
|
|
1628
1574
|
}
|
|
1629
1575
|
};
|
|
1630
|
-
var LinkText = class extends
|
|
1576
|
+
var LinkText = class extends WidgetType4 {
|
|
1631
1577
|
constructor(_text, _url) {
|
|
1632
1578
|
super();
|
|
1633
1579
|
this._text = _text;
|
|
@@ -1708,7 +1654,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
1708
1654
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1709
1655
|
import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1710
1656
|
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1711
|
-
import { markdownLanguage as
|
|
1657
|
+
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1712
1658
|
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
1713
1659
|
import { languages } from "@codemirror/language-data";
|
|
1714
1660
|
import { searchKeymap } from "@codemirror/search";
|
|
@@ -1717,7 +1663,7 @@ import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/the
|
|
|
1717
1663
|
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView9, highlightActiveLine, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
|
|
1718
1664
|
|
|
1719
1665
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1720
|
-
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
1666
|
+
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
1721
1667
|
import { HighlightStyle } from "@codemirror/language";
|
|
1722
1668
|
import { tags, styleTags, Tag } from "@lezer/highlight";
|
|
1723
1669
|
import { Table } from "@lezer/markdown";
|
|
@@ -1727,7 +1673,6 @@ var markdownTags = {
|
|
|
1727
1673
|
CodeText: Tag.define(),
|
|
1728
1674
|
EmphasisMark: Tag.define(),
|
|
1729
1675
|
HeaderMark: Tag.define(),
|
|
1730
|
-
// HorizontalRule: Tag.define(),
|
|
1731
1676
|
InlineCode: Tag.define(),
|
|
1732
1677
|
LinkLabel: Tag.define(),
|
|
1733
1678
|
LinkReference: Tag.define(),
|
|
@@ -1891,12 +1836,6 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1891
1836
|
],
|
|
1892
1837
|
class: blockquote
|
|
1893
1838
|
},
|
|
1894
|
-
// TODO(burdon): Replace with extension.
|
|
1895
|
-
// {
|
|
1896
|
-
// tag: [markdownTags.HorizontalRule],
|
|
1897
|
-
// class: mx(horizontalRule, readonly && '-indent-[100rem]'),
|
|
1898
|
-
// },
|
|
1899
|
-
// TODO(burdon): Only if being edited.
|
|
1900
1839
|
{
|
|
1901
1840
|
tag: [
|
|
1902
1841
|
markdownTags.TableCell
|
|
@@ -1904,7 +1843,7 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1904
1843
|
class: "font-mono"
|
|
1905
1844
|
}
|
|
1906
1845
|
], {
|
|
1907
|
-
scope:
|
|
1846
|
+
scope: markdownLanguage2,
|
|
1908
1847
|
all: {
|
|
1909
1848
|
fontFamily: getToken("fontFamily.body", []).join(",")
|
|
1910
1849
|
}
|
|
@@ -1936,7 +1875,7 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
1936
1875
|
// NOTE: This extends the parser; it doesn't affect rendering.
|
|
1937
1876
|
// https://github.github.com/gfm
|
|
1938
1877
|
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
1939
|
-
base:
|
|
1878
|
+
base: markdownLanguage3,
|
|
1940
1879
|
// Languages for syntax highlighting fenced code blocks.
|
|
1941
1880
|
codeLanguages: languages,
|
|
1942
1881
|
// Parser extensions.
|
|
@@ -1990,7 +1929,7 @@ var mention = ({ onSearch }) => {
|
|
|
1990
1929
|
// packages/ui/react-ui-editor/src/extensions/table.ts
|
|
1991
1930
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1992
1931
|
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField4 } from "@codemirror/state";
|
|
1993
|
-
import { Decoration as Decoration7, EditorView as EditorView10, WidgetType as
|
|
1932
|
+
import { Decoration as Decoration7, EditorView as EditorView10, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
1994
1933
|
var table = (options = {}) => {
|
|
1995
1934
|
return StateField4.define({
|
|
1996
1935
|
create: (state) => update(state, options),
|
|
@@ -2040,7 +1979,6 @@ var update = (state, options) => {
|
|
|
2040
1979
|
tables.forEach((table2) => {
|
|
2041
1980
|
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
2042
1981
|
hide && builder.add(table2.from, table2.to, Decoration7.replace({
|
|
2043
|
-
block: true,
|
|
2044
1982
|
widget: new TableWidget(table2)
|
|
2045
1983
|
}));
|
|
2046
1984
|
builder.add(table2.from, table2.to, Decoration7.mark({
|
|
@@ -2049,7 +1987,7 @@ var update = (state, options) => {
|
|
|
2049
1987
|
});
|
|
2050
1988
|
return builder.finish();
|
|
2051
1989
|
};
|
|
2052
|
-
var TableWidget = class extends
|
|
1990
|
+
var TableWidget = class extends WidgetType5 {
|
|
2053
1991
|
constructor(_table) {
|
|
2054
1992
|
super();
|
|
2055
1993
|
this._table = _table;
|
|
@@ -2081,17 +2019,20 @@ var TableWidget = class extends WidgetType6 {
|
|
|
2081
2019
|
}
|
|
2082
2020
|
return table2;
|
|
2083
2021
|
}
|
|
2022
|
+
ignoreEvent(e) {
|
|
2023
|
+
return !/^mouse/.test(e.type);
|
|
2024
|
+
}
|
|
2084
2025
|
};
|
|
2085
2026
|
|
|
2086
2027
|
// packages/ui/react-ui-editor/src/extensions/tasklist.ts
|
|
2087
|
-
import { EditorView as EditorView11, Decoration as Decoration8, WidgetType as
|
|
2028
|
+
import { EditorView as EditorView11, Decoration as Decoration8, WidgetType as WidgetType6, MatchDecorator as MatchDecorator2, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
2088
2029
|
var styles5 = EditorView11.baseTheme({
|
|
2089
2030
|
"& .cm-task-item": {
|
|
2090
2031
|
paddingLeft: "4px",
|
|
2091
2032
|
paddingRight: "8px"
|
|
2092
2033
|
}
|
|
2093
2034
|
});
|
|
2094
|
-
var CheckboxWidget = class extends
|
|
2035
|
+
var CheckboxWidget = class extends WidgetType6 {
|
|
2095
2036
|
constructor(_checked, _indent, _onCheck) {
|
|
2096
2037
|
super();
|
|
2097
2038
|
this._checked = _checked;
|
|
@@ -2125,7 +2066,7 @@ var CheckboxWidget = class extends WidgetType7 {
|
|
|
2125
2066
|
}
|
|
2126
2067
|
};
|
|
2127
2068
|
var tasklist = (options = {}) => {
|
|
2128
|
-
const taskMatcher = new
|
|
2069
|
+
const taskMatcher = new MatchDecorator2({
|
|
2129
2070
|
regexp: /^(\s*)- \[([ xX])\]\s/g,
|
|
2130
2071
|
decoration: (match, view, pos) => {
|
|
2131
2072
|
const indent = Math.floor(match[1].length / 2);
|
|
@@ -2148,7 +2089,7 @@ var tasklist = (options = {}) => {
|
|
|
2148
2089
|
});
|
|
2149
2090
|
}
|
|
2150
2091
|
});
|
|
2151
|
-
const tasks =
|
|
2092
|
+
const tasks = ViewPlugin6.fromClass(class {
|
|
2152
2093
|
constructor(view) {
|
|
2153
2094
|
this.tasks = taskMatcher.createDeco(view);
|
|
2154
2095
|
}
|
|
@@ -2241,7 +2182,7 @@ var cursorConverter2 = (text) => ({
|
|
|
2241
2182
|
|
|
2242
2183
|
// packages/ui/react-ui-editor/src/extensions/yjs/yjs.ts
|
|
2243
2184
|
var yjs = (content, awareness2) => [
|
|
2244
|
-
|
|
2185
|
+
Cursor.converter.of(cursorConverter2(content)),
|
|
2245
2186
|
yCollab(content, awareness2)
|
|
2246
2187
|
];
|
|
2247
2188
|
|
|
@@ -2338,33 +2279,6 @@ var defaultTheme = {
|
|
|
2338
2279
|
backgroundColor: get3(tokens, "extend.colors.yellow.700")
|
|
2339
2280
|
},
|
|
2340
2281
|
//
|
|
2341
|
-
// collaboration
|
|
2342
|
-
// TODO(burdon): Review classnames (YJS dependent?) Note: e2e tests depend on this class.
|
|
2343
|
-
//
|
|
2344
|
-
"&light .cm-ySelection, &light .cm-yLineSelection": {
|
|
2345
|
-
mixBlendMode: "multiply"
|
|
2346
|
-
},
|
|
2347
|
-
"&dark .cm-ySelection, &dark .cm-yLineSelection": {
|
|
2348
|
-
mixBlendMode: "screen"
|
|
2349
|
-
},
|
|
2350
|
-
".cm-ySelectionInfo": {
|
|
2351
|
-
padding: "2px 4px",
|
|
2352
|
-
marginBlockStart: "-4px"
|
|
2353
|
-
},
|
|
2354
|
-
".cm-ySelection, & .cm-selectionMatch": {
|
|
2355
|
-
paddingBlockStart: ".15em",
|
|
2356
|
-
paddingBlockEnd: ".15em"
|
|
2357
|
-
},
|
|
2358
|
-
".cm-ySelectionCaret": {
|
|
2359
|
-
display: "inline-block",
|
|
2360
|
-
insetBlockStart: ".1em",
|
|
2361
|
-
blockSize: "1.4em",
|
|
2362
|
-
verticalAlign: "top"
|
|
2363
|
-
},
|
|
2364
|
-
".cm-yLineSelection": {
|
|
2365
|
-
margin: 0
|
|
2366
|
-
},
|
|
2367
|
-
//
|
|
2368
2282
|
// link
|
|
2369
2283
|
//
|
|
2370
2284
|
".cm-link": {
|
|
@@ -2401,13 +2315,6 @@ var defaultTheme = {
|
|
|
2401
2315
|
textDecoration: "none"
|
|
2402
2316
|
},
|
|
2403
2317
|
//
|
|
2404
|
-
// widgets
|
|
2405
|
-
//
|
|
2406
|
-
".cm-widgetBuffer": {
|
|
2407
|
-
display: "none",
|
|
2408
|
-
height: 0
|
|
2409
|
-
},
|
|
2410
|
-
//
|
|
2411
2318
|
// table
|
|
2412
2319
|
//
|
|
2413
2320
|
".cm-table *": {
|
|
@@ -2438,27 +2345,17 @@ var defaultTheme = {
|
|
|
2438
2345
|
},
|
|
2439
2346
|
//
|
|
2440
2347
|
// font size
|
|
2441
|
-
// TODO(thure): This appears to be the best or only way to set selection caret heights,
|
|
2348
|
+
// TODO(thure): This appears to be the best or only way to set selection caret heights,
|
|
2349
|
+
// but it's far more verbose than it needs to be.
|
|
2442
2350
|
//
|
|
2443
|
-
...Object.keys(
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
acc[`& .text-${fontSize} + .cm-ySelectionCaret`] = {
|
|
2452
|
-
height
|
|
2453
|
-
};
|
|
2454
|
-
acc[`& .text-${fontSize} + .cm-ySelection + .cm-ySelectionCaret`] = {
|
|
2455
|
-
height
|
|
2456
|
-
};
|
|
2457
|
-
acc[`& .text-${fontSize} + .cm-widgetBuffer + .cm-ySelectionCaret`] = {
|
|
2458
|
-
height
|
|
2459
|
-
};
|
|
2460
|
-
return acc;
|
|
2461
|
-
}, {}),
|
|
2351
|
+
// ...Object.keys(get(tokens, 'extend.fontSize', {})).reduce((acc: Record<string, any>, fontSize) => {
|
|
2352
|
+
// const height = get(tokens, ['extend', 'fontSize', fontSize, 1, 'lineHeight']);
|
|
2353
|
+
//
|
|
2354
|
+
// acc[`& .text-${fontSize} + .cm-ySelectionCaret`] = { height };
|
|
2355
|
+
// acc[`& .text-${fontSize} + .cm-ySelection + .cm-ySelectionCaret`] = { height };
|
|
2356
|
+
// acc[`& .text-${fontSize} + .cm-widgetBuffer + .cm-ySelectionCaret`] = { height };
|
|
2357
|
+
// return acc;
|
|
2358
|
+
// }, {}),
|
|
2462
2359
|
/**
|
|
2463
2360
|
* Panels
|
|
2464
2361
|
* TODO(burdon): Needs styling attention (esp. dark mode).
|
|
@@ -2509,7 +2406,9 @@ var textTheme = {
|
|
|
2509
2406
|
}
|
|
2510
2407
|
};
|
|
2511
2408
|
var markdownTheme = {
|
|
2512
|
-
|
|
2409
|
+
".cm-scroller": {
|
|
2410
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
2411
|
+
},
|
|
2513
2412
|
".cm-placeholder": {
|
|
2514
2413
|
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
2515
2414
|
}
|
|
@@ -2528,21 +2427,23 @@ var EditorModes = [
|
|
|
2528
2427
|
"default",
|
|
2529
2428
|
"vim"
|
|
2530
2429
|
];
|
|
2531
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: comments2, extensions = [], editorMode, slots = defaultSlots }, forwardedRef) => {
|
|
2532
|
-
const { themeMode } = useThemeContext();
|
|
2430
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, focus, selection, readonly, comments: comments2, extensions = [], editorMode, theme, slots = defaultSlots }, forwardedRef) => {
|
|
2533
2431
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
2534
2432
|
tabBehavior: "limited"
|
|
2535
2433
|
});
|
|
2536
|
-
const
|
|
2537
|
-
const
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
state,
|
|
2434
|
+
const { themeMode } = useThemeContext();
|
|
2435
|
+
const rootRef = useRef(null);
|
|
2436
|
+
const [view, setView] = useState(null);
|
|
2437
|
+
useImperativeHandle(forwardedRef, () => view, [
|
|
2541
2438
|
view
|
|
2542
|
-
|
|
2439
|
+
]);
|
|
2440
|
+
useEffect(() => {
|
|
2441
|
+
if (view && focus) {
|
|
2442
|
+
view.focus();
|
|
2443
|
+
}
|
|
2444
|
+
}, [
|
|
2543
2445
|
view,
|
|
2544
|
-
|
|
2545
|
-
root
|
|
2446
|
+
focus
|
|
2546
2447
|
]);
|
|
2547
2448
|
const { awareness: awareness2, peer } = model;
|
|
2548
2449
|
useEffect(() => {
|
|
@@ -2566,7 +2467,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2566
2467
|
themeMode
|
|
2567
2468
|
]);
|
|
2568
2469
|
useEffect(() => {
|
|
2569
|
-
if (view && comments2
|
|
2470
|
+
if (view && comments2 !== void 0) {
|
|
2570
2471
|
view.dispatch({
|
|
2571
2472
|
effects: setCommentRange.of({
|
|
2572
2473
|
model,
|
|
@@ -2579,11 +2480,13 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2579
2480
|
comments2
|
|
2580
2481
|
]);
|
|
2581
2482
|
useEffect(() => {
|
|
2582
|
-
if (!
|
|
2483
|
+
if (!model || !rootRef.current) {
|
|
2583
2484
|
return;
|
|
2584
2485
|
}
|
|
2585
|
-
const
|
|
2486
|
+
const state = EditorState2.create({
|
|
2586
2487
|
doc: model.text(),
|
|
2488
|
+
// TODO(burdon): Composer should store and set selection when switching documents.
|
|
2489
|
+
selection,
|
|
2587
2490
|
extensions: [
|
|
2588
2491
|
readonly && EditorState2.readOnly.of(readonly),
|
|
2589
2492
|
// TODO(burdon): Factor out VIM mode? (manage via MarkdownPlugin).
|
|
@@ -2591,7 +2494,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2591
2494
|
// Theme.
|
|
2592
2495
|
// TODO(burdon): Make theme configurable.
|
|
2593
2496
|
EditorView12.baseTheme(defaultTheme),
|
|
2594
|
-
EditorView12.theme(
|
|
2497
|
+
EditorView12.theme(theme ?? {}),
|
|
2595
2498
|
EditorView12.darkTheme.of(themeMode === "dark"),
|
|
2596
2499
|
// Storage and replication.
|
|
2597
2500
|
model.extension,
|
|
@@ -2600,19 +2503,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2600
2503
|
].filter(Boolean)
|
|
2601
2504
|
});
|
|
2602
2505
|
view?.destroy();
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
state: state2,
|
|
2607
|
-
parent: root
|
|
2608
|
-
})
|
|
2506
|
+
const newView = new EditorView12({
|
|
2507
|
+
parent: rootRef.current,
|
|
2508
|
+
state
|
|
2609
2509
|
});
|
|
2510
|
+
setView(newView);
|
|
2610
2511
|
return () => {
|
|
2611
|
-
|
|
2612
|
-
|
|
2512
|
+
newView?.destroy();
|
|
2513
|
+
setView(null);
|
|
2613
2514
|
};
|
|
2614
2515
|
}, [
|
|
2615
|
-
|
|
2516
|
+
rootRef,
|
|
2616
2517
|
model,
|
|
2617
2518
|
readonly,
|
|
2618
2519
|
editorMode,
|
|
@@ -2621,12 +2522,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2621
2522
|
const handleKeyUp = useCallback((event) => {
|
|
2622
2523
|
const { key, altKey, shiftKey, metaKey, ctrlKey } = event;
|
|
2623
2524
|
switch (key) {
|
|
2624
|
-
case "Enter": {
|
|
2625
|
-
view?.contentDOM.focus();
|
|
2626
|
-
break;
|
|
2627
|
-
}
|
|
2628
2525
|
case "Escape": {
|
|
2629
|
-
editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) &&
|
|
2526
|
+
editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) && rootRef.current?.focus();
|
|
2630
2527
|
break;
|
|
2631
2528
|
}
|
|
2632
2529
|
}
|
|
@@ -2636,16 +2533,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2636
2533
|
]);
|
|
2637
2534
|
return /* @__PURE__ */ React.createElement("div", {
|
|
2638
2535
|
key: model.id,
|
|
2639
|
-
|
|
2536
|
+
role: "none",
|
|
2537
|
+
ref: rootRef,
|
|
2640
2538
|
tabIndex: 0,
|
|
2641
|
-
|
|
2642
|
-
...
|
|
2643
|
-
|
|
2539
|
+
onKeyUp: handleKeyUp,
|
|
2540
|
+
...slots.root,
|
|
2541
|
+
...editorMode !== "vim" && tabsterDOMAttribute
|
|
2644
2542
|
});
|
|
2645
2543
|
});
|
|
2646
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [],
|
|
2544
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, extensions = [], theme = textTheme, slots, ...props }, forwardedRef) => {
|
|
2647
2545
|
const { themeMode } = useThemeContext();
|
|
2648
|
-
const
|
|
2546
|
+
const updatedSlots = defaultsDeep2({}, slots, defaultTextSlots);
|
|
2649
2547
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2650
2548
|
ref: forwardedRef,
|
|
2651
2549
|
readonly,
|
|
@@ -2653,17 +2551,18 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots:
|
|
|
2653
2551
|
basicBundle({
|
|
2654
2552
|
readonly,
|
|
2655
2553
|
themeMode,
|
|
2656
|
-
placeholder:
|
|
2554
|
+
placeholder: placeholder3
|
|
2657
2555
|
}),
|
|
2658
2556
|
...extensions
|
|
2659
2557
|
],
|
|
2660
|
-
|
|
2558
|
+
theme,
|
|
2559
|
+
slots: updatedSlots,
|
|
2661
2560
|
...props
|
|
2662
2561
|
});
|
|
2663
2562
|
});
|
|
2664
|
-
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [],
|
|
2563
|
+
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, extensions = [], theme = markdownTheme, slots, ...props }, forwardedRef) => {
|
|
2665
2564
|
const { themeMode } = useThemeContext();
|
|
2666
|
-
const
|
|
2565
|
+
const updatedSlots = defaultsDeep2({}, slots, defaultMarkdownSlots);
|
|
2667
2566
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2668
2567
|
ref: forwardedRef,
|
|
2669
2568
|
readonly,
|
|
@@ -2671,30 +2570,25 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
|
|
|
2671
2570
|
markdownBundle({
|
|
2672
2571
|
readonly,
|
|
2673
2572
|
themeMode,
|
|
2674
|
-
placeholder:
|
|
2573
|
+
placeholder: placeholder3
|
|
2675
2574
|
}),
|
|
2676
2575
|
...extensions
|
|
2677
2576
|
],
|
|
2678
|
-
|
|
2577
|
+
theme,
|
|
2578
|
+
slots: updatedSlots,
|
|
2679
2579
|
...props
|
|
2680
2580
|
});
|
|
2681
2581
|
});
|
|
2682
2582
|
var defaultSlots = {
|
|
2683
2583
|
root: {
|
|
2684
|
-
className: mx3("p-2", inputSurface)
|
|
2584
|
+
className: mx3("p-2 overflow-y-auto", inputSurface)
|
|
2685
2585
|
}
|
|
2686
2586
|
};
|
|
2687
2587
|
var defaultTextSlots = {
|
|
2688
|
-
...defaultSlots
|
|
2689
|
-
editor: {
|
|
2690
|
-
theme: textTheme
|
|
2691
|
-
}
|
|
2588
|
+
...defaultSlots
|
|
2692
2589
|
};
|
|
2693
2590
|
var defaultMarkdownSlots = {
|
|
2694
|
-
...defaultSlots
|
|
2695
|
-
editor: {
|
|
2696
|
-
theme: markdownTheme
|
|
2697
|
-
}
|
|
2591
|
+
...defaultSlots
|
|
2698
2592
|
};
|
|
2699
2593
|
|
|
2700
2594
|
// packages/ui/react-ui-editor/src/hooks/automerge.ts
|
|
@@ -2817,15 +2711,13 @@ import * as decoding from "lib0/decoding";
|
|
|
2817
2711
|
import * as encoding from "lib0/encoding";
|
|
2818
2712
|
import { Observable } from "lib0/observable";
|
|
2819
2713
|
import * as YP from "y-protocols/awareness";
|
|
2820
|
-
import * as Y2 from "yjs";
|
|
2821
2714
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
2822
2715
|
import { log as log4 } from "@dxos/log";
|
|
2823
|
-
import { arrayToString as arrayToString2, stringToArray as stringToArray2 } from "@dxos/util";
|
|
2824
2716
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/yjs.ts";
|
|
2825
2717
|
var createYjsModel = ({ identity, space, text }) => {
|
|
2826
2718
|
invariant4(text?.doc && text?.content, void 0, {
|
|
2827
2719
|
F: __dxlog_file5,
|
|
2828
|
-
L:
|
|
2720
|
+
L: 21,
|
|
2829
2721
|
S: void 0,
|
|
2830
2722
|
A: [
|
|
2831
2723
|
"text?.doc && text?.content",
|
|
@@ -2841,34 +2733,6 @@ var createYjsModel = ({ identity, space, text }) => {
|
|
|
2841
2733
|
id: text.doc.guid,
|
|
2842
2734
|
content: text.content,
|
|
2843
2735
|
text: () => text.content.toString(),
|
|
2844
|
-
// https://github.com/yjs/yjs?tab=readme-ov-file#relative-positions
|
|
2845
|
-
// TODO(dmaretskyi): Refactor as cursor-converter.
|
|
2846
|
-
getCursorFromRange: (range) => {
|
|
2847
|
-
const from = Y2.encodeRelativePosition(Y2.createRelativePositionFromTypeIndex(text.content, range.from));
|
|
2848
|
-
const to = Y2.encodeRelativePosition(Y2.createRelativePositionFromTypeIndex(text.content, range.to, -1));
|
|
2849
|
-
return [
|
|
2850
|
-
arrayToString2(from),
|
|
2851
|
-
arrayToString2(to)
|
|
2852
|
-
].join(":");
|
|
2853
|
-
},
|
|
2854
|
-
getRangeFromCursor: (cursor) => {
|
|
2855
|
-
invariant4(text.doc, void 0, {
|
|
2856
|
-
F: __dxlog_file5,
|
|
2857
|
-
L: 40,
|
|
2858
|
-
S: void 0,
|
|
2859
|
-
A: [
|
|
2860
|
-
"text.doc",
|
|
2861
|
-
""
|
|
2862
|
-
]
|
|
2863
|
-
});
|
|
2864
|
-
const parts = cursor.split(":");
|
|
2865
|
-
const from = Y2.createAbsolutePositionFromRelativePosition(Y2.decodeRelativePosition(stringToArray2(parts[0])), text.doc);
|
|
2866
|
-
const to = Y2.createAbsolutePositionFromRelativePosition(Y2.decodeRelativePosition(stringToArray2(parts[1])), text.doc);
|
|
2867
|
-
return from && to ? {
|
|
2868
|
-
from: from.index,
|
|
2869
|
-
to: to.index
|
|
2870
|
-
} : void 0;
|
|
2871
|
-
},
|
|
2872
2736
|
extension: [
|
|
2873
2737
|
modelState.init(() => model),
|
|
2874
2738
|
yjs(text.content, provider?.awareness)
|
|
@@ -2918,7 +2782,7 @@ var YAwarenessProvider = class extends Observable {
|
|
|
2918
2782
|
origin
|
|
2919
2783
|
}, {
|
|
2920
2784
|
F: __dxlog_file5,
|
|
2921
|
-
L:
|
|
2785
|
+
L: 100,
|
|
2922
2786
|
S: this,
|
|
2923
2787
|
C: (f, a) => f(...a)
|
|
2924
2788
|
});
|
|
@@ -2931,7 +2795,7 @@ var YAwarenessProvider = class extends Observable {
|
|
|
2931
2795
|
_handleSpaceMessage({ payload }) {
|
|
2932
2796
|
log4("space message", payload, {
|
|
2933
2797
|
F: __dxlog_file5,
|
|
2934
|
-
L:
|
|
2798
|
+
L: 109,
|
|
2935
2799
|
S: this,
|
|
2936
2800
|
C: (f, a) => f(...a)
|
|
2937
2801
|
});
|
|
@@ -2981,7 +2845,7 @@ var modelState = StateField5.define({
|
|
|
2981
2845
|
});
|
|
2982
2846
|
var useTextModel = (props) => {
|
|
2983
2847
|
const { identity, space, text } = props;
|
|
2984
|
-
const [model, setModel] = useState2(
|
|
2848
|
+
const [model, setModel] = useState2();
|
|
2985
2849
|
useEffect2(() => setModel(createModel(props)), [
|
|
2986
2850
|
identity,
|
|
2987
2851
|
space,
|
|
@@ -3040,6 +2904,7 @@ var createAutomergeModel = ({ space, identity, text }) => {
|
|
|
3040
2904
|
export {
|
|
3041
2905
|
AwarenessProvider,
|
|
3042
2906
|
BaseTextEditor,
|
|
2907
|
+
Cursor,
|
|
3043
2908
|
Doc,
|
|
3044
2909
|
EditorModes,
|
|
3045
2910
|
MarkdownEditor,
|
|
@@ -3055,11 +2920,13 @@ export {
|
|
|
3055
2920
|
awareness,
|
|
3056
2921
|
basicBundle,
|
|
3057
2922
|
blast,
|
|
2923
|
+
callbackWrapper,
|
|
3058
2924
|
code2 as code,
|
|
3059
2925
|
codeTheme,
|
|
3060
2926
|
comments,
|
|
3061
2927
|
createAutomergeModel,
|
|
3062
2928
|
createYjsModel,
|
|
2929
|
+
cursorConverter,
|
|
3063
2930
|
defaultMarkdownSlots,
|
|
3064
2931
|
defaultOptions,
|
|
3065
2932
|
defaultSlots,
|