@dxos/react-ui-editor 0.4.8-main.0602afb → 0.4.8-main.2d8e727
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 +939 -777
- 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 +103 -0
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +34 -18
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +5 -79
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- 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/cursor.d.ts +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts +15 -1
- package/dist/types/src/extensions/automerge/defs.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/automerge/sync.d.ts +1 -2
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +1 -2
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness.d.ts.map +1 -0
- 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/extensions/cursor-line-margin.d.ts +7 -6
- package/dist/types/src/extensions/cursor-line-margin.d.ts.map +1 -1
- package/dist/types/src/extensions/cursor.d.ts +1 -1
- package/dist/types/src/extensions/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +1 -3
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +4 -5
- 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/formatting.d.ts +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/table.d.ts +2 -2
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner.d.ts +4 -0
- package/dist/types/src/extensions/outliner.d.ts.map +1 -0
- package/dist/types/src/{extensions/awareness → hooks}/awareness-provider.d.ts +1 -1
- package/dist/types/src/hooks/awareness-provider.d.ts.map +1 -0
- package/dist/types/src/hooks/defs.d.ts +20 -0
- package/dist/types/src/hooks/defs.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +4 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useEditorView.d.ts +20 -0
- package/dist/types/src/hooks/useEditorView.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextEditor.d.ts +44 -3
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.stories.d.ts +0 -6
- package/dist/types/src/hooks/useTextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextModel.d.ts +33 -0
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -0
- package/dist/types/src/themes/default.d.ts +3 -0
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/package.json +24 -24
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +524 -0
- package/src/components/TextEditor/TextEditor.stories.tsx +23 -508
- package/src/components/TextEditor/TextEditor.tsx +149 -37
- package/src/components/Toolbar/Toolbar.stories.tsx +42 -42
- package/src/extensions/automerge/automerge.stories.tsx +17 -16
- package/src/extensions/automerge/automerge.ts +1 -2
- package/src/extensions/automerge/cursor.ts +1 -1
- package/src/extensions/automerge/defs.ts +22 -1
- package/src/extensions/automerge/index.ts +1 -0
- package/src/extensions/automerge/sync.ts +9 -2
- package/src/extensions/automerge/update-automerge.ts +1 -2
- package/src/extensions/{awareness/awareness.ts → awareness.ts} +1 -1
- package/src/extensions/command/state.ts +1 -1
- package/src/extensions/comments.ts +5 -9
- package/src/extensions/cursor-line-margin.ts +18 -17
- package/src/extensions/cursor.ts +1 -1
- package/src/extensions/index.ts +1 -3
- package/src/extensions/markdown/bundle.ts +28 -11
- package/src/extensions/markdown/decorate.ts +3 -1
- package/src/extensions/markdown/formatting.ts +10 -15
- package/src/extensions/markdown/image.ts +0 -1
- package/src/extensions/markdown/table.ts +3 -11
- package/src/extensions/outliner.ts +12 -0
- package/src/{extensions/awareness → hooks}/awareness-provider.ts +1 -1
- package/src/hooks/defs.ts +30 -0
- package/src/hooks/index.ts +5 -1
- package/src/hooks/useEditorView.ts +32 -0
- package/src/hooks/useTextEditor.stories.tsx +34 -39
- package/src/hooks/useTextEditor.ts +120 -11
- package/src/hooks/useTextModel.ts +121 -0
- package/src/index.ts +1 -1
- package/src/themes/default.ts +28 -1
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +0 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +0 -1
- package/dist/types/src/extensions/awareness/index.d.ts +0 -3
- package/dist/types/src/extensions/awareness/index.d.ts.map +0 -1
- package/dist/types/src/extensions/doc.d.ts +0 -3
- package/dist/types/src/extensions/doc.d.ts.map +0 -1
- package/dist/types/src/extensions/factories.d.ts +0 -49
- package/dist/types/src/extensions/factories.d.ts.map +0 -1
- package/dist/types/src/extensions/types.d.ts +0 -9
- package/dist/types/src/extensions/types.d.ts.map +0 -1
- package/dist/types/src/hooks/useDocAccessor.d.ts +0 -7
- package/dist/types/src/hooks/useDocAccessor.d.ts.map +0 -1
- package/src/extensions/awareness/index.ts +0 -6
- package/src/extensions/doc.ts +0 -14
- package/src/extensions/factories.ts +0 -170
- package/src/extensions/types.ts +0 -16
- package/src/hooks/useDocAccessor.ts +0 -21
- /package/dist/types/src/extensions/{awareness/awareness.d.ts → awareness.d.ts} +0 -0
|
@@ -29,12 +29,16 @@ import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
|
29
29
|
import { Doc, YText, YXmlFragment } from "@dxos/text-model";
|
|
30
30
|
|
|
31
31
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
32
|
-
import { EditorState as
|
|
33
|
-
import { EditorView as
|
|
32
|
+
import { EditorState as EditorState3 } from "@codemirror/state";
|
|
33
|
+
import { EditorView as EditorView17, scrollPastEnd as scrollPastEnd2 } from "@codemirror/view";
|
|
34
34
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
35
|
-
import
|
|
35
|
+
import defaultsDeep3 from "lodash.defaultsdeep";
|
|
36
|
+
import React, { forwardRef, useCallback, useEffect as useEffect3, useImperativeHandle, useRef as useRef3, useState as useState5, useMemo as useMemo3 } from "react";
|
|
37
|
+
import { DocAccessor } from "@dxos/echo-schema";
|
|
36
38
|
import { log as log9 } from "@dxos/log";
|
|
37
|
-
import {
|
|
39
|
+
import { useThemeContext } from "@dxos/react-ui";
|
|
40
|
+
import { focusRing } from "@dxos/react-ui-theme";
|
|
41
|
+
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
38
42
|
|
|
39
43
|
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
|
40
44
|
import { StateField } from "@codemirror/state";
|
|
@@ -239,6 +243,7 @@ var cursorConverter = ({ handle, path }) => ({
|
|
|
239
243
|
|
|
240
244
|
// packages/ui/react-ui-editor/src/extensions/automerge/defs.ts
|
|
241
245
|
import { Annotation, StateEffect } from "@codemirror/state";
|
|
246
|
+
import get2 from "lodash.get";
|
|
242
247
|
var getPath = (state, field) => state.field(field).path;
|
|
243
248
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
244
249
|
var updateHeadsEffect = StateEffect.define({});
|
|
@@ -492,7 +497,7 @@ var automerge = (accessor) => {
|
|
|
492
497
|
];
|
|
493
498
|
};
|
|
494
499
|
|
|
495
|
-
// packages/ui/react-ui-editor/src/extensions/awareness
|
|
500
|
+
// packages/ui/react-ui-editor/src/extensions/awareness.ts
|
|
496
501
|
import { Annotation as Annotation2, Facet as Facet2, RangeSet } from "@codemirror/state";
|
|
497
502
|
import { Decoration as Decoration2, EditorView as EditorView3, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
|
|
498
503
|
import { Event } from "@dxos/async";
|
|
@@ -727,115 +732,11 @@ var styles2 = EditorView3.baseTheme({
|
|
|
727
732
|
}
|
|
728
733
|
});
|
|
729
734
|
|
|
730
|
-
// packages/ui/react-ui-editor/src/extensions/awareness/awareness-provider.ts
|
|
731
|
-
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
732
|
-
import { Context as Context2 } from "@dxos/context";
|
|
733
|
-
import { invariant } from "@dxos/invariant";
|
|
734
|
-
import { log as log2 } from "@dxos/log";
|
|
735
|
-
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness-provider.ts";
|
|
736
|
-
var DEBOUNCE_INTERVAL = 100;
|
|
737
|
-
var SpaceAwarenessProvider = class {
|
|
738
|
-
constructor(params) {
|
|
739
|
-
this._remoteStates = /* @__PURE__ */ new Map();
|
|
740
|
-
this.remoteStateChange = new Event2();
|
|
741
|
-
this._space = params.space;
|
|
742
|
-
this._channel = params.channel;
|
|
743
|
-
this._peerId = params.peerId;
|
|
744
|
-
this._info = params.info;
|
|
745
|
-
}
|
|
746
|
-
open() {
|
|
747
|
-
this._ctx = new Context2();
|
|
748
|
-
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
749
|
-
if (this._localState) {
|
|
750
|
-
await this._space.postMessage(this._channel, {
|
|
751
|
-
kind: "post",
|
|
752
|
-
state: this._localState
|
|
753
|
-
});
|
|
754
|
-
await sleep(DEBOUNCE_INTERVAL);
|
|
755
|
-
}
|
|
756
|
-
});
|
|
757
|
-
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
758
|
-
switch (message.payload.kind) {
|
|
759
|
-
case "query": {
|
|
760
|
-
this._handleQueryMessage();
|
|
761
|
-
break;
|
|
762
|
-
}
|
|
763
|
-
case "post": {
|
|
764
|
-
this._handlePostMessage(message.payload);
|
|
765
|
-
break;
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
}));
|
|
769
|
-
void this._space.postMessage(this._channel, {
|
|
770
|
-
kind: "query"
|
|
771
|
-
}).catch((err) => {
|
|
772
|
-
log2.debug("failed to query awareness", {
|
|
773
|
-
err
|
|
774
|
-
}, {
|
|
775
|
-
F: __dxlog_file2,
|
|
776
|
-
L: 89,
|
|
777
|
-
S: this,
|
|
778
|
-
C: (f, a) => f(...a)
|
|
779
|
-
});
|
|
780
|
-
});
|
|
781
|
-
}
|
|
782
|
-
close() {
|
|
783
|
-
void this._ctx?.dispose();
|
|
784
|
-
this._ctx = void 0;
|
|
785
|
-
this._postTask = void 0;
|
|
786
|
-
}
|
|
787
|
-
getRemoteStates() {
|
|
788
|
-
return Array.from(this._remoteStates.values());
|
|
789
|
-
}
|
|
790
|
-
update(position) {
|
|
791
|
-
invariant(this._postTask, void 0, {
|
|
792
|
-
F: __dxlog_file2,
|
|
793
|
-
L: 104,
|
|
794
|
-
S: this,
|
|
795
|
-
A: [
|
|
796
|
-
"this._postTask",
|
|
797
|
-
""
|
|
798
|
-
]
|
|
799
|
-
});
|
|
800
|
-
this._localState = {
|
|
801
|
-
peerId: this._peerId,
|
|
802
|
-
position,
|
|
803
|
-
info: this._info
|
|
804
|
-
};
|
|
805
|
-
this._postTask.schedule();
|
|
806
|
-
}
|
|
807
|
-
_handleQueryMessage() {
|
|
808
|
-
invariant(this._postTask, void 0, {
|
|
809
|
-
F: __dxlog_file2,
|
|
810
|
-
L: 115,
|
|
811
|
-
S: this,
|
|
812
|
-
A: [
|
|
813
|
-
"this._postTask",
|
|
814
|
-
""
|
|
815
|
-
]
|
|
816
|
-
});
|
|
817
|
-
this._postTask.schedule();
|
|
818
|
-
}
|
|
819
|
-
_handlePostMessage(message) {
|
|
820
|
-
invariant(message.kind === "post", void 0, {
|
|
821
|
-
F: __dxlog_file2,
|
|
822
|
-
L: 120,
|
|
823
|
-
S: this,
|
|
824
|
-
A: [
|
|
825
|
-
"message.kind === 'post'",
|
|
826
|
-
""
|
|
827
|
-
]
|
|
828
|
-
});
|
|
829
|
-
this._remoteStates.set(message.state.peerId, message.state);
|
|
830
|
-
this.remoteStateChange.emit();
|
|
831
|
-
}
|
|
832
|
-
};
|
|
833
|
-
|
|
834
735
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
|
835
736
|
import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
|
|
836
737
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
837
|
-
import { invariant
|
|
838
|
-
var
|
|
738
|
+
import { invariant } from "@dxos/invariant";
|
|
739
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
|
839
740
|
var defaultOptions = {
|
|
840
741
|
effect: 2,
|
|
841
742
|
maxParticles: 200,
|
|
@@ -961,8 +862,8 @@ var Blaster = class {
|
|
|
961
862
|
return this._node;
|
|
962
863
|
}
|
|
963
864
|
initialize() {
|
|
964
|
-
|
|
965
|
-
F:
|
|
865
|
+
invariant(!this._canvas && !this._ctx, void 0, {
|
|
866
|
+
F: __dxlog_file2,
|
|
966
867
|
L: 141,
|
|
967
868
|
S: this,
|
|
968
869
|
A: [
|
|
@@ -998,8 +899,8 @@ var Blaster = class {
|
|
|
998
899
|
}
|
|
999
900
|
}
|
|
1000
901
|
start() {
|
|
1001
|
-
|
|
1002
|
-
F:
|
|
902
|
+
invariant(this._canvas && this._ctx, void 0, {
|
|
903
|
+
F: __dxlog_file2,
|
|
1003
904
|
L: 180,
|
|
1004
905
|
S: this,
|
|
1005
906
|
A: [
|
|
@@ -1209,8 +1110,8 @@ var commandState = StateField3.define({
|
|
|
1209
1110
|
}
|
|
1210
1111
|
return state;
|
|
1211
1112
|
},
|
|
1212
|
-
provide: (
|
|
1213
|
-
showTooltip.from(
|
|
1113
|
+
provide: (f) => [
|
|
1114
|
+
showTooltip.from(f, (value) => value.tooltip ?? null)
|
|
1214
1115
|
]
|
|
1215
1116
|
});
|
|
1216
1117
|
var openEffect = StateEffect2.define();
|
|
@@ -1365,7 +1266,7 @@ import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView
|
|
|
1365
1266
|
import sortBy from "lodash.sortby";
|
|
1366
1267
|
import { useEffect } from "react";
|
|
1367
1268
|
import { debounce } from "@dxos/async";
|
|
1368
|
-
import { log as
|
|
1269
|
+
import { log as log3 } from "@dxos/log";
|
|
1369
1270
|
import { nonNullable } from "@dxos/util";
|
|
1370
1271
|
|
|
1371
1272
|
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
@@ -1392,10 +1293,10 @@ var inlineUrl = mx(code, "px-1");
|
|
|
1392
1293
|
var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
|
|
1393
1294
|
|
|
1394
1295
|
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
|
1395
|
-
import
|
|
1296
|
+
import get3 from "lodash.get";
|
|
1396
1297
|
import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
1397
1298
|
var tokens = tailwindConfig({}).theme;
|
|
1398
|
-
var getToken = (path, defaultValue = void 0) =>
|
|
1299
|
+
var getToken = (path, defaultValue = void 0) => get3(tokens, path, defaultValue);
|
|
1399
1300
|
|
|
1400
1301
|
// packages/ui/react-ui-editor/src/styles/layout.ts
|
|
1401
1302
|
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
|
@@ -1403,14 +1304,14 @@ var editorFillLayoutRoot = "bs-full relative";
|
|
|
1403
1304
|
var editorFillLayoutEditor = "!absolute inset-0";
|
|
1404
1305
|
|
|
1405
1306
|
// packages/ui/react-ui-editor/src/util.ts
|
|
1406
|
-
import { log as
|
|
1407
|
-
var
|
|
1307
|
+
import { log as log2 } from "@dxos/log";
|
|
1308
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
|
|
1408
1309
|
var callbackWrapper = (fn) => (...args) => {
|
|
1409
1310
|
try {
|
|
1410
1311
|
return fn(...args);
|
|
1411
1312
|
} catch (err) {
|
|
1412
|
-
|
|
1413
|
-
F:
|
|
1313
|
+
log2.catch(err, void 0, {
|
|
1314
|
+
F: __dxlog_file3,
|
|
1414
1315
|
L: 18,
|
|
1415
1316
|
S: void 0,
|
|
1416
1317
|
C: (f, a) => f(...a)
|
|
@@ -1433,10 +1334,10 @@ var logChanges = (trs) => {
|
|
|
1433
1334
|
return changes2;
|
|
1434
1335
|
}).filter(Boolean);
|
|
1435
1336
|
if (changes.length) {
|
|
1436
|
-
|
|
1337
|
+
log2.info("changes", {
|
|
1437
1338
|
changes
|
|
1438
1339
|
}, {
|
|
1439
|
-
F:
|
|
1340
|
+
F: __dxlog_file3,
|
|
1440
1341
|
L: 39,
|
|
1441
1342
|
S: void 0,
|
|
1442
1343
|
C: (f, a) => f(...a)
|
|
@@ -1445,7 +1346,7 @@ var logChanges = (trs) => {
|
|
|
1445
1346
|
};
|
|
1446
1347
|
|
|
1447
1348
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1448
|
-
var
|
|
1349
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
|
|
1449
1350
|
var documentId = Facet4.define({
|
|
1450
1351
|
combine: (values) => values[0]
|
|
1451
1352
|
});
|
|
@@ -1531,8 +1432,8 @@ var commentsDecorations = EditorView7.decorations.compute([
|
|
|
1531
1432
|
const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
1532
1433
|
const range = comment.range;
|
|
1533
1434
|
if (!range || range.from === range.to) {
|
|
1534
|
-
|
|
1535
|
-
F:
|
|
1435
|
+
log3.warn("Invalid range:", range, {
|
|
1436
|
+
F: __dxlog_file4,
|
|
1536
1437
|
L: 132,
|
|
1537
1438
|
S: void 0,
|
|
1538
1439
|
C: (f, a) => f(...a)
|
|
@@ -1834,14 +1735,12 @@ var focusComment = (view, id, center = true) => {
|
|
|
1834
1735
|
var useComments = (view, id, comments2 = []) => {
|
|
1835
1736
|
useEffect(() => {
|
|
1836
1737
|
if (view) {
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
});
|
|
1844
|
-
}
|
|
1738
|
+
view.dispatch({
|
|
1739
|
+
effects: setComments.of({
|
|
1740
|
+
id,
|
|
1741
|
+
comments: comments2
|
|
1742
|
+
})
|
|
1743
|
+
});
|
|
1845
1744
|
}
|
|
1846
1745
|
}, [
|
|
1847
1746
|
id,
|
|
@@ -1851,97 +1750,74 @@ var useComments = (view, id, comments2 = []) => {
|
|
|
1851
1750
|
};
|
|
1852
1751
|
|
|
1853
1752
|
// packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts
|
|
1854
|
-
import { Transaction } from "@codemirror/state";
|
|
1753
|
+
import { Facet as Facet5, Transaction } from "@codemirror/state";
|
|
1855
1754
|
import { EditorView as EditorView8 } from "@codemirror/view";
|
|
1856
|
-
import { log as
|
|
1857
|
-
var
|
|
1755
|
+
import { log as log4 } from "@dxos/log";
|
|
1756
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts";
|
|
1757
|
+
var cursorLineMarginFacet = Facet5.define({
|
|
1758
|
+
combine: (input) => input[0] ?? 3
|
|
1759
|
+
});
|
|
1858
1760
|
var annotation = "cursorLineMargin";
|
|
1859
1761
|
var lineAtPos = (s, pos) => s.doc.lineAt(pos).number;
|
|
1860
|
-
var cursorLineMargin = (
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
const { lines } = options;
|
|
1864
|
-
if (!lines || lines <= 0) {
|
|
1865
|
-
return [];
|
|
1762
|
+
var cursorLineMargin = EditorView8.updateListener.of(({ transactions, state, selectionSet, startState, view }) => {
|
|
1763
|
+
if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
|
|
1764
|
+
return;
|
|
1866
1765
|
}
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1766
|
+
const s = state;
|
|
1767
|
+
const { main } = s.selection;
|
|
1768
|
+
const cursorLineMargin2 = s.facet(cursorLineMarginFacet);
|
|
1769
|
+
const rect = view.dom.getBoundingClientRect();
|
|
1770
|
+
const viewportTop = rect.top - view.documentTop;
|
|
1771
|
+
const viewportBottom = rect.bottom - view.documentTop;
|
|
1772
|
+
const mainLine = lineAtPos(s, main.head);
|
|
1773
|
+
const _visTopLine = lineAtPos(s, view.lineBlockAtHeight(viewportTop).from);
|
|
1774
|
+
const botLineBlk = view.lineBlockAtHeight(viewportBottom);
|
|
1775
|
+
const visBotLineDoc = lineAtPos(s, Math.min(botLineBlk.to, s.doc.length));
|
|
1776
|
+
const visBotLine = botLineBlk.bottom >= viewportBottom ? visBotLineDoc : visBotLineDoc + Math.floor((viewportBottom - botLineBlk.bottom) / view.defaultLineHeight);
|
|
1777
|
+
const needsScrollTop = false;
|
|
1778
|
+
const needsScrollBot = mainLine >= visBotLine - cursorLineMargin2;
|
|
1779
|
+
if (needsScrollTop && needsScrollBot) {
|
|
1780
|
+
log4.warn("is cursorScrollMargin too large for the editor size?", void 0, {
|
|
1781
|
+
F: __dxlog_file5,
|
|
1782
|
+
L: 66,
|
|
1783
|
+
S: void 0,
|
|
1784
|
+
C: (f, a) => f(...a)
|
|
1785
|
+
});
|
|
1786
|
+
return;
|
|
1787
|
+
}
|
|
1788
|
+
if (!needsScrollTop && !needsScrollBot) {
|
|
1789
|
+
return;
|
|
1790
|
+
}
|
|
1791
|
+
if (selectionSet) {
|
|
1792
|
+
const { head } = startState.selection.main;
|
|
1793
|
+
const oldMainLine = lineAtPos(startState, head);
|
|
1794
|
+
if (needsScrollTop && oldMainLine < mainLine) {
|
|
1890
1795
|
return;
|
|
1891
1796
|
}
|
|
1892
|
-
if (
|
|
1797
|
+
if (needsScrollBot && oldMainLine > mainLine) {
|
|
1893
1798
|
return;
|
|
1894
1799
|
}
|
|
1895
|
-
if (selectionSet) {
|
|
1896
|
-
const { head } = startState.selection.main;
|
|
1897
|
-
const oldMainLine = lineAtPos(startState, head);
|
|
1898
|
-
if (needsScrollTop && oldMainLine < mainLine) {
|
|
1899
|
-
return;
|
|
1900
|
-
}
|
|
1901
|
-
if (needsScrollBot && oldMainLine > mainLine) {
|
|
1902
|
-
return;
|
|
1903
|
-
}
|
|
1904
|
-
}
|
|
1905
|
-
view.dispatch({
|
|
1906
|
-
annotations: Transaction.userEvent.of(annotation),
|
|
1907
|
-
effects: EditorView8.scrollIntoView(s.selection.main.head, {
|
|
1908
|
-
y: needsScrollTop ? "start" : "end",
|
|
1909
|
-
yMargin: view.defaultLineHeight * lines
|
|
1910
|
-
})
|
|
1911
|
-
});
|
|
1912
|
-
});
|
|
1913
|
-
};
|
|
1914
|
-
|
|
1915
|
-
// packages/ui/react-ui-editor/src/extensions/doc.ts
|
|
1916
|
-
import { Facet as Facet5 } from "@codemirror/state";
|
|
1917
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1918
|
-
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/doc.ts";
|
|
1919
|
-
var documentId2 = Facet5.define({
|
|
1920
|
-
combine: (providers) => {
|
|
1921
|
-
invariant3(providers.length <= 1, void 0, {
|
|
1922
|
-
F: __dxlog_file7,
|
|
1923
|
-
L: 11,
|
|
1924
|
-
S: void 0,
|
|
1925
|
-
A: [
|
|
1926
|
-
"providers.length <= 1",
|
|
1927
|
-
""
|
|
1928
|
-
]
|
|
1929
|
-
});
|
|
1930
|
-
return providers[0];
|
|
1931
1800
|
}
|
|
1801
|
+
view.dispatch({
|
|
1802
|
+
annotations: Transaction.userEvent.of(annotation),
|
|
1803
|
+
effects: EditorView8.scrollIntoView(s.selection.main.head, {
|
|
1804
|
+
y: needsScrollTop ? "start" : "end",
|
|
1805
|
+
yMargin: view.defaultLineHeight * cursorLineMargin2
|
|
1806
|
+
})
|
|
1807
|
+
});
|
|
1932
1808
|
});
|
|
1933
1809
|
|
|
1934
1810
|
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
|
1935
1811
|
import { EditorView as EditorView9 } from "@codemirror/view";
|
|
1936
|
-
import { log as
|
|
1937
|
-
var
|
|
1812
|
+
import { log as log5 } from "@dxos/log";
|
|
1813
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/dnd.ts";
|
|
1938
1814
|
var dnd = () => {
|
|
1939
1815
|
return EditorView9.domEventHandlers({
|
|
1940
1816
|
drop: (event, view) => {
|
|
1941
|
-
|
|
1817
|
+
log5.info("domEventHandlersDrop", {
|
|
1942
1818
|
event
|
|
1943
1819
|
}, {
|
|
1944
|
-
F:
|
|
1820
|
+
F: __dxlog_file6,
|
|
1945
1821
|
L: 14,
|
|
1946
1822
|
S: void 0,
|
|
1947
1823
|
C: (f, a) => f(...a)
|
|
@@ -1950,353 +1826,31 @@ var dnd = () => {
|
|
|
1950
1826
|
});
|
|
1951
1827
|
};
|
|
1952
1828
|
|
|
1953
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
1954
|
-
import {
|
|
1955
|
-
|
|
1956
|
-
|
|
1829
|
+
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
1830
|
+
import { EditorView as EditorView10 } from "@codemirror/view";
|
|
1831
|
+
var listener = ({ onFocus, onChange }) => {
|
|
1832
|
+
const extensions = [];
|
|
1833
|
+
onFocus && extensions.push(EditorView10.focusChangeEffect.of((_, focusing) => {
|
|
1834
|
+
onFocus(focusing);
|
|
1835
|
+
return null;
|
|
1836
|
+
}));
|
|
1837
|
+
onChange && extensions.push(EditorView10.updateListener.of((update2) => {
|
|
1838
|
+
onChange(update2.state.doc.toString());
|
|
1839
|
+
}));
|
|
1840
|
+
return extensions;
|
|
1841
|
+
};
|
|
1842
|
+
|
|
1843
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1844
|
+
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1845
|
+
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1846
|
+
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1847
|
+
import { bracketMatching, defaultHighlightStyle, indentOnInput, syntaxHighlighting } from "@codemirror/language";
|
|
1848
|
+
import { languages } from "@codemirror/language-data";
|
|
1849
|
+
import { searchKeymap } from "@codemirror/search";
|
|
1957
1850
|
import { EditorState } from "@codemirror/state";
|
|
1958
|
-
import {
|
|
1959
|
-
import
|
|
1960
|
-
import {
|
|
1961
|
-
import { log as log7 } from "@dxos/log";
|
|
1962
|
-
import { hueTokens } from "@dxos/react-ui-theme";
|
|
1963
|
-
import { hexToHue, isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
1964
|
-
|
|
1965
|
-
// packages/ui/react-ui-editor/src/themes/default.ts
|
|
1966
|
-
import get3 from "lodash.get";
|
|
1967
|
-
var defaultTheme = {
|
|
1968
|
-
//
|
|
1969
|
-
// Main layout:
|
|
1970
|
-
// https://codemirror.net/examples/styling
|
|
1971
|
-
//
|
|
1972
|
-
// <div class="cm-editor [cm-focused] [generated classes]">
|
|
1973
|
-
// <div class="cm-scroller">
|
|
1974
|
-
// <div class="cm-gutters">
|
|
1975
|
-
// <div class="cm-gutter [...]">
|
|
1976
|
-
// <div class="cm-gutterElement">...</div>
|
|
1977
|
-
// </div>
|
|
1978
|
-
// </div>
|
|
1979
|
-
// <div class="cm-content" role="textbox" contenteditable="true">
|
|
1980
|
-
// <div class="cm-line"></div>
|
|
1981
|
-
// </div>
|
|
1982
|
-
// <div class="cm-selectionLayer">
|
|
1983
|
-
// <div class="cm-selectionBackground"></div>
|
|
1984
|
-
// </div>
|
|
1985
|
-
// <div class="cm-cursorLayer">
|
|
1986
|
-
// <div class="cm-cursor"></div>
|
|
1987
|
-
// </div>
|
|
1988
|
-
// </div>
|
|
1989
|
-
// </div>
|
|
1990
|
-
//
|
|
1991
|
-
"&": {},
|
|
1992
|
-
"&.cm-focused": {
|
|
1993
|
-
outline: "none"
|
|
1994
|
-
},
|
|
1995
|
-
// NOTE: See https://codemirror.net/docs/guide (DOM Structure).
|
|
1996
|
-
".cm-scroller": {
|
|
1997
|
-
// TODO(burdon): Reconcile with docs: https://codemirror.net/docs/guide
|
|
1998
|
-
// Inside of that is the scroller element. If the editor has its own scrollbar, this one should be styled with overflow: auto. But it doesn't have to—the editor also supports growing to accomodate its content, or growing up to a certain max-height and then scrolling.
|
|
1999
|
-
overflowY: "auto",
|
|
2000
|
-
fontFamily: get3(tokens, "fontFamily.body", []).join(","),
|
|
2001
|
-
lineHeight: 1.5
|
|
2002
|
-
},
|
|
2003
|
-
".cm-content": {
|
|
2004
|
-
// TODO(burdon): Is it possible to remove the padding value from CM's default theme?
|
|
2005
|
-
// padding: 'unset',
|
|
2006
|
-
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
|
2007
|
-
fontSize: "16px"
|
|
2008
|
-
},
|
|
2009
|
-
"&light .cm-content": {
|
|
2010
|
-
color: get3(tokens, "extend.semanticColors.base.fg.light", "black"),
|
|
2011
|
-
caretColor: "black"
|
|
2012
|
-
},
|
|
2013
|
-
"&dark .cm-content": {
|
|
2014
|
-
color: get3(tokens, "extend.semanticColors.base.fg.dark", "white"),
|
|
2015
|
-
caretColor: "white"
|
|
2016
|
-
},
|
|
2017
|
-
//
|
|
2018
|
-
// Cursor
|
|
2019
|
-
//
|
|
2020
|
-
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
2021
|
-
borderLeft: "2px solid black"
|
|
2022
|
-
},
|
|
2023
|
-
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
2024
|
-
borderLeft: "2px solid white"
|
|
2025
|
-
},
|
|
2026
|
-
"&light .cm-placeholder": {
|
|
2027
|
-
color: get3(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
2028
|
-
},
|
|
2029
|
-
"&dark .cm-placeholder": {
|
|
2030
|
-
color: get3(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
2031
|
-
},
|
|
2032
|
-
//
|
|
2033
|
-
// line
|
|
2034
|
-
//
|
|
2035
|
-
".cm-line": {
|
|
2036
|
-
paddingInline: 0
|
|
2037
|
-
},
|
|
2038
|
-
".cm-activeLine": {
|
|
2039
|
-
background: "transparent"
|
|
2040
|
-
},
|
|
2041
|
-
//
|
|
2042
|
-
// gutter
|
|
2043
|
-
//
|
|
2044
|
-
".cm-gutterElement": {
|
|
2045
|
-
width: "48px"
|
|
2046
|
-
},
|
|
2047
|
-
//
|
|
2048
|
-
// Selection
|
|
2049
|
-
//
|
|
2050
|
-
"&light .cm-selectionBackground": {
|
|
2051
|
-
background: get3(tokens, "extend.colors.primary.100")
|
|
2052
|
-
},
|
|
2053
|
-
"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
2054
|
-
background: get3(tokens, "extend.colors.primary.200")
|
|
2055
|
-
},
|
|
2056
|
-
"&dark .cm-selectionBackground": {
|
|
2057
|
-
background: get3(tokens, "extend.colors.primary.700")
|
|
2058
|
-
},
|
|
2059
|
-
"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
2060
|
-
background: get3(tokens, "extend.colors.primary.600")
|
|
2061
|
-
},
|
|
2062
|
-
//
|
|
2063
|
-
// Search
|
|
2064
|
-
//
|
|
2065
|
-
"&light .cm-searchMatch": {
|
|
2066
|
-
backgroundColor: get3(tokens, "extend.colors.yellow.100")
|
|
2067
|
-
},
|
|
2068
|
-
"&dark .cm-searchMatch": {
|
|
2069
|
-
backgroundColor: get3(tokens, "extend.colors.yellow.700")
|
|
2070
|
-
},
|
|
2071
|
-
//
|
|
2072
|
-
// link
|
|
2073
|
-
//
|
|
2074
|
-
".cm-link": {
|
|
2075
|
-
color: get3(tokens, "extend.colors.primary.500"),
|
|
2076
|
-
textDecorationLine: "underline",
|
|
2077
|
-
textDecorationThickness: "1px",
|
|
2078
|
-
textUnderlineOffset: "2px",
|
|
2079
|
-
borderRadius: ".125rem",
|
|
2080
|
-
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
2081
|
-
},
|
|
2082
|
-
//
|
|
2083
|
-
// tooltip
|
|
2084
|
-
//
|
|
2085
|
-
".cm-tooltip": {
|
|
2086
|
-
border: "none",
|
|
2087
|
-
background: "unset"
|
|
2088
|
-
},
|
|
2089
|
-
".cm-tooltip-below": {},
|
|
2090
|
-
//
|
|
2091
|
-
// autocomplete
|
|
2092
|
-
//
|
|
2093
|
-
".cm-tooltip-autocomplete": {
|
|
2094
|
-
marginTop: "4px",
|
|
2095
|
-
marginLeft: "-3px"
|
|
2096
|
-
},
|
|
2097
|
-
".cm-tooltip-autocomplete ul li": {},
|
|
2098
|
-
".cm-tooltip-autocomplete ul li[aria-selected]": {},
|
|
2099
|
-
".cm-completionIcon": {
|
|
2100
|
-
display: "none"
|
|
2101
|
-
},
|
|
2102
|
-
".cm-completionLabel": {
|
|
2103
|
-
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
2104
|
-
},
|
|
2105
|
-
".cm-completionMatchedText": {
|
|
2106
|
-
textDecoration: "none"
|
|
2107
|
-
},
|
|
2108
|
-
//
|
|
2109
|
-
// table
|
|
2110
|
-
//
|
|
2111
|
-
".cm-table *": {
|
|
2112
|
-
fontFamily: `${get3(tokens, "fontFamily.mono", []).join(",")} !important`,
|
|
2113
|
-
textDecoration: "none !important"
|
|
2114
|
-
},
|
|
2115
|
-
".cm-table-head": {
|
|
2116
|
-
padding: "2px 16px 2px 0px",
|
|
2117
|
-
borderBottom: `1px solid ${get3(tokens, "extend.colors.neutral.500")}`,
|
|
2118
|
-
fontWeight: 100,
|
|
2119
|
-
textAlign: "left",
|
|
2120
|
-
color: get3(tokens, "extend.colors.neutral.500")
|
|
2121
|
-
},
|
|
2122
|
-
".cm-table-cell": {
|
|
2123
|
-
padding: "2px 16px 2px 0px"
|
|
2124
|
-
},
|
|
2125
|
-
//
|
|
2126
|
-
// image
|
|
2127
|
-
//
|
|
2128
|
-
".cm-image": {
|
|
2129
|
-
display: "block",
|
|
2130
|
-
height: "0"
|
|
2131
|
-
},
|
|
2132
|
-
".cm-image.cm-loaded-image": {
|
|
2133
|
-
height: "auto",
|
|
2134
|
-
borderTop: "0.5rem solid transparent",
|
|
2135
|
-
borderBottom: "0.5rem solid transparent"
|
|
2136
|
-
},
|
|
2137
|
-
//
|
|
2138
|
-
// font size
|
|
2139
|
-
// TODO(thure): This appears to be the best or only way to set selection caret heights,
|
|
2140
|
-
// but it's far more verbose than it needs to be.
|
|
2141
|
-
//
|
|
2142
|
-
// ...Object.keys(get(tokens, 'extend.fontSize', {})).reduce((acc: Record<string, any>, fontSize) => {
|
|
2143
|
-
// const height = get(tokens, ['extend', 'fontSize', fontSize, 1, 'lineHeight']);
|
|
2144
|
-
//
|
|
2145
|
-
// acc[`& .text-${fontSize} + .cm-ySelectionCaret`] = { height };
|
|
2146
|
-
// acc[`& .text-${fontSize} + .cm-ySelection + .cm-ySelectionCaret`] = { height };
|
|
2147
|
-
// acc[`& .text-${fontSize} + .cm-widgetBuffer + .cm-ySelectionCaret`] = { height };
|
|
2148
|
-
// return acc;
|
|
2149
|
-
// }, {}),
|
|
2150
|
-
/**
|
|
2151
|
-
* Panels
|
|
2152
|
-
* TODO(burdon): Needs styling attention (esp. dark mode).
|
|
2153
|
-
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
|
2154
|
-
*
|
|
2155
|
-
* Find/replace panel.
|
|
2156
|
-
* <div class="cm-announced">...</div>
|
|
2157
|
-
* <div class="cm-scroller">...</div>
|
|
2158
|
-
* <div class="cm-panels cm-panels-bottom">
|
|
2159
|
-
* <div class="cm-search cm-panel">
|
|
2160
|
-
* <input class="cm-textfield" />
|
|
2161
|
-
* <button class="cm-button">...</button>
|
|
2162
|
-
* <label><input type="checkbox" />...</label>
|
|
2163
|
-
* </div>
|
|
2164
|
-
* </div
|
|
2165
|
-
*/
|
|
2166
|
-
".cm-panels": {
|
|
2167
|
-
border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`
|
|
2168
|
-
},
|
|
2169
|
-
".cm-panel": {
|
|
2170
|
-
background: get3(tokens, "extend.colors.neutral.50"),
|
|
2171
|
-
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
2172
|
-
},
|
|
2173
|
-
".cm-button": {
|
|
2174
|
-
margin: "4px",
|
|
2175
|
-
fontFamily: get3(tokens, "fontFamily.body", []).join(","),
|
|
2176
|
-
background: get3(tokens, "extend.colors.neutral.100"),
|
|
2177
|
-
backgroundImage: "none",
|
|
2178
|
-
border: "none",
|
|
2179
|
-
"&:hover": {
|
|
2180
|
-
background: get3(tokens, "extend.colors.neutral.200")
|
|
2181
|
-
},
|
|
2182
|
-
"&:active": {
|
|
2183
|
-
background: get3(tokens, "extend.colors.neutral.300"),
|
|
2184
|
-
backgroundImage: "none"
|
|
2185
|
-
}
|
|
2186
|
-
},
|
|
2187
|
-
".cm-panel input[type=checkbox]": {
|
|
2188
|
-
marginRight: "0.4rem !important"
|
|
2189
|
-
}
|
|
2190
|
-
};
|
|
2191
|
-
|
|
2192
|
-
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
|
2193
|
-
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
|
|
2194
|
-
var defaults = {
|
|
2195
|
-
bracketMatching: true,
|
|
2196
|
-
closeBrackets: true,
|
|
2197
|
-
drawSelection: true,
|
|
2198
|
-
editable: true,
|
|
2199
|
-
history: true,
|
|
2200
|
-
lineWrapping: true
|
|
2201
|
-
};
|
|
2202
|
-
var createBasicExtensions = (_props) => {
|
|
2203
|
-
const props = defaultsDeep2({}, _props, defaults);
|
|
2204
|
-
return [
|
|
2205
|
-
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
2206
|
-
EditorView10.exceptionSink.of((err) => {
|
|
2207
|
-
log7.catch(err, void 0, {
|
|
2208
|
-
F: __dxlog_file9,
|
|
2209
|
-
L: 78,
|
|
2210
|
-
S: void 0,
|
|
2211
|
-
C: (f, a) => f(...a)
|
|
2212
|
-
});
|
|
2213
|
-
}),
|
|
2214
|
-
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2215
|
-
props.bracketMatching && bracketMatching(),
|
|
2216
|
-
props.closeBrackets && closeBrackets(),
|
|
2217
|
-
props.crosshairCursor && crosshairCursor(),
|
|
2218
|
-
props.dropCursor && dropCursor(),
|
|
2219
|
-
props.drawSelection && drawSelection(),
|
|
2220
|
-
props.highlightActiveLine && highlightActiveLine(),
|
|
2221
|
-
props.history && history(),
|
|
2222
|
-
props.lineNumbers && lineNumbers(),
|
|
2223
|
-
props.lineWrapping && EditorView10.lineWrapping,
|
|
2224
|
-
props.placeholder && placeholder(props.placeholder),
|
|
2225
|
-
props.readonly && [
|
|
2226
|
-
EditorState.readOnly.of(true),
|
|
2227
|
-
EditorView10.editable.of(false)
|
|
2228
|
-
],
|
|
2229
|
-
props.scrollPastEnd && scrollPastEnd(),
|
|
2230
|
-
props.tabSize && EditorState.tabSize.of(props.tabSize)
|
|
2231
|
-
].filter(isNotFalsy2);
|
|
2232
|
-
};
|
|
2233
|
-
var defaultSlots = {
|
|
2234
|
-
editor: {
|
|
2235
|
-
className: "w-full bs-full"
|
|
2236
|
-
},
|
|
2237
|
-
content: {
|
|
2238
|
-
className: "!p-2"
|
|
2239
|
-
}
|
|
2240
|
-
};
|
|
2241
|
-
var createThemeExtensions = ({ theme, themeMode, slots: _slots } = {}) => {
|
|
2242
|
-
const slots = defaultsDeep2({}, _slots, defaultSlots);
|
|
2243
|
-
return [
|
|
2244
|
-
EditorView10.baseTheme(defaultTheme),
|
|
2245
|
-
EditorView10.darkTheme.of(themeMode === "dark"),
|
|
2246
|
-
theme && EditorView10.theme(theme),
|
|
2247
|
-
slots.editor?.className && EditorView10.editorAttributes.of({
|
|
2248
|
-
class: slots.editor.className
|
|
2249
|
-
}),
|
|
2250
|
-
slots.content?.className && EditorView10.contentAttributes.of({
|
|
2251
|
-
class: slots.content.className
|
|
2252
|
-
})
|
|
2253
|
-
].filter(isNotFalsy2);
|
|
2254
|
-
};
|
|
2255
|
-
var createDataExtensions = ({ id, text, space, identity }) => {
|
|
2256
|
-
const extensions = [
|
|
2257
|
-
automerge(text)
|
|
2258
|
-
];
|
|
2259
|
-
if (space && identity) {
|
|
2260
|
-
const peerId = identity?.identityKey.toHex();
|
|
2261
|
-
const { cursorLightValue, cursorDarkValue } = hueTokens[identity?.profile?.data?.hue ?? hexToHue(peerId ?? "0")];
|
|
2262
|
-
const awarenessProvider2 = new SpaceAwarenessProvider({
|
|
2263
|
-
space,
|
|
2264
|
-
channel: `awareness.${id}`,
|
|
2265
|
-
peerId: identity.identityKey.toHex(),
|
|
2266
|
-
info: {
|
|
2267
|
-
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
2268
|
-
color: cursorDarkValue,
|
|
2269
|
-
lightColor: cursorLightValue
|
|
2270
|
-
}
|
|
2271
|
-
});
|
|
2272
|
-
extensions.push(awareness(awarenessProvider2));
|
|
2273
|
-
}
|
|
2274
|
-
return extensions;
|
|
2275
|
-
};
|
|
2276
|
-
|
|
2277
|
-
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
2278
|
-
import { EditorView as EditorView11 } from "@codemirror/view";
|
|
2279
|
-
var listener = ({ onFocus, onChange }) => {
|
|
2280
|
-
const extensions = [];
|
|
2281
|
-
onFocus && extensions.push(EditorView11.focusChangeEffect.of((_, focusing) => {
|
|
2282
|
-
onFocus(focusing);
|
|
2283
|
-
return null;
|
|
2284
|
-
}));
|
|
2285
|
-
onChange && extensions.push(EditorView11.updateListener.of((update2) => {
|
|
2286
|
-
onChange(update2.state.doc.toString());
|
|
2287
|
-
}));
|
|
2288
|
-
return extensions;
|
|
2289
|
-
};
|
|
2290
|
-
|
|
2291
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
2292
|
-
import { closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
2293
|
-
import { historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
2294
|
-
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
2295
|
-
import { defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
2296
|
-
import { languages } from "@codemirror/language-data";
|
|
2297
|
-
import { searchKeymap } from "@codemirror/search";
|
|
2298
|
-
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
2299
|
-
import { keymap as keymap5 } from "@codemirror/view";
|
|
1851
|
+
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
1852
|
+
import { EditorView as EditorView11, drawSelection, dropCursor, keymap as keymap5, placeholder } from "@codemirror/view";
|
|
1853
|
+
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
2300
1854
|
|
|
2301
1855
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
2302
1856
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -2487,8 +2041,19 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
2487
2041
|
};
|
|
2488
2042
|
|
|
2489
2043
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
2490
|
-
var createMarkdownExtensions = ({ themeMode } = {}) => {
|
|
2044
|
+
var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
|
|
2491
2045
|
return [
|
|
2046
|
+
// TODO(burdon): Reconcile with createBasicExtensions.
|
|
2047
|
+
lineWrapping && EditorView11.lineWrapping,
|
|
2048
|
+
EditorState.allowMultipleSelections.of(true),
|
|
2049
|
+
EditorState.tabSize.of(2),
|
|
2050
|
+
bracketMatching(),
|
|
2051
|
+
closeBrackets(),
|
|
2052
|
+
dropCursor(),
|
|
2053
|
+
drawSelection(),
|
|
2054
|
+
history(),
|
|
2055
|
+
indentOnInput(),
|
|
2056
|
+
_placeholder && placeholder(_placeholder),
|
|
2492
2057
|
// Main extension.
|
|
2493
2058
|
// https://github.com/codemirror/lang-markdown
|
|
2494
2059
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -2523,7 +2088,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
|
|
|
2523
2088
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
2524
2089
|
...standardKeymap
|
|
2525
2090
|
])
|
|
2526
|
-
];
|
|
2091
|
+
].filter(isNotFalsy2);
|
|
2527
2092
|
};
|
|
2528
2093
|
|
|
2529
2094
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
|
@@ -3453,8 +3018,8 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3453
3018
|
return true;
|
|
3454
3019
|
};
|
|
3455
3020
|
var toggleList = (type) => (target) => {
|
|
3456
|
-
const
|
|
3457
|
-
const active =
|
|
3021
|
+
const formatting2 = getFormatting(target.state);
|
|
3022
|
+
const active = formatting2.listStyle === (type === 1 ? "bullet" : type === 0 ? "ordered" : "task");
|
|
3458
3023
|
return (active ? removeList(type) : addList(type))(target);
|
|
3459
3024
|
};
|
|
3460
3025
|
var renumberListItems = (item, counter, changes, doc) => {
|
|
@@ -3668,7 +3233,7 @@ var removeCodeblock = ({ state, dispatch }) => {
|
|
|
3668
3233
|
var toggleCodeblock = (target) => {
|
|
3669
3234
|
return (getFormatting(target.state).blockType === "codeblock" ? removeCodeblock : addCodeblock)(target);
|
|
3670
3235
|
};
|
|
3671
|
-
var
|
|
3236
|
+
var formatting = (options = {}) => {
|
|
3672
3237
|
return [
|
|
3673
3238
|
keymap6.of([
|
|
3674
3239
|
{
|
|
@@ -4049,11 +3614,9 @@ var update = (state, options) => {
|
|
|
4049
3614
|
});
|
|
4050
3615
|
tables.forEach((table2) => {
|
|
4051
3616
|
const hide2 = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
}));
|
|
4056
|
-
}
|
|
3617
|
+
hide2 && builder.add(table2.from, table2.to, Decoration7.replace({
|
|
3618
|
+
widget: new TableWidget(table2)
|
|
3619
|
+
}));
|
|
4057
3620
|
builder.add(table2.from, table2.to, Decoration7.mark({
|
|
4058
3621
|
class: "cm-table"
|
|
4059
3622
|
}));
|
|
@@ -4099,8 +3662,8 @@ var TableWidget = class extends WidgetType5 {
|
|
|
4099
3662
|
|
|
4100
3663
|
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
|
4101
3664
|
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
4102
|
-
import { log as
|
|
4103
|
-
var
|
|
3665
|
+
import { log as log6 } from "@dxos/log";
|
|
3666
|
+
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
|
|
4104
3667
|
var mention = ({ onSearch }) => {
|
|
4105
3668
|
return autocompletion2({
|
|
4106
3669
|
// TODO(burdon): Not working.
|
|
@@ -4112,10 +3675,10 @@ var mention = ({ onSearch }) => {
|
|
|
4112
3675
|
icons: false,
|
|
4113
3676
|
override: [
|
|
4114
3677
|
(context) => {
|
|
4115
|
-
|
|
3678
|
+
log6.info("completion context", {
|
|
4116
3679
|
context
|
|
4117
3680
|
}, {
|
|
4118
|
-
F:
|
|
3681
|
+
F: __dxlog_file7,
|
|
4119
3682
|
L: 26,
|
|
4120
3683
|
S: void 0,
|
|
4121
3684
|
C: (f, a) => f(...a)
|
|
@@ -4164,6 +3727,11 @@ var EditorModes = {
|
|
|
4164
3727
|
]
|
|
4165
3728
|
};
|
|
4166
3729
|
|
|
3730
|
+
// packages/ui/react-ui-editor/src/extensions/outliner.ts
|
|
3731
|
+
var outliner = (options = {}) => {
|
|
3732
|
+
return [];
|
|
3733
|
+
};
|
|
3734
|
+
|
|
4167
3735
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
4168
3736
|
import { keymap as keymap8 } from "@codemirror/view";
|
|
4169
3737
|
var defaultItems = [
|
|
@@ -4221,63 +3789,728 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4221
3789
|
];
|
|
4222
3790
|
};
|
|
4223
3791
|
|
|
4224
|
-
// packages/ui/react-ui-editor/src/
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
F: __dxlog_file11,
|
|
4251
|
-
L: 88,
|
|
4252
|
-
S: void 0,
|
|
4253
|
-
C: (f, a) => f(...a)
|
|
3792
|
+
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
3793
|
+
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
3794
|
+
import { Context as Context2 } from "@dxos/context";
|
|
3795
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
3796
|
+
import { log as log7 } from "@dxos/log";
|
|
3797
|
+
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
3798
|
+
var DEBOUNCE_INTERVAL = 100;
|
|
3799
|
+
var SpaceAwarenessProvider = class {
|
|
3800
|
+
constructor(params) {
|
|
3801
|
+
this._remoteStates = /* @__PURE__ */ new Map();
|
|
3802
|
+
this.remoteStateChange = new Event2();
|
|
3803
|
+
this._space = params.space;
|
|
3804
|
+
this._channel = params.channel;
|
|
3805
|
+
this._peerId = params.peerId;
|
|
3806
|
+
this._info = params.info;
|
|
3807
|
+
}
|
|
3808
|
+
open() {
|
|
3809
|
+
this._ctx = new Context2();
|
|
3810
|
+
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
3811
|
+
if (this._localState) {
|
|
3812
|
+
await this._space.postMessage(this._channel, {
|
|
3813
|
+
kind: "post",
|
|
3814
|
+
state: this._localState
|
|
3815
|
+
});
|
|
3816
|
+
await sleep(DEBOUNCE_INTERVAL);
|
|
3817
|
+
}
|
|
4254
3818
|
});
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
3819
|
+
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
3820
|
+
switch (message.payload.kind) {
|
|
3821
|
+
case "query": {
|
|
3822
|
+
this._handleQueryMessage();
|
|
3823
|
+
break;
|
|
3824
|
+
}
|
|
3825
|
+
case "post": {
|
|
3826
|
+
this._handlePostMessage(message.payload);
|
|
3827
|
+
break;
|
|
3828
|
+
}
|
|
3829
|
+
}
|
|
3830
|
+
}));
|
|
3831
|
+
void this._space.postMessage(this._channel, {
|
|
3832
|
+
kind: "query"
|
|
3833
|
+
}).catch((err) => {
|
|
3834
|
+
log7.debug("failed to query awareness", {
|
|
3835
|
+
err
|
|
3836
|
+
}, {
|
|
3837
|
+
F: __dxlog_file8,
|
|
3838
|
+
L: 89,
|
|
3839
|
+
S: this,
|
|
3840
|
+
C: (f, a) => f(...a)
|
|
3841
|
+
});
|
|
3842
|
+
});
|
|
3843
|
+
}
|
|
3844
|
+
close() {
|
|
3845
|
+
void this._ctx?.dispose();
|
|
3846
|
+
this._ctx = void 0;
|
|
3847
|
+
this._postTask = void 0;
|
|
3848
|
+
}
|
|
3849
|
+
getRemoteStates() {
|
|
3850
|
+
return Array.from(this._remoteStates.values());
|
|
3851
|
+
}
|
|
3852
|
+
update(position) {
|
|
3853
|
+
invariant2(this._postTask, void 0, {
|
|
3854
|
+
F: __dxlog_file8,
|
|
3855
|
+
L: 104,
|
|
3856
|
+
S: this,
|
|
3857
|
+
A: [
|
|
3858
|
+
"this._postTask",
|
|
3859
|
+
""
|
|
3860
|
+
]
|
|
3861
|
+
});
|
|
3862
|
+
this._localState = {
|
|
3863
|
+
peerId: this._peerId,
|
|
3864
|
+
position,
|
|
3865
|
+
info: this._info
|
|
3866
|
+
};
|
|
3867
|
+
this._postTask.schedule();
|
|
3868
|
+
}
|
|
3869
|
+
_handleQueryMessage() {
|
|
3870
|
+
invariant2(this._postTask, void 0, {
|
|
3871
|
+
F: __dxlog_file8,
|
|
3872
|
+
L: 115,
|
|
3873
|
+
S: this,
|
|
3874
|
+
A: [
|
|
3875
|
+
"this._postTask",
|
|
3876
|
+
""
|
|
3877
|
+
]
|
|
3878
|
+
});
|
|
3879
|
+
this._postTask.schedule();
|
|
3880
|
+
}
|
|
3881
|
+
_handlePostMessage(message) {
|
|
3882
|
+
invariant2(message.kind === "post", void 0, {
|
|
3883
|
+
F: __dxlog_file8,
|
|
3884
|
+
L: 120,
|
|
3885
|
+
S: this,
|
|
3886
|
+
A: [
|
|
3887
|
+
"message.kind === 'post'",
|
|
3888
|
+
""
|
|
3889
|
+
]
|
|
3890
|
+
});
|
|
3891
|
+
this._remoteStates.set(message.state.peerId, message.state);
|
|
3892
|
+
this.remoteStateChange.emit();
|
|
3893
|
+
}
|
|
3894
|
+
};
|
|
3895
|
+
|
|
3896
|
+
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
3897
|
+
var useActionHandler = (view) => {
|
|
3898
|
+
return (action) => {
|
|
3899
|
+
if (!view) {
|
|
3900
|
+
return;
|
|
3901
|
+
}
|
|
3902
|
+
let inlineType, listType;
|
|
3903
|
+
switch (action.type) {
|
|
3904
|
+
case "heading":
|
|
3905
|
+
setHeading(parseInt(action.data))(view);
|
|
3906
|
+
break;
|
|
3907
|
+
case "strong":
|
|
3908
|
+
case "emphasis":
|
|
3909
|
+
case "strikethrough":
|
|
3910
|
+
case "code":
|
|
3911
|
+
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
3912
|
+
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
3913
|
+
break;
|
|
3914
|
+
case "list-ordered":
|
|
3915
|
+
case "list-bullet":
|
|
3916
|
+
case "list-task":
|
|
3917
|
+
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
3918
|
+
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
3919
|
+
break;
|
|
3920
|
+
case "blockquote":
|
|
3921
|
+
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
3922
|
+
break;
|
|
3923
|
+
case "codeblock":
|
|
3924
|
+
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
3925
|
+
break;
|
|
3926
|
+
case "table":
|
|
3927
|
+
insertTable(view);
|
|
3928
|
+
break;
|
|
3929
|
+
case "link":
|
|
3930
|
+
(action.data === false ? removeLink : addLink)(view);
|
|
3931
|
+
break;
|
|
3932
|
+
case "comment":
|
|
3933
|
+
createComment(view);
|
|
3934
|
+
break;
|
|
3935
|
+
}
|
|
3936
|
+
setTimeout(() => {
|
|
3937
|
+
if (!view.hasFocus) {
|
|
3938
|
+
view.focus();
|
|
3939
|
+
}
|
|
3940
|
+
});
|
|
3941
|
+
};
|
|
3942
|
+
};
|
|
3943
|
+
|
|
3944
|
+
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
3945
|
+
import { useRef, useState as useState2 } from "react";
|
|
3946
|
+
var useEditorView = (id) => {
|
|
3947
|
+
const editorRef = useRef(null);
|
|
3948
|
+
const [prev, setPrev] = useState2([
|
|
3949
|
+
null,
|
|
3950
|
+
""
|
|
3951
|
+
]);
|
|
3952
|
+
if (prev[0] !== editorRef.current) {
|
|
3953
|
+
setPrev([
|
|
3954
|
+
editorRef.current,
|
|
3955
|
+
id
|
|
3956
|
+
]);
|
|
3957
|
+
}
|
|
3958
|
+
return [
|
|
3959
|
+
editorRef,
|
|
3960
|
+
prev[1] !== id
|
|
3961
|
+
];
|
|
3962
|
+
};
|
|
3963
|
+
|
|
3964
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
3965
|
+
import { closeBrackets as closeBrackets2 } from "@codemirror/autocomplete";
|
|
3966
|
+
import { history as history2 } from "@codemirror/commands";
|
|
3967
|
+
import { bracketMatching as bracketMatching2 } from "@codemirror/language";
|
|
3968
|
+
import { EditorSelection as EditorSelection2, EditorState as EditorState2 } from "@codemirror/state";
|
|
3969
|
+
import { crosshairCursor, drawSelection as drawSelection2, dropCursor as dropCursor2, EditorView as EditorView16, highlightActiveLine, lineNumbers, placeholder as placeholder2, scrollPastEnd } from "@codemirror/view";
|
|
3970
|
+
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
3971
|
+
import { useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
|
|
3972
|
+
import { log as log8 } from "@dxos/log";
|
|
3973
|
+
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
3974
|
+
|
|
3975
|
+
// packages/ui/react-ui-editor/src/themes/default.ts
|
|
3976
|
+
import get4 from "lodash.get";
|
|
3977
|
+
var defaultTheme = {
|
|
3978
|
+
//
|
|
3979
|
+
// Main layout:
|
|
3980
|
+
// https://codemirror.net/examples/styling
|
|
3981
|
+
//
|
|
3982
|
+
// <div class="cm-editor [cm-focused] [generated classes]">
|
|
3983
|
+
// <div class="cm-scroller">
|
|
3984
|
+
// <div class="cm-gutters">
|
|
3985
|
+
// <div class="cm-gutter [...]">
|
|
3986
|
+
// <div class="cm-gutterElement">...</div>
|
|
3987
|
+
// </div>
|
|
3988
|
+
// </div>
|
|
3989
|
+
// <div class="cm-content" role="textbox" contenteditable="true">
|
|
3990
|
+
// <div class="cm-line"></div>
|
|
3991
|
+
// </div>
|
|
3992
|
+
// <div class="cm-selectionLayer">
|
|
3993
|
+
// <div class="cm-selectionBackground"></div>
|
|
3994
|
+
// </div>
|
|
3995
|
+
// <div class="cm-cursorLayer">
|
|
3996
|
+
// <div class="cm-cursor"></div>
|
|
3997
|
+
// </div>
|
|
3998
|
+
// </div>
|
|
3999
|
+
// </div>
|
|
4000
|
+
//
|
|
4001
|
+
"&": {},
|
|
4002
|
+
"&.cm-focused": {
|
|
4003
|
+
outline: "none"
|
|
4004
|
+
},
|
|
4005
|
+
// NOTE: See https://codemirror.net/docs/guide (DOM Structure).
|
|
4006
|
+
".cm-scroller": {
|
|
4007
|
+
// TODO(burdon): Reconcile with docs: https://codemirror.net/docs/guide
|
|
4008
|
+
// Inside of that is the scroller element. If the editor has its own scrollbar, this one should be styled with overflow: auto. But it doesn't have to—the editor also supports growing to accomodate its content, or growing up to a certain max-height and then scrolling.
|
|
4009
|
+
overflowY: "auto",
|
|
4010
|
+
fontFamily: get4(tokens, "fontFamily.mono", []).join(","),
|
|
4011
|
+
lineHeight: 1.5
|
|
4012
|
+
},
|
|
4013
|
+
".cm-content": {
|
|
4014
|
+
// TODO(burdon): Is it possible to remove the padding value from CM's default theme?
|
|
4015
|
+
// padding: 'unset',
|
|
4016
|
+
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
|
4017
|
+
fontSize: "16px"
|
|
4018
|
+
},
|
|
4019
|
+
"&light .cm-content": {
|
|
4020
|
+
color: get4(tokens, "extend.semanticColors.base.fg.light", "black"),
|
|
4021
|
+
caretColor: "black"
|
|
4022
|
+
},
|
|
4023
|
+
"&dark .cm-content": {
|
|
4024
|
+
color: get4(tokens, "extend.semanticColors.base.fg.dark", "white"),
|
|
4025
|
+
caretColor: "white"
|
|
4026
|
+
},
|
|
4027
|
+
//
|
|
4028
|
+
// Cursor
|
|
4029
|
+
//
|
|
4030
|
+
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
4031
|
+
borderLeft: "2px solid black"
|
|
4032
|
+
},
|
|
4033
|
+
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
4034
|
+
borderLeft: "2px solid white"
|
|
4035
|
+
},
|
|
4036
|
+
"&light .cm-placeholder": {
|
|
4037
|
+
color: get4(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
4038
|
+
},
|
|
4039
|
+
"&dark .cm-placeholder": {
|
|
4040
|
+
color: get4(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
4041
|
+
},
|
|
4042
|
+
//
|
|
4043
|
+
// line
|
|
4044
|
+
//
|
|
4045
|
+
".cm-line": {
|
|
4046
|
+
paddingInline: 0
|
|
4047
|
+
},
|
|
4048
|
+
".cm-activeLine": {
|
|
4049
|
+
background: "transparent"
|
|
4050
|
+
},
|
|
4051
|
+
//
|
|
4052
|
+
// gutter
|
|
4053
|
+
//
|
|
4054
|
+
".cm-gutterElement": {
|
|
4055
|
+
width: "48px"
|
|
4056
|
+
},
|
|
4057
|
+
//
|
|
4058
|
+
// Selection
|
|
4059
|
+
//
|
|
4060
|
+
"&light .cm-selectionBackground": {
|
|
4061
|
+
background: get4(tokens, "extend.colors.primary.100")
|
|
4062
|
+
},
|
|
4063
|
+
"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
4064
|
+
background: get4(tokens, "extend.colors.primary.200")
|
|
4065
|
+
},
|
|
4066
|
+
"&dark .cm-selectionBackground": {
|
|
4067
|
+
background: get4(tokens, "extend.colors.primary.700")
|
|
4068
|
+
},
|
|
4069
|
+
"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
4070
|
+
background: get4(tokens, "extend.colors.primary.600")
|
|
4071
|
+
},
|
|
4072
|
+
//
|
|
4073
|
+
// Search
|
|
4074
|
+
//
|
|
4075
|
+
"&light .cm-searchMatch": {
|
|
4076
|
+
backgroundColor: get4(tokens, "extend.colors.yellow.100")
|
|
4077
|
+
},
|
|
4078
|
+
"&dark .cm-searchMatch": {
|
|
4079
|
+
backgroundColor: get4(tokens, "extend.colors.yellow.700")
|
|
4080
|
+
},
|
|
4081
|
+
//
|
|
4082
|
+
// link
|
|
4083
|
+
//
|
|
4084
|
+
".cm-link": {
|
|
4085
|
+
color: get4(tokens, "extend.colors.primary.500"),
|
|
4086
|
+
textDecorationLine: "underline",
|
|
4087
|
+
textDecorationThickness: "1px",
|
|
4088
|
+
textUnderlineOffset: "2px",
|
|
4089
|
+
borderRadius: ".125rem",
|
|
4090
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4091
|
+
},
|
|
4092
|
+
//
|
|
4093
|
+
// tooltip
|
|
4094
|
+
//
|
|
4095
|
+
".cm-tooltip": {
|
|
4096
|
+
border: "none",
|
|
4097
|
+
background: "unset"
|
|
4098
|
+
},
|
|
4099
|
+
".cm-tooltip-below": {},
|
|
4100
|
+
//
|
|
4101
|
+
// autocomplete
|
|
4102
|
+
//
|
|
4103
|
+
".cm-tooltip-autocomplete": {
|
|
4104
|
+
marginTop: "4px",
|
|
4105
|
+
marginLeft: "-3px"
|
|
4106
|
+
},
|
|
4107
|
+
".cm-tooltip-autocomplete ul li": {},
|
|
4108
|
+
".cm-tooltip-autocomplete ul li[aria-selected]": {},
|
|
4109
|
+
".cm-completionIcon": {
|
|
4110
|
+
display: "none"
|
|
4111
|
+
},
|
|
4112
|
+
".cm-completionLabel": {
|
|
4113
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4114
|
+
},
|
|
4115
|
+
".cm-completionMatchedText": {
|
|
4116
|
+
textDecoration: "none"
|
|
4117
|
+
},
|
|
4118
|
+
//
|
|
4119
|
+
// table
|
|
4120
|
+
//
|
|
4121
|
+
".cm-table *": {
|
|
4122
|
+
fontFamily: `${get4(tokens, "fontFamily.mono", []).join(",")} !important`,
|
|
4123
|
+
textDecoration: "none !important"
|
|
4124
|
+
},
|
|
4125
|
+
".cm-table-head": {
|
|
4126
|
+
padding: "2px 16px 2px 0px",
|
|
4127
|
+
borderBottom: `1px solid ${get4(tokens, "extend.colors.neutral.500")}`,
|
|
4128
|
+
fontWeight: 100,
|
|
4129
|
+
textAlign: "left",
|
|
4130
|
+
color: get4(tokens, "extend.colors.neutral.500")
|
|
4131
|
+
},
|
|
4132
|
+
".cm-table-cell": {
|
|
4133
|
+
padding: "2px 16px 2px 0px"
|
|
4134
|
+
},
|
|
4135
|
+
//
|
|
4136
|
+
// image
|
|
4137
|
+
//
|
|
4138
|
+
".cm-image": {
|
|
4139
|
+
display: "block",
|
|
4140
|
+
height: "0"
|
|
4141
|
+
},
|
|
4142
|
+
".cm-image.cm-loaded-image": {
|
|
4143
|
+
height: "auto",
|
|
4144
|
+
borderTop: "0.5rem solid transparent",
|
|
4145
|
+
borderBottom: "0.5rem solid transparent"
|
|
4146
|
+
},
|
|
4147
|
+
//
|
|
4148
|
+
// font size
|
|
4149
|
+
// TODO(thure): This appears to be the best or only way to set selection caret heights,
|
|
4150
|
+
// but it's far more verbose than it needs to be.
|
|
4151
|
+
//
|
|
4152
|
+
// ...Object.keys(get(tokens, 'extend.fontSize', {})).reduce((acc: Record<string, any>, fontSize) => {
|
|
4153
|
+
// const height = get(tokens, ['extend', 'fontSize', fontSize, 1, 'lineHeight']);
|
|
4154
|
+
//
|
|
4155
|
+
// acc[`& .text-${fontSize} + .cm-ySelectionCaret`] = { height };
|
|
4156
|
+
// acc[`& .text-${fontSize} + .cm-ySelection + .cm-ySelectionCaret`] = { height };
|
|
4157
|
+
// acc[`& .text-${fontSize} + .cm-widgetBuffer + .cm-ySelectionCaret`] = { height };
|
|
4158
|
+
// return acc;
|
|
4159
|
+
// }, {}),
|
|
4160
|
+
/**
|
|
4161
|
+
* Panels
|
|
4162
|
+
* TODO(burdon): Needs styling attention (esp. dark mode).
|
|
4163
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
|
4164
|
+
*
|
|
4165
|
+
* Find/replace panel.
|
|
4166
|
+
* <div class="cm-announced">...</div>
|
|
4167
|
+
* <div class="cm-scroller">...</div>
|
|
4168
|
+
* <div class="cm-panels cm-panels-bottom">
|
|
4169
|
+
* <div class="cm-search cm-panel">
|
|
4170
|
+
* <input class="cm-textfield" />
|
|
4171
|
+
* <button class="cm-button">...</button>
|
|
4172
|
+
* <label><input type="checkbox" />...</label>
|
|
4173
|
+
* </div>
|
|
4174
|
+
* </div
|
|
4175
|
+
*/
|
|
4176
|
+
".cm-panels": {
|
|
4177
|
+
border: `1px solid ${get4(tokens, "extend.colors.neutral.200")}`
|
|
4178
|
+
},
|
|
4179
|
+
".cm-panel": {
|
|
4180
|
+
background: get4(tokens, "extend.colors.neutral.50"),
|
|
4181
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4182
|
+
},
|
|
4183
|
+
".cm-button": {
|
|
4184
|
+
margin: "4px",
|
|
4185
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(","),
|
|
4186
|
+
background: get4(tokens, "extend.colors.neutral.100"),
|
|
4187
|
+
backgroundImage: "none",
|
|
4188
|
+
border: "none",
|
|
4189
|
+
"&:hover": {
|
|
4190
|
+
background: get4(tokens, "extend.colors.neutral.200")
|
|
4191
|
+
},
|
|
4192
|
+
"&:active": {
|
|
4193
|
+
background: get4(tokens, "extend.colors.neutral.300"),
|
|
4194
|
+
backgroundImage: "none"
|
|
4195
|
+
}
|
|
4196
|
+
},
|
|
4197
|
+
".cm-panel input[type=checkbox]": {
|
|
4198
|
+
marginRight: "0.4rem !important"
|
|
4199
|
+
}
|
|
4200
|
+
};
|
|
4201
|
+
var textTheme = {
|
|
4202
|
+
".cm-scroller": {
|
|
4203
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4204
|
+
},
|
|
4205
|
+
".cm-placeholder": {
|
|
4206
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4207
|
+
}
|
|
4208
|
+
};
|
|
4209
|
+
var markdownTheme = {
|
|
4210
|
+
".cm-scroller": {
|
|
4211
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4212
|
+
},
|
|
4213
|
+
".cm-placeholder": {
|
|
4214
|
+
fontFamily: get4(tokens, "fontFamily.body", []).join(",")
|
|
4215
|
+
}
|
|
4216
|
+
};
|
|
4217
|
+
var codeTheme = {
|
|
4218
|
+
".cm-scroller": {
|
|
4219
|
+
fontFamily: get4(tokens, "fontFamily.mono", []).join(",")
|
|
4220
|
+
},
|
|
4221
|
+
".cm-placeholder": {
|
|
4222
|
+
fontFamily: get4(tokens, "fontFamily.mono", []).join(",")
|
|
4223
|
+
}
|
|
4224
|
+
};
|
|
4225
|
+
|
|
4226
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4227
|
+
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4228
|
+
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}, deps = []) => {
|
|
4229
|
+
const onUpdate = useRef2();
|
|
4230
|
+
const [view, setView] = useState3();
|
|
4231
|
+
const parentRef = useRef2(null);
|
|
4232
|
+
useEffect2(() => {
|
|
4233
|
+
let view2;
|
|
4234
|
+
if (parentRef.current) {
|
|
4235
|
+
const state = EditorState2.create({
|
|
4236
|
+
doc,
|
|
4237
|
+
selection,
|
|
4238
|
+
extensions: [
|
|
4239
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4240
|
+
EditorView16.exceptionSink.of((err) => {
|
|
4241
|
+
log8.catch(err, void 0, {
|
|
4242
|
+
F: __dxlog_file9,
|
|
4243
|
+
L: 70,
|
|
4244
|
+
S: void 0,
|
|
4245
|
+
C: (f, a) => f(...a)
|
|
4246
|
+
});
|
|
4247
|
+
}),
|
|
4248
|
+
extensions,
|
|
4249
|
+
EditorView16.updateListener.of(() => {
|
|
4250
|
+
onUpdate.current?.();
|
|
4251
|
+
})
|
|
4252
|
+
].filter(isNotFalsy3)
|
|
4253
|
+
});
|
|
4254
|
+
view2 = new EditorView16({
|
|
4255
|
+
parent: parentRef.current,
|
|
4256
|
+
scrollTo,
|
|
4257
|
+
state,
|
|
4258
|
+
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4259
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4260
|
+
dispatchTransactions: (trs, view3) => {
|
|
4261
|
+
if (debug) {
|
|
4262
|
+
logChanges(trs);
|
|
4263
|
+
}
|
|
4264
|
+
view3.update(trs);
|
|
4265
|
+
}
|
|
4266
|
+
});
|
|
4267
|
+
setView(view2);
|
|
4268
|
+
}
|
|
4269
|
+
return () => {
|
|
4270
|
+
view2?.destroy();
|
|
4271
|
+
};
|
|
4272
|
+
}, deps);
|
|
4273
|
+
useEffect2(() => {
|
|
4274
|
+
if (view) {
|
|
4275
|
+
if (!selection && !view.state.selection.main.anchor) {
|
|
4276
|
+
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4277
|
+
}
|
|
4278
|
+
if (selection || scrollTo) {
|
|
4279
|
+
onUpdate.current = () => {
|
|
4280
|
+
onUpdate.current = void 0;
|
|
4281
|
+
view.dispatch({
|
|
4282
|
+
selection,
|
|
4283
|
+
effects: scrollTo && [
|
|
4284
|
+
scrollTo
|
|
4285
|
+
],
|
|
4286
|
+
scrollIntoView: !scrollTo
|
|
4287
|
+
});
|
|
4288
|
+
};
|
|
4289
|
+
}
|
|
4290
|
+
if (autoFocus) {
|
|
4291
|
+
view.focus();
|
|
4292
|
+
}
|
|
4293
|
+
}
|
|
4294
|
+
}, [
|
|
4295
|
+
view,
|
|
4296
|
+
autoFocus,
|
|
4297
|
+
selection,
|
|
4298
|
+
scrollTo
|
|
4299
|
+
]);
|
|
4300
|
+
return {
|
|
4301
|
+
parentRef,
|
|
4302
|
+
view
|
|
4303
|
+
};
|
|
4304
|
+
};
|
|
4305
|
+
var defaults = {
|
|
4306
|
+
bracketMatching: true,
|
|
4307
|
+
closeBrackets: true,
|
|
4308
|
+
drawSelection: true,
|
|
4309
|
+
editable: true,
|
|
4310
|
+
history: true,
|
|
4311
|
+
lineWrapping: true
|
|
4312
|
+
};
|
|
4313
|
+
var createBasicExtensions = (_props) => {
|
|
4314
|
+
const props = defaultsDeep2({}, _props, defaults);
|
|
4315
|
+
return [
|
|
4316
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4317
|
+
EditorView16.exceptionSink.of((err) => {
|
|
4318
|
+
log8.catch(err, void 0, {
|
|
4319
|
+
F: __dxlog_file9,
|
|
4320
|
+
L: 167,
|
|
4321
|
+
S: void 0,
|
|
4322
|
+
C: (f, a) => f(...a)
|
|
4323
|
+
});
|
|
4324
|
+
}),
|
|
4325
|
+
props.allowMultipleSelections && EditorState2.allowMultipleSelections.of(true),
|
|
4326
|
+
props.bracketMatching && bracketMatching2(),
|
|
4327
|
+
props.closeBrackets && closeBrackets2(),
|
|
4328
|
+
props.crosshairCursor && crosshairCursor(),
|
|
4329
|
+
props.dropCursor && dropCursor2(),
|
|
4330
|
+
props.drawSelection && drawSelection2(),
|
|
4331
|
+
props.highlightActiveLine && highlightActiveLine(),
|
|
4332
|
+
props.history && history2(),
|
|
4333
|
+
props.lineNumbers && lineNumbers(),
|
|
4334
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
4335
|
+
props.placeholder && placeholder2(props.placeholder),
|
|
4336
|
+
props.readonly && [
|
|
4337
|
+
EditorState2.readOnly.of(true),
|
|
4338
|
+
EditorView16.editable.of(false)
|
|
4339
|
+
],
|
|
4340
|
+
props.scrollPastEnd && scrollPastEnd(),
|
|
4341
|
+
props.tabSize && EditorState2.tabSize.of(props.tabSize)
|
|
4342
|
+
].filter(isNotFalsy3);
|
|
4343
|
+
};
|
|
4344
|
+
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4345
|
+
return [
|
|
4346
|
+
EditorView16.baseTheme(defaultTheme),
|
|
4347
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
4348
|
+
theme && EditorView16.theme(theme),
|
|
4349
|
+
slots?.editor?.className && EditorView16.editorAttributes.of({
|
|
4350
|
+
class: slots.editor.className
|
|
4351
|
+
}),
|
|
4352
|
+
slots?.content?.className && EditorView16.contentAttributes.of({
|
|
4353
|
+
class: slots.content.className
|
|
4354
|
+
})
|
|
4355
|
+
].filter(isNotFalsy3);
|
|
4356
|
+
};
|
|
4357
|
+
|
|
4358
|
+
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
4359
|
+
import get5 from "lodash.get";
|
|
4360
|
+
import { useState as useState4, useMemo as useMemo2 } from "react";
|
|
4361
|
+
import { generateName } from "@dxos/display-name";
|
|
4362
|
+
import { getRawDoc } from "@dxos/echo-schema";
|
|
4363
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
4364
|
+
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
4365
|
+
import { hueTokens } from "@dxos/react-ui-theme";
|
|
4366
|
+
import { hexToHue } from "@dxos/util";
|
|
4367
|
+
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
4368
|
+
var useTextExtensions = ({ id, text, space, identity }) => {
|
|
4369
|
+
const extensions = [
|
|
4370
|
+
automerge(text)
|
|
4371
|
+
];
|
|
4372
|
+
const peerId = identity?.identityKey.toHex();
|
|
4373
|
+
const { cursorLightValue, cursorDarkValue } = hueTokens[identity?.profile?.data?.hue ?? hexToHue(peerId ?? "0")];
|
|
4374
|
+
if (space && identity) {
|
|
4375
|
+
const awarenessProvider2 = new SpaceAwarenessProvider({
|
|
4376
|
+
space,
|
|
4377
|
+
channel: `awareness.${id}`,
|
|
4378
|
+
peerId: identity.identityKey.toHex(),
|
|
4379
|
+
info: {
|
|
4380
|
+
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
4381
|
+
color: cursorDarkValue,
|
|
4382
|
+
lightColor: cursorLightValue
|
|
4383
|
+
}
|
|
4384
|
+
});
|
|
4385
|
+
extensions.push(awareness(awarenessProvider2));
|
|
4386
|
+
}
|
|
4387
|
+
return extensions;
|
|
4388
|
+
};
|
|
4389
|
+
var useTextModel = (props) => useMemo2(() => createModel(props), Object.values(props));
|
|
4390
|
+
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4391
|
+
const [content, setContent] = useState4(defaultContent ?? "");
|
|
4392
|
+
return {
|
|
4393
|
+
id,
|
|
4394
|
+
content,
|
|
4395
|
+
text: () => content,
|
|
4396
|
+
setContent
|
|
4397
|
+
};
|
|
4398
|
+
};
|
|
4399
|
+
var createModel = ({ space, identity, text }) => {
|
|
4400
|
+
if (!text) {
|
|
4401
|
+
return void 0;
|
|
4402
|
+
}
|
|
4403
|
+
invariant3(isAutomergeObject(text), void 0, {
|
|
4404
|
+
F: __dxlog_file10,
|
|
4405
|
+
L: 89,
|
|
4406
|
+
S: void 0,
|
|
4407
|
+
A: [
|
|
4408
|
+
"isAutomergeObject(text)",
|
|
4409
|
+
""
|
|
4410
|
+
]
|
|
4411
|
+
});
|
|
4412
|
+
const obj = text;
|
|
4413
|
+
const doc = getRawDoc(obj, [
|
|
4414
|
+
obj.field
|
|
4415
|
+
]);
|
|
4416
|
+
const peerId = identity?.identityKey.toHex();
|
|
4417
|
+
const { cursorLightValue, cursorDarkValue } = hueTokens[identity?.profile?.data?.hue ?? hexToHue(peerId ?? "0")];
|
|
4418
|
+
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
4419
|
+
space,
|
|
4420
|
+
channel: `automerge.awareness.${obj.id}`,
|
|
4421
|
+
info: {
|
|
4422
|
+
displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
|
|
4423
|
+
color: cursorLightValue,
|
|
4424
|
+
lightColor: cursorDarkValue
|
|
4425
|
+
},
|
|
4426
|
+
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
4427
|
+
});
|
|
4428
|
+
const extensions = [
|
|
4429
|
+
automerge({
|
|
4430
|
+
handle: doc.handle,
|
|
4431
|
+
path: doc.path
|
|
4432
|
+
})
|
|
4433
|
+
];
|
|
4434
|
+
if (awarenessProvider2) {
|
|
4435
|
+
extensions.push(awareness(awarenessProvider2));
|
|
4436
|
+
}
|
|
4437
|
+
return {
|
|
4438
|
+
id: obj.id,
|
|
4439
|
+
content: doc,
|
|
4440
|
+
text: () => get5(doc.handle.docSync(), doc.path),
|
|
4441
|
+
extension: extensions
|
|
4442
|
+
};
|
|
4443
|
+
};
|
|
4444
|
+
|
|
4445
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
4446
|
+
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
4447
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo = EditorView17.scrollIntoView(0), moveToEndOfLine, selection, theme, slots = defaultSlots, extensions = [], scrollPastEnd: _scrollPastEnd, debug }, forwardedRef) => {
|
|
4448
|
+
const tabsterDOMAttribute = useFocusableGroup({
|
|
4449
|
+
tabBehavior: "limited"
|
|
4450
|
+
});
|
|
4451
|
+
const { themeMode } = useThemeContext();
|
|
4452
|
+
const rootRef = useRef3(null);
|
|
4453
|
+
const [view, setView] = useState5(null);
|
|
4454
|
+
useImperativeHandle(forwardedRef, () => view, [
|
|
4455
|
+
view
|
|
4456
|
+
]);
|
|
4457
|
+
useEffect3(() => {
|
|
4458
|
+
if (autoFocus) {
|
|
4459
|
+
view?.focus();
|
|
4460
|
+
}
|
|
4461
|
+
}, [
|
|
4462
|
+
view,
|
|
4463
|
+
autoFocus
|
|
4464
|
+
]);
|
|
4465
|
+
useEffect3(() => {
|
|
4466
|
+
if (!model || !rootRef.current) {
|
|
4467
|
+
return;
|
|
4468
|
+
}
|
|
4469
|
+
const state = EditorState3.create({
|
|
4470
|
+
doc: typeof model.content === "string" ? model.content : DocAccessor.getValue(model.content),
|
|
4471
|
+
selection,
|
|
4472
|
+
extensions: [
|
|
4473
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4474
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4475
|
+
log9.catch(err, void 0, {
|
|
4263
4476
|
F: __dxlog_file11,
|
|
4264
|
-
L:
|
|
4477
|
+
L: 123,
|
|
4265
4478
|
S: void 0,
|
|
4266
4479
|
C: (f, a) => f(...a)
|
|
4267
4480
|
});
|
|
4268
4481
|
}),
|
|
4482
|
+
// Theme.
|
|
4483
|
+
// TODO(burdon): Make base theme configurable.
|
|
4484
|
+
EditorView17.baseTheme(defaultTheme),
|
|
4485
|
+
theme && EditorView17.theme(theme),
|
|
4486
|
+
EditorView17.darkTheme.of(themeMode === "dark"),
|
|
4487
|
+
slots.editor?.className && EditorView17.editorAttributes.of({
|
|
4488
|
+
class: slots.editor.className
|
|
4489
|
+
}),
|
|
4490
|
+
slots.content?.className && EditorView17.contentAttributes.of({
|
|
4491
|
+
class: slots.content.className
|
|
4492
|
+
}),
|
|
4493
|
+
// NOTE: Assumes default line height.
|
|
4494
|
+
_scrollPastEnd && scrollPastEnd2(),
|
|
4269
4495
|
// Focus.
|
|
4270
|
-
|
|
4496
|
+
EditorView17.updateListener.of((update2) => {
|
|
4271
4497
|
update2.transactions.forEach((transaction) => {
|
|
4272
4498
|
if (transaction.isUserEvent("focus.container")) {
|
|
4273
4499
|
rootRef.current?.focus();
|
|
4274
4500
|
}
|
|
4275
4501
|
});
|
|
4276
4502
|
}),
|
|
4277
|
-
|
|
4278
|
-
|
|
4503
|
+
// State.
|
|
4504
|
+
EditorView17.editable.of(!readonly),
|
|
4505
|
+
EditorState3.readOnly.of(!!readonly),
|
|
4506
|
+
// Storage and replication.
|
|
4507
|
+
// NOTE: This must come before user extensions.
|
|
4508
|
+
model.extension,
|
|
4509
|
+
// Custom.
|
|
4510
|
+
...extensions
|
|
4511
|
+
].filter(isNotFalsy4)
|
|
4279
4512
|
});
|
|
4280
|
-
const view2 = new
|
|
4513
|
+
const view2 = new EditorView17({
|
|
4281
4514
|
state,
|
|
4282
4515
|
parent: rootRef.current,
|
|
4283
4516
|
scrollTo,
|
|
@@ -4300,16 +4533,18 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4300
4533
|
});
|
|
4301
4534
|
}
|
|
4302
4535
|
if (state.facet(editorMode).noTabster) {
|
|
4303
|
-
rootRef.current
|
|
4536
|
+
rootRef.current.removeAttribute("data-tabster");
|
|
4304
4537
|
}
|
|
4305
4538
|
return () => {
|
|
4306
4539
|
view2?.destroy();
|
|
4307
4540
|
setView(null);
|
|
4308
4541
|
};
|
|
4309
4542
|
}, [
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4543
|
+
rootRef,
|
|
4544
|
+
extensions,
|
|
4545
|
+
model,
|
|
4546
|
+
readonly,
|
|
4547
|
+
themeMode
|
|
4313
4548
|
]);
|
|
4314
4549
|
const handleKeyUp = useCallback((event) => {
|
|
4315
4550
|
const { key } = event;
|
|
@@ -4325,18 +4560,82 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4325
4560
|
return /* @__PURE__ */ React.createElement("div", {
|
|
4326
4561
|
role: "none",
|
|
4327
4562
|
ref: rootRef,
|
|
4563
|
+
key: model.id,
|
|
4328
4564
|
tabIndex: 0,
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
...tabsterDOMAttribute
|
|
4332
|
-
|
|
4565
|
+
onKeyUp: handleKeyUp,
|
|
4566
|
+
...slots.root,
|
|
4567
|
+
...tabsterDOMAttribute
|
|
4568
|
+
});
|
|
4569
|
+
});
|
|
4570
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping = true, theme = textTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
4571
|
+
const { themeMode } = useThemeContext();
|
|
4572
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultTextSlots);
|
|
4573
|
+
const extensions = useMemo3(() => [
|
|
4574
|
+
createBasicExtensions({
|
|
4575
|
+
lineWrapping,
|
|
4576
|
+
placeholder: placeholder3
|
|
4577
|
+
}),
|
|
4578
|
+
createThemeExtensions({
|
|
4579
|
+
themeMode
|
|
4580
|
+
}),
|
|
4581
|
+
..._extensions ?? []
|
|
4582
|
+
], [
|
|
4583
|
+
themeMode,
|
|
4584
|
+
placeholder3,
|
|
4585
|
+
lineWrapping,
|
|
4586
|
+
_extensions
|
|
4587
|
+
]);
|
|
4588
|
+
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
4589
|
+
ref: forwardedRef,
|
|
4590
|
+
readonly,
|
|
4591
|
+
extensions,
|
|
4592
|
+
theme,
|
|
4593
|
+
slots: updatedSlots,
|
|
4594
|
+
...props
|
|
4595
|
+
});
|
|
4596
|
+
});
|
|
4597
|
+
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, theme = markdownTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
4598
|
+
const { themeMode } = useThemeContext();
|
|
4599
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultMarkdownSlots);
|
|
4600
|
+
const extensions = useMemo3(() => [
|
|
4601
|
+
createMarkdownExtensions({
|
|
4602
|
+
themeMode,
|
|
4603
|
+
placeholder: placeholder3
|
|
4604
|
+
}),
|
|
4605
|
+
..._extensions ?? []
|
|
4606
|
+
], [
|
|
4607
|
+
themeMode,
|
|
4608
|
+
placeholder3,
|
|
4609
|
+
_extensions
|
|
4610
|
+
]);
|
|
4611
|
+
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
4612
|
+
ref: forwardedRef,
|
|
4613
|
+
readonly,
|
|
4614
|
+
extensions,
|
|
4615
|
+
theme,
|
|
4616
|
+
slots: updatedSlots,
|
|
4617
|
+
...props
|
|
4333
4618
|
});
|
|
4334
4619
|
});
|
|
4620
|
+
var defaultSlots = {
|
|
4621
|
+
root: {
|
|
4622
|
+
className: focusRing
|
|
4623
|
+
},
|
|
4624
|
+
editor: {
|
|
4625
|
+
className: "bs-full"
|
|
4626
|
+
}
|
|
4627
|
+
};
|
|
4628
|
+
var defaultTextSlots = {
|
|
4629
|
+
...defaultSlots
|
|
4630
|
+
};
|
|
4631
|
+
var defaultMarkdownSlots = {
|
|
4632
|
+
...defaultSlots
|
|
4633
|
+
};
|
|
4335
4634
|
|
|
4336
4635
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
4337
4636
|
import { ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, Quotes } from "@phosphor-icons/react";
|
|
4338
4637
|
import { createContext } from "@radix-ui/react-context";
|
|
4339
|
-
import React2, { useRef as
|
|
4638
|
+
import React2, { useRef as useRef4, useState as useState6 } from "react";
|
|
4340
4639
|
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
4341
4640
|
import { getSize } from "@dxos/react-ui-theme";
|
|
4342
4641
|
var tooltipProps = {
|
|
@@ -4394,9 +4693,9 @@ var MarkdownHeading = () => {
|
|
|
4394
4693
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4395
4694
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4396
4695
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
4397
|
-
const suppressNextTooltip =
|
|
4398
|
-
const [tooltipOpen, setTooltipOpen] =
|
|
4399
|
-
const [selectOpen, setSelectOpen] =
|
|
4696
|
+
const suppressNextTooltip = useRef4(false);
|
|
4697
|
+
const [tooltipOpen, setTooltipOpen] = useState6(false);
|
|
4698
|
+
const [selectOpen, setSelectOpen] = useState6(false);
|
|
4400
4699
|
return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
|
|
4401
4700
|
open: tooltipOpen,
|
|
4402
4701
|
onOpenChange: (nextOpen) => {
|
|
@@ -4599,160 +4898,14 @@ var Toolbar = {
|
|
|
4599
4898
|
Markdown: MarkdownStandard,
|
|
4600
4899
|
Extended: MarkdownExtended
|
|
4601
4900
|
};
|
|
4602
|
-
|
|
4603
|
-
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
4604
|
-
var useActionHandler = (view) => {
|
|
4605
|
-
return (action) => {
|
|
4606
|
-
if (!view) {
|
|
4607
|
-
return;
|
|
4608
|
-
}
|
|
4609
|
-
let inlineType, listType;
|
|
4610
|
-
switch (action.type) {
|
|
4611
|
-
case "heading":
|
|
4612
|
-
setHeading(parseInt(action.data))(view);
|
|
4613
|
-
break;
|
|
4614
|
-
case "strong":
|
|
4615
|
-
case "emphasis":
|
|
4616
|
-
case "strikethrough":
|
|
4617
|
-
case "code":
|
|
4618
|
-
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
4619
|
-
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
4620
|
-
break;
|
|
4621
|
-
case "list-ordered":
|
|
4622
|
-
case "list-bullet":
|
|
4623
|
-
case "list-task":
|
|
4624
|
-
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
4625
|
-
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
4626
|
-
break;
|
|
4627
|
-
case "blockquote":
|
|
4628
|
-
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
4629
|
-
break;
|
|
4630
|
-
case "codeblock":
|
|
4631
|
-
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
4632
|
-
break;
|
|
4633
|
-
case "table":
|
|
4634
|
-
insertTable(view);
|
|
4635
|
-
break;
|
|
4636
|
-
case "link":
|
|
4637
|
-
(action.data === false ? removeLink : addLink)(view);
|
|
4638
|
-
break;
|
|
4639
|
-
case "comment":
|
|
4640
|
-
createComment(view);
|
|
4641
|
-
break;
|
|
4642
|
-
}
|
|
4643
|
-
setTimeout(() => {
|
|
4644
|
-
if (!view.hasFocus) {
|
|
4645
|
-
view.focus();
|
|
4646
|
-
}
|
|
4647
|
-
});
|
|
4648
|
-
};
|
|
4649
|
-
};
|
|
4650
|
-
|
|
4651
|
-
// packages/ui/react-ui-editor/src/hooks/useDocAccessor.ts
|
|
4652
|
-
import { useMemo as useMemo2 } from "react";
|
|
4653
|
-
import { createDocAccessor, getTextContent } from "@dxos/echo-schema";
|
|
4654
|
-
var useDocAccessor = (text) => {
|
|
4655
|
-
return useMemo2(() => ({
|
|
4656
|
-
id: text.id,
|
|
4657
|
-
doc: getTextContent(text),
|
|
4658
|
-
accessor: createDocAccessor(text)
|
|
4659
|
-
}), [
|
|
4660
|
-
text
|
|
4661
|
-
]);
|
|
4662
|
-
};
|
|
4663
|
-
|
|
4664
|
-
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4665
|
-
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4666
|
-
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
4667
|
-
import { useEffect as useEffect3, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
|
|
4668
|
-
import { log as log10 } from "@dxos/log";
|
|
4669
|
-
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
4670
|
-
var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4671
|
-
var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
4672
|
-
let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo3(cb, deps ?? []);
|
|
4673
|
-
const onUpdate = useRef3();
|
|
4674
|
-
const [view, setView] = useState4();
|
|
4675
|
-
const parentRef = useRef3(null);
|
|
4676
|
-
useEffect3(() => {
|
|
4677
|
-
let view2;
|
|
4678
|
-
if (parentRef.current) {
|
|
4679
|
-
const state = EditorState3.create({
|
|
4680
|
-
doc,
|
|
4681
|
-
selection,
|
|
4682
|
-
extensions: [
|
|
4683
|
-
id && documentId2.of(id),
|
|
4684
|
-
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4685
|
-
EditorView17.exceptionSink.of((err) => {
|
|
4686
|
-
log10.catch(err, void 0, {
|
|
4687
|
-
F: __dxlog_file12,
|
|
4688
|
-
L: 44,
|
|
4689
|
-
S: void 0,
|
|
4690
|
-
C: (f, a) => f(...a)
|
|
4691
|
-
});
|
|
4692
|
-
}),
|
|
4693
|
-
extensions,
|
|
4694
|
-
EditorView17.updateListener.of(() => {
|
|
4695
|
-
onUpdate.current?.();
|
|
4696
|
-
})
|
|
4697
|
-
].filter(isNotFalsy4)
|
|
4698
|
-
});
|
|
4699
|
-
view2 = new EditorView17({
|
|
4700
|
-
parent: parentRef.current,
|
|
4701
|
-
scrollTo,
|
|
4702
|
-
state,
|
|
4703
|
-
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4704
|
-
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4705
|
-
dispatchTransactions: (trs, view3) => {
|
|
4706
|
-
if (debug) {
|
|
4707
|
-
logChanges(trs);
|
|
4708
|
-
}
|
|
4709
|
-
view3.update(trs);
|
|
4710
|
-
}
|
|
4711
|
-
});
|
|
4712
|
-
setView(view2);
|
|
4713
|
-
}
|
|
4714
|
-
return () => {
|
|
4715
|
-
view2?.destroy();
|
|
4716
|
-
};
|
|
4717
|
-
}, deps);
|
|
4718
|
-
useEffect3(() => {
|
|
4719
|
-
if (view) {
|
|
4720
|
-
if (!selection && !view.state.selection.main.anchor) {
|
|
4721
|
-
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4722
|
-
}
|
|
4723
|
-
if (selection || scrollTo) {
|
|
4724
|
-
onUpdate.current = () => {
|
|
4725
|
-
onUpdate.current = void 0;
|
|
4726
|
-
view.dispatch({
|
|
4727
|
-
selection,
|
|
4728
|
-
effects: scrollTo && [
|
|
4729
|
-
scrollTo
|
|
4730
|
-
],
|
|
4731
|
-
scrollIntoView: !scrollTo
|
|
4732
|
-
});
|
|
4733
|
-
};
|
|
4734
|
-
}
|
|
4735
|
-
if (autoFocus) {
|
|
4736
|
-
view.focus();
|
|
4737
|
-
}
|
|
4738
|
-
}
|
|
4739
|
-
}, [
|
|
4740
|
-
view,
|
|
4741
|
-
autoFocus,
|
|
4742
|
-
selection,
|
|
4743
|
-
scrollTo
|
|
4744
|
-
]);
|
|
4745
|
-
return {
|
|
4746
|
-
parentRef,
|
|
4747
|
-
view
|
|
4748
|
-
};
|
|
4749
|
-
};
|
|
4750
4901
|
export {
|
|
4902
|
+
BaseTextEditor,
|
|
4751
4903
|
Cursor,
|
|
4752
4904
|
Doc,
|
|
4753
4905
|
EditorModes,
|
|
4754
4906
|
Inline,
|
|
4755
4907
|
List,
|
|
4908
|
+
MarkdownEditor,
|
|
4756
4909
|
RemoteSelectionsDecorator,
|
|
4757
4910
|
SpaceAwarenessProvider,
|
|
4758
4911
|
TextEditor,
|
|
@@ -4772,26 +4925,29 @@ export {
|
|
|
4772
4925
|
awarenessProvider,
|
|
4773
4926
|
blast,
|
|
4774
4927
|
callbackWrapper,
|
|
4928
|
+
codeTheme,
|
|
4775
4929
|
command,
|
|
4776
4930
|
comments,
|
|
4777
4931
|
compareFormatting,
|
|
4778
4932
|
createBasicExtensions,
|
|
4779
4933
|
createComment,
|
|
4780
|
-
createDataExtensions,
|
|
4781
4934
|
createMarkdownExtensions,
|
|
4782
4935
|
createThemeExtensions,
|
|
4783
4936
|
cursorLineMargin,
|
|
4937
|
+
cursorLineMarginFacet,
|
|
4784
4938
|
decorateMarkdown,
|
|
4939
|
+
defaultMarkdownSlots,
|
|
4785
4940
|
defaultOptions,
|
|
4941
|
+
defaultSlots,
|
|
4942
|
+
defaultTextSlots,
|
|
4786
4943
|
defaultTheme,
|
|
4787
4944
|
dnd,
|
|
4788
|
-
documentId2 as documentId,
|
|
4789
4945
|
editorFillLayoutEditor,
|
|
4790
4946
|
editorFillLayoutRoot,
|
|
4791
4947
|
editorMode,
|
|
4792
4948
|
editorWithToolbarLayout,
|
|
4793
4949
|
focusComment,
|
|
4794
|
-
|
|
4950
|
+
formatting,
|
|
4795
4951
|
getFormatting,
|
|
4796
4952
|
getToken,
|
|
4797
4953
|
image,
|
|
@@ -4803,7 +4959,9 @@ export {
|
|
|
4803
4959
|
markdownHighlightStyle,
|
|
4804
4960
|
markdownTags,
|
|
4805
4961
|
markdownTagsExtensions,
|
|
4962
|
+
markdownTheme,
|
|
4806
4963
|
mention,
|
|
4964
|
+
outliner,
|
|
4807
4965
|
removeBlockquote,
|
|
4808
4966
|
removeCodeblock,
|
|
4809
4967
|
removeLink,
|
|
@@ -4816,6 +4974,7 @@ export {
|
|
|
4816
4974
|
setStyle,
|
|
4817
4975
|
table,
|
|
4818
4976
|
tags2 as tags,
|
|
4977
|
+
textTheme,
|
|
4819
4978
|
toggleBlockquote,
|
|
4820
4979
|
toggleCodeblock,
|
|
4821
4980
|
toggleEmphasis,
|
|
@@ -4828,9 +4987,12 @@ export {
|
|
|
4828
4987
|
typewriter,
|
|
4829
4988
|
useActionHandler,
|
|
4830
4989
|
useComments,
|
|
4831
|
-
|
|
4990
|
+
useEditorView,
|
|
4832
4991
|
useFormattingState,
|
|
4992
|
+
useInMemoryTextModel,
|
|
4833
4993
|
useTextEditor,
|
|
4994
|
+
useTextExtensions,
|
|
4995
|
+
useTextModel,
|
|
4834
4996
|
useToolbarContext
|
|
4835
4997
|
};
|
|
4836
4998
|
//# sourceMappingURL=index.mjs.map
|