@dxos/react-ui-editor 0.4.7-main.69f352e → 0.4.7-main.6a8321e
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 +530 -528
- 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 +3 -0
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +0 -9
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/index.d.ts +0 -2
- package/dist/types/src/components/TextEditor/index.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/{components/TextEditor → extensions/automerge}/automerge.stories.d.ts +4 -2
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -0
- package/dist/types/src/extensions/command/command.d.ts.map +1 -1
- package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
- package/dist/types/src/extensions/command/state.d.ts +1 -1
- package/dist/types/src/extensions/command/state.d.ts.map +1 -1
- package/dist/types/src/extensions/cursor-line-margin.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +0 -1
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts +1 -1
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +2 -2
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts +3 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/hooks/defs.d.ts +5 -11
- package/dist/types/src/hooks/defs.d.ts.map +1 -1
- package/dist/types/src/hooks/useEditorView.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +20 -5
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/{components/TextEditor/hooks.stories.d.ts → hooks/useTextEditor.stories.d.ts} +1 -3
- package/dist/types/src/hooks/useTextEditor.stories.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/package.json +24 -24
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +25 -6
- package/src/components/TextEditor/TextEditor.stories.tsx +0 -15
- package/src/components/TextEditor/TextEditor.tsx +11 -6
- package/src/components/TextEditor/index.ts +0 -3
- package/src/components/Toolbar/Toolbar.stories.tsx +2 -1
- package/src/{components/TextEditor → extensions/automerge}/automerge.stories.tsx +32 -37
- package/src/extensions/command/command.ts +4 -7
- package/src/extensions/command/hint.ts +1 -0
- package/src/extensions/command/state.ts +2 -2
- package/src/extensions/cursor-line-margin.ts +2 -1
- package/src/extensions/index.ts +0 -1
- package/src/extensions/listener.ts +3 -3
- package/src/extensions/markdown/bundle.ts +4 -14
- package/src/extensions/markdown/decorate.ts +19 -12
- package/src/hooks/defs.ts +6 -20
- package/src/hooks/useActionHandler.ts +11 -11
- package/src/hooks/useEditorView.ts +0 -1
- package/src/{components/TextEditor/hooks.stories.tsx → hooks/useTextEditor.stories.tsx} +8 -8
- package/src/hooks/useTextEditor.ts +69 -14
- package/src/hooks/useTextModel.ts +6 -13
- package/src/index.ts +2 -0
- package/src/themes/default.ts +1 -0
- package/dist/types/src/components/TextEditor/automerge.stories.d.ts.map +0 -1
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +0 -1
- package/dist/types/src/extensions/basic.d.ts +0 -9
- package/dist/types/src/extensions/basic.d.ts.map +0 -1
- package/src/extensions/basic.ts +0 -41
|
@@ -24,19 +24,18 @@ var translations_default = [
|
|
|
24
24
|
|
|
25
25
|
// packages/ui/react-ui-editor/src/index.ts
|
|
26
26
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
27
|
+
import { tags as tags2 } from "@lezer/highlight";
|
|
27
28
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
28
29
|
import { Doc, YText, YXmlFragment } from "@dxos/text-model";
|
|
29
30
|
|
|
30
|
-
// packages/ui/react-ui-editor/src/components/TextEditor/index.ts
|
|
31
|
-
import { tags as tags2 } from "@lezer/highlight";
|
|
32
|
-
|
|
33
31
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
34
|
-
import { EditorState as
|
|
35
|
-
import { EditorView as EditorView17, scrollPastEnd } from "@codemirror/view";
|
|
32
|
+
import { EditorState as EditorState3 } from "@codemirror/state";
|
|
33
|
+
import { EditorView as EditorView17, scrollPastEnd as scrollPastEnd2 } from "@codemirror/view";
|
|
36
34
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
37
|
-
import
|
|
38
|
-
import React, { forwardRef, useCallback, useEffect as
|
|
39
|
-
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";
|
|
38
|
+
import { log as log5 } from "@dxos/log";
|
|
40
39
|
import { useThemeContext } from "@dxos/react-ui";
|
|
41
40
|
import { focusRing } from "@dxos/react-ui-theme";
|
|
42
41
|
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
@@ -733,28 +732,8 @@ var styles2 = EditorView3.baseTheme({
|
|
|
733
732
|
}
|
|
734
733
|
});
|
|
735
734
|
|
|
736
|
-
// packages/ui/react-ui-editor/src/extensions/basic.ts
|
|
737
|
-
import { closeBrackets } from "@codemirror/autocomplete";
|
|
738
|
-
import { history } from "@codemirror/commands";
|
|
739
|
-
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
740
|
-
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
741
|
-
import { drawSelection, EditorView as EditorView4, highlightActiveLine, placeholder } from "@codemirror/view";
|
|
742
|
-
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
743
|
-
var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true, bracketMatching: _bracketMatching = true } = {}) => [
|
|
744
|
-
lineWrapping && EditorView4.lineWrapping,
|
|
745
|
-
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
746
|
-
_bracketMatching && bracketMatching(),
|
|
747
|
-
closeBrackets(),
|
|
748
|
-
drawSelection(),
|
|
749
|
-
highlightActiveLine(),
|
|
750
|
-
history(),
|
|
751
|
-
_placeholder && placeholder(_placeholder),
|
|
752
|
-
// https://github.com/codemirror/theme-one-dark
|
|
753
|
-
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
|
|
754
|
-
].filter(isNotFalsy2);
|
|
755
|
-
|
|
756
735
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
|
757
|
-
import { EditorView as
|
|
736
|
+
import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
|
|
758
737
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
759
738
|
import { invariant } from "@dxos/invariant";
|
|
760
739
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
|
@@ -802,7 +781,7 @@ var blast = (options = defaultOptions) => {
|
|
|
802
781
|
};
|
|
803
782
|
return [
|
|
804
783
|
// Cursor moved.
|
|
805
|
-
|
|
784
|
+
EditorView4.updateListener.of((update2) => {
|
|
806
785
|
if (blaster?.node !== update2.view.scrollDOM) {
|
|
807
786
|
if (blaster) {
|
|
808
787
|
blaster.destroy();
|
|
@@ -1064,11 +1043,11 @@ var random = (min, max) => {
|
|
|
1064
1043
|
};
|
|
1065
1044
|
|
|
1066
1045
|
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
|
1067
|
-
import { EditorView as
|
|
1046
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
|
1068
1047
|
|
|
1069
1048
|
// packages/ui/react-ui-editor/src/extensions/command/hint.ts
|
|
1070
1049
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
1071
|
-
import { Decoration as Decoration3, EditorView as
|
|
1050
|
+
import { Decoration as Decoration3, EditorView as EditorView5, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
1072
1051
|
|
|
1073
1052
|
// packages/ui/react-ui-editor/src/extensions/command/state.ts
|
|
1074
1053
|
import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
|
|
@@ -1162,7 +1141,7 @@ var closeCommand = (view) => {
|
|
|
1162
1141
|
}
|
|
1163
1142
|
return false;
|
|
1164
1143
|
};
|
|
1165
|
-
var
|
|
1144
|
+
var commandKeyBindings = [
|
|
1166
1145
|
{
|
|
1167
1146
|
key: "/",
|
|
1168
1147
|
run: openCommand
|
|
@@ -1263,28 +1242,27 @@ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
|
|
|
1263
1242
|
}
|
|
1264
1243
|
}, {
|
|
1265
1244
|
provide: (plugin) => [
|
|
1266
|
-
|
|
1245
|
+
EditorView5.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
|
|
1267
1246
|
]
|
|
1268
1247
|
});
|
|
1269
1248
|
|
|
1270
1249
|
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
|
1271
1250
|
var command = (options) => {
|
|
1272
1251
|
return [
|
|
1252
|
+
commandConfig.of(options),
|
|
1273
1253
|
commandState,
|
|
1274
|
-
keymap3.of(
|
|
1254
|
+
keymap3.of(commandKeyBindings),
|
|
1275
1255
|
hintViewPlugin(options),
|
|
1276
|
-
|
|
1277
|
-
EditorView7.focusChangeEffect.of((_, focusing) => {
|
|
1256
|
+
EditorView6.focusChangeEffect.of((_, focusing) => {
|
|
1278
1257
|
return focusing ? closeEffect.of(null) : null;
|
|
1279
|
-
})
|
|
1280
|
-
commandConfig.of(options)
|
|
1258
|
+
})
|
|
1281
1259
|
];
|
|
1282
1260
|
};
|
|
1283
1261
|
|
|
1284
1262
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1285
1263
|
import { invertedEffects } from "@codemirror/commands";
|
|
1286
1264
|
import { Facet as Facet4, StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
|
|
1287
|
-
import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView as
|
|
1265
|
+
import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView as EditorView7 } from "@codemirror/view";
|
|
1288
1266
|
import sortBy from "lodash.sortby";
|
|
1289
1267
|
import { useEffect } from "react";
|
|
1290
1268
|
import { debounce } from "@dxos/async";
|
|
@@ -1404,7 +1382,7 @@ var commentsState = StateField4.define({
|
|
|
1404
1382
|
return value;
|
|
1405
1383
|
}
|
|
1406
1384
|
});
|
|
1407
|
-
var styles3 =
|
|
1385
|
+
var styles3 = EditorView7.baseTheme({
|
|
1408
1386
|
"&light .cm-comment, &light .cm-comment-current": {
|
|
1409
1387
|
mixBlendMode: "darken"
|
|
1410
1388
|
},
|
|
@@ -1438,7 +1416,7 @@ var commentCurrentMark = Decoration4.mark({
|
|
|
1438
1416
|
"data-testid": "cm-comment"
|
|
1439
1417
|
}
|
|
1440
1418
|
});
|
|
1441
|
-
var commentsDecorations =
|
|
1419
|
+
var commentsDecorations = EditorView7.decorations.compute([
|
|
1442
1420
|
commentsState
|
|
1443
1421
|
], (state) => {
|
|
1444
1422
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
@@ -1476,7 +1454,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1476
1454
|
}
|
|
1477
1455
|
};
|
|
1478
1456
|
return [
|
|
1479
|
-
|
|
1457
|
+
EditorView7.domEventHandlers({
|
|
1480
1458
|
cut: handleTrack,
|
|
1481
1459
|
copy: handleTrack
|
|
1482
1460
|
}),
|
|
@@ -1498,7 +1476,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1498
1476
|
return effects;
|
|
1499
1477
|
}),
|
|
1500
1478
|
// Handle paste or the undo of comment deletion.
|
|
1501
|
-
|
|
1479
|
+
EditorView7.updateListener.of((update2) => {
|
|
1502
1480
|
const restore = [];
|
|
1503
1481
|
for (let i = 0; i < update2.transactions.length; i++) {
|
|
1504
1482
|
const tr = update2.transactions[i];
|
|
@@ -1649,7 +1627,7 @@ var comments = (options = {}) => {
|
|
|
1649
1627
|
//
|
|
1650
1628
|
// Track deleted ranges and update ranges for decorations.
|
|
1651
1629
|
//
|
|
1652
|
-
|
|
1630
|
+
EditorView7.updateListener.of(({ view, state, changes }) => {
|
|
1653
1631
|
let mod = false;
|
|
1654
1632
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
1655
1633
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -1681,7 +1659,7 @@ var comments = (options = {}) => {
|
|
|
1681
1659
|
//
|
|
1682
1660
|
// Track selection/proximity.
|
|
1683
1661
|
//
|
|
1684
|
-
|
|
1662
|
+
EditorView7.updateListener.of(({ view, state }) => {
|
|
1685
1663
|
let min = Infinity;
|
|
1686
1664
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
1687
1665
|
const { head } = state.selection.main;
|
|
@@ -1730,7 +1708,7 @@ var focusComment = (view, id, center = true) => {
|
|
|
1730
1708
|
},
|
|
1731
1709
|
effects: [
|
|
1732
1710
|
//
|
|
1733
|
-
|
|
1711
|
+
EditorView7.scrollIntoView(range.from, center ? {
|
|
1734
1712
|
y: "center"
|
|
1735
1713
|
} : void 0),
|
|
1736
1714
|
setSelection.of({
|
|
@@ -1759,13 +1737,13 @@ var useComments = (view, id, comments2 = []) => {
|
|
|
1759
1737
|
|
|
1760
1738
|
// packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts
|
|
1761
1739
|
import { Facet as Facet5, Transaction } from "@codemirror/state";
|
|
1762
|
-
import { EditorView as
|
|
1740
|
+
import { EditorView as EditorView8 } from "@codemirror/view";
|
|
1763
1741
|
var cursorLineMarginFacet = Facet5.define({
|
|
1764
1742
|
combine: (input) => input[0] ?? 3
|
|
1765
1743
|
});
|
|
1766
1744
|
var annotation = "cursorLineMargin";
|
|
1767
1745
|
var lineAtPos = (s, pos) => s.doc.lineAt(pos).number;
|
|
1768
|
-
var cursorLineMargin =
|
|
1746
|
+
var cursorLineMargin = EditorView8.updateListener.of(({ transactions, state, selectionSet, startState, view }) => {
|
|
1769
1747
|
if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
|
|
1770
1748
|
return;
|
|
1771
1749
|
}
|
|
@@ -1801,7 +1779,7 @@ var cursorLineMargin = EditorView9.updateListener.of(({ transactions, state, sel
|
|
|
1801
1779
|
}
|
|
1802
1780
|
view.dispatch({
|
|
1803
1781
|
annotations: Transaction.userEvent.of(annotation),
|
|
1804
|
-
effects:
|
|
1782
|
+
effects: EditorView8.scrollIntoView(s.selection.main.head, {
|
|
1805
1783
|
y: needsScrollTop ? "start" : "end",
|
|
1806
1784
|
yMargin: view.defaultLineHeight * cursorLineMargin2
|
|
1807
1785
|
})
|
|
@@ -1809,9 +1787,9 @@ var cursorLineMargin = EditorView9.updateListener.of(({ transactions, state, sel
|
|
|
1809
1787
|
});
|
|
1810
1788
|
|
|
1811
1789
|
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
|
1812
|
-
import { EditorView as
|
|
1790
|
+
import { EditorView as EditorView9 } from "@codemirror/view";
|
|
1813
1791
|
var dnd = () => {
|
|
1814
|
-
return
|
|
1792
|
+
return EditorView9.domEventHandlers({
|
|
1815
1793
|
drop: (event, view) => {
|
|
1816
1794
|
console.log(event);
|
|
1817
1795
|
}
|
|
@@ -1819,30 +1797,30 @@ var dnd = () => {
|
|
|
1819
1797
|
};
|
|
1820
1798
|
|
|
1821
1799
|
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
1822
|
-
import { EditorView as
|
|
1800
|
+
import { EditorView as EditorView10 } from "@codemirror/view";
|
|
1823
1801
|
var listener = ({ onFocus, onChange }) => {
|
|
1824
1802
|
const extensions = [];
|
|
1825
|
-
onFocus && extensions.push(
|
|
1826
|
-
onFocus(
|
|
1803
|
+
onFocus && extensions.push(EditorView10.focusChangeEffect.of((_, focusing) => {
|
|
1804
|
+
onFocus(focusing);
|
|
1827
1805
|
return null;
|
|
1828
1806
|
}));
|
|
1829
|
-
onChange && extensions.push(
|
|
1807
|
+
onChange && extensions.push(EditorView10.updateListener.of((update2) => {
|
|
1830
1808
|
onChange(update2.state.doc.toString());
|
|
1831
1809
|
}));
|
|
1832
1810
|
return extensions;
|
|
1833
1811
|
};
|
|
1834
1812
|
|
|
1835
1813
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1836
|
-
import { closeBrackets
|
|
1837
|
-
import { history
|
|
1814
|
+
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1815
|
+
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1838
1816
|
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1839
|
-
import { bracketMatching
|
|
1817
|
+
import { bracketMatching, defaultHighlightStyle, indentOnInput, syntaxHighlighting } from "@codemirror/language";
|
|
1840
1818
|
import { languages } from "@codemirror/language-data";
|
|
1841
1819
|
import { searchKeymap } from "@codemirror/search";
|
|
1842
1820
|
import { EditorState } from "@codemirror/state";
|
|
1843
|
-
import { oneDarkHighlightStyle
|
|
1844
|
-
import {
|
|
1845
|
-
import { isNotFalsy as
|
|
1821
|
+
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
1822
|
+
import { EditorView as EditorView11, drawSelection, dropCursor, keymap as keymap5, placeholder } from "@codemirror/view";
|
|
1823
|
+
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
1846
1824
|
|
|
1847
1825
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1848
1826
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -2035,19 +2013,17 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
2035
2013
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
2036
2014
|
var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
|
|
2037
2015
|
return [
|
|
2038
|
-
|
|
2016
|
+
// TODO(burdon): Reconcile with createBasicExtensions.
|
|
2017
|
+
lineWrapping && EditorView11.lineWrapping,
|
|
2039
2018
|
EditorState.allowMultipleSelections.of(true),
|
|
2040
2019
|
EditorState.tabSize.of(2),
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
closeBrackets2(),
|
|
2044
|
-
crosshairCursor(),
|
|
2020
|
+
bracketMatching(),
|
|
2021
|
+
closeBrackets(),
|
|
2045
2022
|
dropCursor(),
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
history2(),
|
|
2023
|
+
drawSelection(),
|
|
2024
|
+
history(),
|
|
2049
2025
|
indentOnInput(),
|
|
2050
|
-
_placeholder &&
|
|
2026
|
+
_placeholder && placeholder(_placeholder),
|
|
2051
2027
|
// Main extension.
|
|
2052
2028
|
// https://github.com/codemirror/lang-markdown
|
|
2053
2029
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -2067,9 +2043,9 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
2067
2043
|
]
|
|
2068
2044
|
}),
|
|
2069
2045
|
// https://github.com/codemirror/theme-one-dark
|
|
2070
|
-
themeMode === "dark" ?
|
|
2046
|
+
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
|
|
2071
2047
|
// Custom styles.
|
|
2072
|
-
|
|
2048
|
+
syntaxHighlighting(markdownHighlightStyle()),
|
|
2073
2049
|
keymap5.of([
|
|
2074
2050
|
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
2075
2051
|
indentWithTab,
|
|
@@ -2082,13 +2058,13 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
2082
2058
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
2083
2059
|
...standardKeymap
|
|
2084
2060
|
])
|
|
2085
|
-
].filter(
|
|
2061
|
+
].filter(isNotFalsy2);
|
|
2086
2062
|
};
|
|
2087
2063
|
|
|
2088
2064
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
|
2089
2065
|
import { syntaxTree } from "@codemirror/language";
|
|
2090
2066
|
import { RangeSetBuilder as RangeSetBuilder2, StateEffect as StateEffect4 } from "@codemirror/state";
|
|
2091
|
-
import { EditorView as
|
|
2067
|
+
import { EditorView as EditorView12, Decoration as Decoration5, WidgetType as WidgetType3, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
2092
2068
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
2093
2069
|
var HorizontalRuleWidget = class extends WidgetType3 {
|
|
2094
2070
|
toDOM() {
|
|
@@ -2265,45 +2241,46 @@ var decorateMarkdown = (options = {}) => {
|
|
|
2265
2241
|
return [
|
|
2266
2242
|
ViewPlugin4.fromClass(class {
|
|
2267
2243
|
constructor(view) {
|
|
2268
|
-
this.pendingUpdate = -1;
|
|
2269
2244
|
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));
|
|
2270
2245
|
}
|
|
2271
2246
|
update(update2) {
|
|
2272
|
-
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((e) => e.is(forceUpdate)))) {
|
|
2247
|
+
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((e) => e.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
|
|
2273
2248
|
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(update2.view, options, update2.view.hasFocus));
|
|
2274
2249
|
this.clearUpdate();
|
|
2275
2250
|
} else if (update2.selectionSet) {
|
|
2276
2251
|
this.scheduleUpdate(update2.view);
|
|
2277
2252
|
}
|
|
2278
2253
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
window.clearTimeout(this.pendingUpdate);
|
|
2282
|
-
this.pendingUpdate = -1;
|
|
2283
|
-
}
|
|
2284
|
-
}
|
|
2254
|
+
// TODO(burdon): BUG: If the cursor is at the end of a link at the end of a line,
|
|
2255
|
+
// the cursor will float in space or be in the wrong position after the decoration is applied.
|
|
2285
2256
|
scheduleUpdate(view) {
|
|
2286
2257
|
this.clearUpdate();
|
|
2287
|
-
this.pendingUpdate =
|
|
2258
|
+
this.pendingUpdate = setTimeout(() => {
|
|
2288
2259
|
view.dispatch({
|
|
2289
2260
|
effects: forceUpdate.of(null)
|
|
2290
2261
|
});
|
|
2291
|
-
}, options.selectionChangeDelay
|
|
2262
|
+
}, options.selectionChangeDelay);
|
|
2263
|
+
}
|
|
2264
|
+
clearUpdate() {
|
|
2265
|
+
if (this.pendingUpdate) {
|
|
2266
|
+
clearTimeout(this.pendingUpdate);
|
|
2267
|
+
this.pendingUpdate = void 0;
|
|
2268
|
+
}
|
|
2292
2269
|
}
|
|
2293
2270
|
destroy() {
|
|
2294
2271
|
this.clearUpdate();
|
|
2295
2272
|
}
|
|
2296
2273
|
}, {
|
|
2297
2274
|
provide: (plugin) => [
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2275
|
+
EditorView12.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
2276
|
+
EditorView12.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
2277
|
+
EditorView12.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration5.none)
|
|
2301
2278
|
]
|
|
2302
2279
|
}),
|
|
2303
2280
|
formattingStyles
|
|
2304
2281
|
];
|
|
2305
2282
|
};
|
|
2306
|
-
var formattingStyles =
|
|
2283
|
+
var formattingStyles = EditorView12.baseTheme({
|
|
2307
2284
|
"& .cm-code": {
|
|
2308
2285
|
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
2309
2286
|
},
|
|
@@ -2356,7 +2333,7 @@ var formattingStyles = EditorView13.baseTheme({
|
|
|
2356
2333
|
import { snippet } from "@codemirror/autocomplete";
|
|
2357
2334
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2358
2335
|
import { EditorSelection } from "@codemirror/state";
|
|
2359
|
-
import { EditorView as
|
|
2336
|
+
import { EditorView as EditorView13, keymap as keymap6 } from "@codemirror/view";
|
|
2360
2337
|
import { useState, useMemo } from "react";
|
|
2361
2338
|
var compareFormatting = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
|
|
2362
2339
|
var Inline;
|
|
@@ -3426,7 +3403,7 @@ var getFormatting = (state) => {
|
|
|
3426
3403
|
};
|
|
3427
3404
|
var useFormattingState = () => {
|
|
3428
3405
|
const [state, setState] = useState(null);
|
|
3429
|
-
const observer = useMemo(() =>
|
|
3406
|
+
const observer = useMemo(() => EditorView13.updateListener.of((update2) => {
|
|
3430
3407
|
if (update2.docChanged || update2.selectionSet) {
|
|
3431
3408
|
const newState = getFormatting(update2.state);
|
|
3432
3409
|
if (!state || !compareFormatting(state, newState)) {
|
|
@@ -3443,7 +3420,7 @@ var useFormattingState = () => {
|
|
|
3443
3420
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
3444
3421
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3445
3422
|
import { StateField as StateField5 } from "@codemirror/state";
|
|
3446
|
-
import { Decoration as Decoration6, EditorView as
|
|
3423
|
+
import { Decoration as Decoration6, EditorView as EditorView14, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3447
3424
|
var image = (options = {}) => {
|
|
3448
3425
|
return StateField5.define({
|
|
3449
3426
|
create: (state) => {
|
|
@@ -3470,7 +3447,7 @@ var image = (options = {}) => {
|
|
|
3470
3447
|
add: buildDecorations2(from, to, tr.state)
|
|
3471
3448
|
});
|
|
3472
3449
|
},
|
|
3473
|
-
provide: (field) =>
|
|
3450
|
+
provide: (field) => EditorView14.decorations.from(field)
|
|
3474
3451
|
});
|
|
3475
3452
|
};
|
|
3476
3453
|
var preloaded = /* @__PURE__ */ new Set();
|
|
@@ -3558,12 +3535,12 @@ var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
|
|
|
3558
3535
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
3559
3536
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
3560
3537
|
import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField6 } from "@codemirror/state";
|
|
3561
|
-
import { Decoration as Decoration7, EditorView as
|
|
3538
|
+
import { Decoration as Decoration7, EditorView as EditorView15, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
3562
3539
|
var table = (options = {}) => {
|
|
3563
3540
|
return StateField6.define({
|
|
3564
3541
|
create: (state) => update(state, options),
|
|
3565
3542
|
update: (_, tr) => update(tr.state, options),
|
|
3566
|
-
provide: (field) =>
|
|
3543
|
+
provide: (field) => EditorView15.decorations.from(field)
|
|
3567
3544
|
});
|
|
3568
3545
|
};
|
|
3569
3546
|
var update = (state, options) => {
|
|
@@ -3773,6 +3750,189 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
3773
3750
|
];
|
|
3774
3751
|
};
|
|
3775
3752
|
|
|
3753
|
+
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
3754
|
+
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
3755
|
+
import { Context as Context2 } from "@dxos/context";
|
|
3756
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
3757
|
+
import { log as log3 } from "@dxos/log";
|
|
3758
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
3759
|
+
var DEBOUNCE_INTERVAL = 100;
|
|
3760
|
+
var SpaceAwarenessProvider = class {
|
|
3761
|
+
constructor(params) {
|
|
3762
|
+
this._remoteStates = /* @__PURE__ */ new Map();
|
|
3763
|
+
this.remoteStateChange = new Event2();
|
|
3764
|
+
this._space = params.space;
|
|
3765
|
+
this._channel = params.channel;
|
|
3766
|
+
this._peerId = params.peerId;
|
|
3767
|
+
this._info = params.info;
|
|
3768
|
+
}
|
|
3769
|
+
open() {
|
|
3770
|
+
this._ctx = new Context2();
|
|
3771
|
+
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
3772
|
+
if (this._localState) {
|
|
3773
|
+
await this._space.postMessage(this._channel, {
|
|
3774
|
+
kind: "post",
|
|
3775
|
+
state: this._localState
|
|
3776
|
+
});
|
|
3777
|
+
await sleep(DEBOUNCE_INTERVAL);
|
|
3778
|
+
}
|
|
3779
|
+
});
|
|
3780
|
+
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
3781
|
+
switch (message.payload.kind) {
|
|
3782
|
+
case "query": {
|
|
3783
|
+
this._handleQueryMessage();
|
|
3784
|
+
break;
|
|
3785
|
+
}
|
|
3786
|
+
case "post": {
|
|
3787
|
+
this._handlePostMessage(message.payload);
|
|
3788
|
+
break;
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
}));
|
|
3792
|
+
void this._space.postMessage(this._channel, {
|
|
3793
|
+
kind: "query"
|
|
3794
|
+
}).catch((err) => {
|
|
3795
|
+
log3.debug("failed to query awareness", {
|
|
3796
|
+
err
|
|
3797
|
+
}, {
|
|
3798
|
+
F: __dxlog_file4,
|
|
3799
|
+
L: 89,
|
|
3800
|
+
S: this,
|
|
3801
|
+
C: (f, a) => f(...a)
|
|
3802
|
+
});
|
|
3803
|
+
});
|
|
3804
|
+
}
|
|
3805
|
+
close() {
|
|
3806
|
+
void this._ctx?.dispose();
|
|
3807
|
+
this._ctx = void 0;
|
|
3808
|
+
this._postTask = void 0;
|
|
3809
|
+
}
|
|
3810
|
+
getRemoteStates() {
|
|
3811
|
+
return Array.from(this._remoteStates.values());
|
|
3812
|
+
}
|
|
3813
|
+
update(position) {
|
|
3814
|
+
invariant2(this._postTask, void 0, {
|
|
3815
|
+
F: __dxlog_file4,
|
|
3816
|
+
L: 104,
|
|
3817
|
+
S: this,
|
|
3818
|
+
A: [
|
|
3819
|
+
"this._postTask",
|
|
3820
|
+
""
|
|
3821
|
+
]
|
|
3822
|
+
});
|
|
3823
|
+
this._localState = {
|
|
3824
|
+
peerId: this._peerId,
|
|
3825
|
+
position,
|
|
3826
|
+
info: this._info
|
|
3827
|
+
};
|
|
3828
|
+
this._postTask.schedule();
|
|
3829
|
+
}
|
|
3830
|
+
_handleQueryMessage() {
|
|
3831
|
+
invariant2(this._postTask, void 0, {
|
|
3832
|
+
F: __dxlog_file4,
|
|
3833
|
+
L: 115,
|
|
3834
|
+
S: this,
|
|
3835
|
+
A: [
|
|
3836
|
+
"this._postTask",
|
|
3837
|
+
""
|
|
3838
|
+
]
|
|
3839
|
+
});
|
|
3840
|
+
this._postTask.schedule();
|
|
3841
|
+
}
|
|
3842
|
+
_handlePostMessage(message) {
|
|
3843
|
+
invariant2(message.kind === "post", void 0, {
|
|
3844
|
+
F: __dxlog_file4,
|
|
3845
|
+
L: 120,
|
|
3846
|
+
S: this,
|
|
3847
|
+
A: [
|
|
3848
|
+
"message.kind === 'post'",
|
|
3849
|
+
""
|
|
3850
|
+
]
|
|
3851
|
+
});
|
|
3852
|
+
this._remoteStates.set(message.state.peerId, message.state);
|
|
3853
|
+
this.remoteStateChange.emit();
|
|
3854
|
+
}
|
|
3855
|
+
};
|
|
3856
|
+
|
|
3857
|
+
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
3858
|
+
var useActionHandler = (view) => {
|
|
3859
|
+
return (action) => {
|
|
3860
|
+
if (!view) {
|
|
3861
|
+
return;
|
|
3862
|
+
}
|
|
3863
|
+
let inlineType, listType;
|
|
3864
|
+
switch (action.type) {
|
|
3865
|
+
case "heading":
|
|
3866
|
+
setHeading(parseInt(action.data))(view);
|
|
3867
|
+
break;
|
|
3868
|
+
case "strong":
|
|
3869
|
+
case "emphasis":
|
|
3870
|
+
case "strikethrough":
|
|
3871
|
+
case "code":
|
|
3872
|
+
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
3873
|
+
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
3874
|
+
break;
|
|
3875
|
+
case "list-ordered":
|
|
3876
|
+
case "list-bullet":
|
|
3877
|
+
case "list-task":
|
|
3878
|
+
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
3879
|
+
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
3880
|
+
break;
|
|
3881
|
+
case "blockquote":
|
|
3882
|
+
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
3883
|
+
break;
|
|
3884
|
+
case "codeblock":
|
|
3885
|
+
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
3886
|
+
break;
|
|
3887
|
+
case "table":
|
|
3888
|
+
insertTable(view);
|
|
3889
|
+
break;
|
|
3890
|
+
case "link":
|
|
3891
|
+
(action.data === false ? removeLink : addLink)(view);
|
|
3892
|
+
break;
|
|
3893
|
+
case "comment":
|
|
3894
|
+
createComment(view);
|
|
3895
|
+
break;
|
|
3896
|
+
}
|
|
3897
|
+
setTimeout(() => {
|
|
3898
|
+
if (!view.hasFocus) {
|
|
3899
|
+
view.focus();
|
|
3900
|
+
}
|
|
3901
|
+
});
|
|
3902
|
+
};
|
|
3903
|
+
};
|
|
3904
|
+
|
|
3905
|
+
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
3906
|
+
import { useRef, useState as useState2 } from "react";
|
|
3907
|
+
var useEditorView = (id) => {
|
|
3908
|
+
const editorRef = useRef(null);
|
|
3909
|
+
const [prev, setPrev] = useState2([
|
|
3910
|
+
null,
|
|
3911
|
+
""
|
|
3912
|
+
]);
|
|
3913
|
+
if (prev[0] !== editorRef.current) {
|
|
3914
|
+
setPrev([
|
|
3915
|
+
editorRef.current,
|
|
3916
|
+
id
|
|
3917
|
+
]);
|
|
3918
|
+
}
|
|
3919
|
+
return [
|
|
3920
|
+
editorRef,
|
|
3921
|
+
prev[1] !== id
|
|
3922
|
+
];
|
|
3923
|
+
};
|
|
3924
|
+
|
|
3925
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
3926
|
+
import { closeBrackets as closeBrackets2 } from "@codemirror/autocomplete";
|
|
3927
|
+
import { history as history2 } from "@codemirror/commands";
|
|
3928
|
+
import { bracketMatching as bracketMatching2 } from "@codemirror/language";
|
|
3929
|
+
import { EditorSelection as EditorSelection2, EditorState as EditorState2 } from "@codemirror/state";
|
|
3930
|
+
import { crosshairCursor, drawSelection as drawSelection2, dropCursor as dropCursor2, EditorView as EditorView16, highlightActiveLine, lineNumbers, placeholder as placeholder2, scrollPastEnd } from "@codemirror/view";
|
|
3931
|
+
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
3932
|
+
import { useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
|
|
3933
|
+
import { log as log4 } from "@dxos/log";
|
|
3934
|
+
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
3935
|
+
|
|
3776
3936
|
// packages/ui/react-ui-editor/src/themes/default.ts
|
|
3777
3937
|
import get4 from "lodash.get";
|
|
3778
3938
|
var defaultTheme = {
|
|
@@ -3894,7 +4054,8 @@ var defaultTheme = {
|
|
|
3894
4054
|
// tooltip
|
|
3895
4055
|
//
|
|
3896
4056
|
".cm-tooltip": {
|
|
3897
|
-
border: "none"
|
|
4057
|
+
border: "none",
|
|
4058
|
+
background: "unset"
|
|
3898
4059
|
},
|
|
3899
4060
|
".cm-tooltip-below": {},
|
|
3900
4061
|
//
|
|
@@ -4023,45 +4184,264 @@ var codeTheme = {
|
|
|
4023
4184
|
}
|
|
4024
4185
|
};
|
|
4025
4186
|
|
|
4026
|
-
// packages/ui/react-ui-editor/src/
|
|
4027
|
-
var
|
|
4028
|
-
var
|
|
4029
|
-
const
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
const { themeMode } = useThemeContext();
|
|
4033
|
-
const rootRef = useRef(null);
|
|
4034
|
-
const [view, setView] = useState2(null);
|
|
4035
|
-
useImperativeHandle(forwardedRef, () => view, [
|
|
4036
|
-
view
|
|
4037
|
-
]);
|
|
4187
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4188
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4189
|
+
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}, deps = []) => {
|
|
4190
|
+
const onUpdate = useRef2();
|
|
4191
|
+
const [view, setView] = useState3();
|
|
4192
|
+
const parentRef = useRef2(null);
|
|
4038
4193
|
useEffect2(() => {
|
|
4039
|
-
|
|
4040
|
-
|
|
4194
|
+
let view2;
|
|
4195
|
+
if (parentRef.current) {
|
|
4196
|
+
const state = EditorState2.create({
|
|
4197
|
+
doc,
|
|
4198
|
+
selection,
|
|
4199
|
+
extensions: [
|
|
4200
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4201
|
+
EditorView16.exceptionSink.of((err) => {
|
|
4202
|
+
log4.catch(err, void 0, {
|
|
4203
|
+
F: __dxlog_file5,
|
|
4204
|
+
L: 70,
|
|
4205
|
+
S: void 0,
|
|
4206
|
+
C: (f, a) => f(...a)
|
|
4207
|
+
});
|
|
4208
|
+
}),
|
|
4209
|
+
extensions,
|
|
4210
|
+
EditorView16.updateListener.of(() => {
|
|
4211
|
+
onUpdate.current?.();
|
|
4212
|
+
})
|
|
4213
|
+
].filter(isNotFalsy3)
|
|
4214
|
+
});
|
|
4215
|
+
view2 = new EditorView16({
|
|
4216
|
+
parent: parentRef.current,
|
|
4217
|
+
scrollTo,
|
|
4218
|
+
state,
|
|
4219
|
+
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4220
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4221
|
+
dispatchTransactions: (trs, view3) => {
|
|
4222
|
+
if (debug) {
|
|
4223
|
+
logChanges(trs);
|
|
4224
|
+
}
|
|
4225
|
+
view3.update(trs);
|
|
4226
|
+
}
|
|
4227
|
+
});
|
|
4228
|
+
setView(view2);
|
|
4041
4229
|
}
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4230
|
+
return () => {
|
|
4231
|
+
view2?.destroy();
|
|
4232
|
+
};
|
|
4233
|
+
}, deps);
|
|
4046
4234
|
useEffect2(() => {
|
|
4047
|
-
if (
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4235
|
+
if (view) {
|
|
4236
|
+
if (!selection && !view.state.selection.main.anchor) {
|
|
4237
|
+
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4238
|
+
}
|
|
4239
|
+
if (selection || scrollTo) {
|
|
4240
|
+
onUpdate.current = () => {
|
|
4241
|
+
onUpdate.current = void 0;
|
|
4242
|
+
view.dispatch({
|
|
4243
|
+
selection,
|
|
4244
|
+
effects: scrollTo && [
|
|
4245
|
+
scrollTo
|
|
4246
|
+
],
|
|
4247
|
+
scrollIntoView: !scrollTo
|
|
4248
|
+
});
|
|
4249
|
+
};
|
|
4250
|
+
}
|
|
4251
|
+
if (autoFocus) {
|
|
4252
|
+
view.focus();
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4255
|
+
}, [
|
|
4256
|
+
view,
|
|
4257
|
+
autoFocus,
|
|
4258
|
+
selection,
|
|
4259
|
+
scrollTo
|
|
4260
|
+
]);
|
|
4261
|
+
return {
|
|
4262
|
+
parentRef,
|
|
4263
|
+
view
|
|
4264
|
+
};
|
|
4265
|
+
};
|
|
4266
|
+
var defaults = {
|
|
4267
|
+
bracketMatching: true,
|
|
4268
|
+
closeBrackets: true,
|
|
4269
|
+
drawSelection: true,
|
|
4270
|
+
editable: true,
|
|
4271
|
+
history: true,
|
|
4272
|
+
lineWrapping: true
|
|
4273
|
+
};
|
|
4274
|
+
var createBasicExtensions = (_props) => {
|
|
4275
|
+
const props = defaultsDeep2({}, _props, defaults);
|
|
4276
|
+
return [
|
|
4277
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4278
|
+
EditorView16.exceptionSink.of((err) => {
|
|
4279
|
+
log4.catch(err, void 0, {
|
|
4280
|
+
F: __dxlog_file5,
|
|
4281
|
+
L: 167,
|
|
4282
|
+
S: void 0,
|
|
4283
|
+
C: (f, a) => f(...a)
|
|
4284
|
+
});
|
|
4285
|
+
}),
|
|
4286
|
+
props.allowMultipleSelections && EditorState2.allowMultipleSelections.of(true),
|
|
4287
|
+
props.bracketMatching && bracketMatching2(),
|
|
4288
|
+
props.closeBrackets && closeBrackets2(),
|
|
4289
|
+
props.crosshairCursor && crosshairCursor(),
|
|
4290
|
+
props.dropCursor && dropCursor2(),
|
|
4291
|
+
props.drawSelection && drawSelection2(),
|
|
4292
|
+
props.highlightActiveLine && highlightActiveLine(),
|
|
4293
|
+
props.history && history2(),
|
|
4294
|
+
props.lineNumbers && lineNumbers(),
|
|
4295
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
4296
|
+
props.placeholder && placeholder2(props.placeholder),
|
|
4297
|
+
props.readonly && [
|
|
4298
|
+
EditorState2.readOnly.of(true),
|
|
4299
|
+
EditorView16.editable.of(false)
|
|
4300
|
+
],
|
|
4301
|
+
props.scrollPastEnd && scrollPastEnd(),
|
|
4302
|
+
props.tabSize && EditorState2.tabSize.of(props.tabSize)
|
|
4303
|
+
].filter(isNotFalsy3);
|
|
4304
|
+
};
|
|
4305
|
+
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4306
|
+
return [
|
|
4307
|
+
EditorView16.baseTheme(defaultTheme),
|
|
4308
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
4309
|
+
theme && EditorView16.theme(theme),
|
|
4310
|
+
slots?.editor?.className && EditorView16.editorAttributes.of({
|
|
4311
|
+
class: slots.editor.className
|
|
4312
|
+
}),
|
|
4313
|
+
slots?.content?.className && EditorView16.contentAttributes.of({
|
|
4314
|
+
class: slots.content.className
|
|
4315
|
+
})
|
|
4316
|
+
].filter(isNotFalsy3);
|
|
4317
|
+
};
|
|
4318
|
+
|
|
4319
|
+
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
4320
|
+
import get5 from "lodash.get";
|
|
4321
|
+
import { useState as useState4, useMemo as useMemo2 } from "react";
|
|
4322
|
+
import { generateName } from "@dxos/display-name";
|
|
4323
|
+
import { getRawDoc } from "@dxos/echo-schema";
|
|
4324
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
4325
|
+
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
4326
|
+
import { hueTokens } from "@dxos/react-ui-theme";
|
|
4327
|
+
import { hexToHue } from "@dxos/util";
|
|
4328
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
4329
|
+
var useTextExtensions = ({ id, text, space, identity }) => {
|
|
4330
|
+
const extensions = [
|
|
4331
|
+
automerge(text)
|
|
4332
|
+
];
|
|
4333
|
+
const peerId = identity?.identityKey.toHex();
|
|
4334
|
+
const { cursorLightValue, cursorDarkValue } = hueTokens[hexToHue(peerId ?? "0")];
|
|
4335
|
+
if (space && identity) {
|
|
4336
|
+
const awarenessProvider2 = new SpaceAwarenessProvider({
|
|
4337
|
+
space,
|
|
4338
|
+
channel: `awareness.${id}`,
|
|
4339
|
+
peerId: identity.identityKey.toHex(),
|
|
4340
|
+
info: {
|
|
4341
|
+
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
4342
|
+
color: cursorDarkValue,
|
|
4343
|
+
lightColor: cursorLightValue
|
|
4344
|
+
}
|
|
4345
|
+
});
|
|
4346
|
+
extensions.push(awareness(awarenessProvider2));
|
|
4347
|
+
}
|
|
4348
|
+
return extensions;
|
|
4349
|
+
};
|
|
4350
|
+
var useTextModel = (props) => useMemo2(() => createModel(props), Object.values(props));
|
|
4351
|
+
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4352
|
+
const [content, setContent] = useState4(defaultContent ?? "");
|
|
4353
|
+
return {
|
|
4354
|
+
id,
|
|
4355
|
+
content,
|
|
4356
|
+
text: () => content,
|
|
4357
|
+
setContent
|
|
4358
|
+
};
|
|
4359
|
+
};
|
|
4360
|
+
var createModel = ({ space, identity, text }) => {
|
|
4361
|
+
if (!text) {
|
|
4362
|
+
return void 0;
|
|
4363
|
+
}
|
|
4364
|
+
invariant3(isAutomergeObject(text), void 0, {
|
|
4365
|
+
F: __dxlog_file6,
|
|
4366
|
+
L: 88,
|
|
4367
|
+
S: void 0,
|
|
4368
|
+
A: [
|
|
4369
|
+
"isAutomergeObject(text)",
|
|
4370
|
+
""
|
|
4371
|
+
]
|
|
4372
|
+
});
|
|
4373
|
+
const obj = text;
|
|
4374
|
+
const doc = getRawDoc(obj, [
|
|
4375
|
+
obj.field
|
|
4376
|
+
]);
|
|
4377
|
+
const peerId = identity?.identityKey.toHex();
|
|
4378
|
+
const { cursorLightValue, cursorDarkValue } = hueTokens[hexToHue(peerId ?? "0")];
|
|
4379
|
+
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
4380
|
+
space,
|
|
4381
|
+
channel: `automerge.awareness.${obj.id}`,
|
|
4382
|
+
info: {
|
|
4383
|
+
displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
|
|
4384
|
+
color: cursorLightValue,
|
|
4385
|
+
lightColor: cursorDarkValue
|
|
4386
|
+
},
|
|
4387
|
+
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
4388
|
+
});
|
|
4389
|
+
const extensions = [
|
|
4390
|
+
automerge({
|
|
4391
|
+
handle: doc.handle,
|
|
4392
|
+
path: doc.path
|
|
4393
|
+
})
|
|
4394
|
+
];
|
|
4395
|
+
if (awarenessProvider2) {
|
|
4396
|
+
extensions.push(awareness(awarenessProvider2));
|
|
4397
|
+
}
|
|
4398
|
+
return {
|
|
4399
|
+
id: obj.id,
|
|
4400
|
+
content: doc,
|
|
4401
|
+
text: () => get5(doc.handle.docSync(), doc.path),
|
|
4402
|
+
extension: extensions
|
|
4403
|
+
};
|
|
4404
|
+
};
|
|
4405
|
+
|
|
4406
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
4407
|
+
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
4408
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo = EditorView17.scrollIntoView(0), moveToEndOfLine, selection, theme, slots = defaultSlots, extensions = [], scrollPastEnd: _scrollPastEnd, debug }, forwardedRef) => {
|
|
4409
|
+
const tabsterDOMAttribute = useFocusableGroup({
|
|
4410
|
+
tabBehavior: "limited"
|
|
4411
|
+
});
|
|
4412
|
+
const { themeMode } = useThemeContext();
|
|
4413
|
+
const rootRef = useRef3(null);
|
|
4414
|
+
const [view, setView] = useState5(null);
|
|
4415
|
+
useImperativeHandle(forwardedRef, () => view, [
|
|
4416
|
+
view
|
|
4417
|
+
]);
|
|
4418
|
+
useEffect3(() => {
|
|
4419
|
+
if (autoFocus) {
|
|
4420
|
+
view?.focus();
|
|
4421
|
+
}
|
|
4422
|
+
}, [
|
|
4423
|
+
view,
|
|
4424
|
+
autoFocus
|
|
4425
|
+
]);
|
|
4426
|
+
useEffect3(() => {
|
|
4427
|
+
if (!model || !rootRef.current) {
|
|
4428
|
+
return;
|
|
4429
|
+
}
|
|
4430
|
+
const state = EditorState3.create({
|
|
4431
|
+
doc: typeof model.content === "string" ? model.content : DocAccessor.getValue(model.content),
|
|
4432
|
+
selection,
|
|
4433
|
+
extensions: [
|
|
4434
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4435
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4436
|
+
log5.catch(err, void 0, {
|
|
4437
|
+
F: __dxlog_file7,
|
|
4438
|
+
L: 123,
|
|
4439
|
+
S: void 0,
|
|
4440
|
+
C: (f, a) => f(...a)
|
|
4441
|
+
});
|
|
4442
|
+
}),
|
|
4443
|
+
// Theme.
|
|
4444
|
+
// TODO(burdon): Make base theme configurable.
|
|
4065
4445
|
EditorView17.baseTheme(defaultTheme),
|
|
4066
4446
|
theme && EditorView17.theme(theme),
|
|
4067
4447
|
EditorView17.darkTheme.of(themeMode === "dark"),
|
|
@@ -4072,7 +4452,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
4072
4452
|
class: slots.content.className
|
|
4073
4453
|
}),
|
|
4074
4454
|
// NOTE: Assumes default line height.
|
|
4075
|
-
_scrollPastEnd &&
|
|
4455
|
+
_scrollPastEnd && scrollPastEnd2(),
|
|
4076
4456
|
// Focus.
|
|
4077
4457
|
EditorView17.updateListener.of((update2) => {
|
|
4078
4458
|
update2.transactions.forEach((transaction) => {
|
|
@@ -4083,7 +4463,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
4083
4463
|
}),
|
|
4084
4464
|
// State.
|
|
4085
4465
|
EditorView17.editable.of(!readonly),
|
|
4086
|
-
|
|
4466
|
+
EditorState3.readOnly.of(!!readonly),
|
|
4087
4467
|
// Storage and replication.
|
|
4088
4468
|
// NOTE: This must come before user extensions.
|
|
4089
4469
|
model.extension,
|
|
@@ -4148,14 +4528,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
4148
4528
|
...tabsterDOMAttribute
|
|
4149
4529
|
});
|
|
4150
4530
|
});
|
|
4151
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping, theme = textTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
4531
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping = true, theme = textTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
4152
4532
|
const { themeMode } = useThemeContext();
|
|
4153
|
-
const updatedSlots =
|
|
4154
|
-
const extensions =
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
placeholder: placeholder3
|
|
4158
|
-
|
|
4533
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultTextSlots);
|
|
4534
|
+
const extensions = useMemo3(() => [
|
|
4535
|
+
createBasicExtensions({
|
|
4536
|
+
lineWrapping,
|
|
4537
|
+
placeholder: placeholder3
|
|
4538
|
+
}),
|
|
4539
|
+
createThemeExtensions({
|
|
4540
|
+
themeMode
|
|
4159
4541
|
}),
|
|
4160
4542
|
..._extensions ?? []
|
|
4161
4543
|
], [
|
|
@@ -4175,8 +4557,8 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
4175
4557
|
});
|
|
4176
4558
|
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, theme = markdownTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
|
|
4177
4559
|
const { themeMode } = useThemeContext();
|
|
4178
|
-
const updatedSlots =
|
|
4179
|
-
const extensions =
|
|
4560
|
+
const updatedSlots = defaultsDeep3({}, slots, defaultMarkdownSlots);
|
|
4561
|
+
const extensions = useMemo3(() => [
|
|
4180
4562
|
createMarkdownExtensions({
|
|
4181
4563
|
themeMode,
|
|
4182
4564
|
placeholder: placeholder3
|
|
@@ -4214,7 +4596,7 @@ var defaultMarkdownSlots = {
|
|
|
4214
4596
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
4215
4597
|
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";
|
|
4216
4598
|
import { createContext } from "@radix-ui/react-context";
|
|
4217
|
-
import React2, { useRef as
|
|
4599
|
+
import React2, { useRef as useRef4, useState as useState6 } from "react";
|
|
4218
4600
|
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
4219
4601
|
import { getSize } from "@dxos/react-ui-theme";
|
|
4220
4602
|
var tooltipProps = {
|
|
@@ -4272,9 +4654,9 @@ var MarkdownHeading = () => {
|
|
|
4272
4654
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4273
4655
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4274
4656
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
4275
|
-
const suppressNextTooltip =
|
|
4276
|
-
const [tooltipOpen, setTooltipOpen] =
|
|
4277
|
-
const [selectOpen, setSelectOpen] =
|
|
4657
|
+
const suppressNextTooltip = useRef4(false);
|
|
4658
|
+
const [tooltipOpen, setTooltipOpen] = useState6(false);
|
|
4659
|
+
const [selectOpen, setSelectOpen] = useState6(false);
|
|
4278
4660
|
return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
|
|
4279
4661
|
open: tooltipOpen,
|
|
4280
4662
|
onOpenChange: (nextOpen) => {
|
|
@@ -4477,384 +4859,6 @@ var Toolbar = {
|
|
|
4477
4859
|
Markdown: MarkdownStandard,
|
|
4478
4860
|
Extended: MarkdownExtended
|
|
4479
4861
|
};
|
|
4480
|
-
|
|
4481
|
-
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
4482
|
-
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
4483
|
-
import { Context as Context2 } from "@dxos/context";
|
|
4484
|
-
import { invariant as invariant2 } from "@dxos/invariant";
|
|
4485
|
-
import { log as log4 } from "@dxos/log";
|
|
4486
|
-
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
4487
|
-
var DEBOUNCE_INTERVAL = 100;
|
|
4488
|
-
var SpaceAwarenessProvider = class {
|
|
4489
|
-
constructor(params) {
|
|
4490
|
-
this._remoteStates = /* @__PURE__ */ new Map();
|
|
4491
|
-
this.remoteStateChange = new Event2();
|
|
4492
|
-
this._space = params.space;
|
|
4493
|
-
this._channel = params.channel;
|
|
4494
|
-
this._peerId = params.peerId;
|
|
4495
|
-
this._info = params.info;
|
|
4496
|
-
}
|
|
4497
|
-
open() {
|
|
4498
|
-
this._ctx = new Context2();
|
|
4499
|
-
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
4500
|
-
if (this._localState) {
|
|
4501
|
-
await this._space.postMessage(this._channel, {
|
|
4502
|
-
kind: "post",
|
|
4503
|
-
state: this._localState
|
|
4504
|
-
});
|
|
4505
|
-
await sleep(DEBOUNCE_INTERVAL);
|
|
4506
|
-
}
|
|
4507
|
-
});
|
|
4508
|
-
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
4509
|
-
switch (message.payload.kind) {
|
|
4510
|
-
case "query": {
|
|
4511
|
-
this._handleQueryMessage();
|
|
4512
|
-
break;
|
|
4513
|
-
}
|
|
4514
|
-
case "post": {
|
|
4515
|
-
this._handlePostMessage(message.payload);
|
|
4516
|
-
break;
|
|
4517
|
-
}
|
|
4518
|
-
}
|
|
4519
|
-
}));
|
|
4520
|
-
void this._space.postMessage(this._channel, {
|
|
4521
|
-
kind: "query"
|
|
4522
|
-
}).catch((err) => {
|
|
4523
|
-
log4.debug("failed to query awareness", {
|
|
4524
|
-
err
|
|
4525
|
-
}, {
|
|
4526
|
-
F: __dxlog_file5,
|
|
4527
|
-
L: 89,
|
|
4528
|
-
S: this,
|
|
4529
|
-
C: (f, a) => f(...a)
|
|
4530
|
-
});
|
|
4531
|
-
});
|
|
4532
|
-
}
|
|
4533
|
-
close() {
|
|
4534
|
-
void this._ctx?.dispose();
|
|
4535
|
-
this._ctx = void 0;
|
|
4536
|
-
this._postTask = void 0;
|
|
4537
|
-
}
|
|
4538
|
-
getRemoteStates() {
|
|
4539
|
-
return Array.from(this._remoteStates.values());
|
|
4540
|
-
}
|
|
4541
|
-
update(position) {
|
|
4542
|
-
invariant2(this._postTask, void 0, {
|
|
4543
|
-
F: __dxlog_file5,
|
|
4544
|
-
L: 104,
|
|
4545
|
-
S: this,
|
|
4546
|
-
A: [
|
|
4547
|
-
"this._postTask",
|
|
4548
|
-
""
|
|
4549
|
-
]
|
|
4550
|
-
});
|
|
4551
|
-
this._localState = {
|
|
4552
|
-
peerId: this._peerId,
|
|
4553
|
-
position,
|
|
4554
|
-
info: this._info
|
|
4555
|
-
};
|
|
4556
|
-
this._postTask.schedule();
|
|
4557
|
-
}
|
|
4558
|
-
_handleQueryMessage() {
|
|
4559
|
-
invariant2(this._postTask, void 0, {
|
|
4560
|
-
F: __dxlog_file5,
|
|
4561
|
-
L: 115,
|
|
4562
|
-
S: this,
|
|
4563
|
-
A: [
|
|
4564
|
-
"this._postTask",
|
|
4565
|
-
""
|
|
4566
|
-
]
|
|
4567
|
-
});
|
|
4568
|
-
this._postTask.schedule();
|
|
4569
|
-
}
|
|
4570
|
-
_handlePostMessage(message) {
|
|
4571
|
-
invariant2(message.kind === "post", void 0, {
|
|
4572
|
-
F: __dxlog_file5,
|
|
4573
|
-
L: 120,
|
|
4574
|
-
S: this,
|
|
4575
|
-
A: [
|
|
4576
|
-
"message.kind === 'post'",
|
|
4577
|
-
""
|
|
4578
|
-
]
|
|
4579
|
-
});
|
|
4580
|
-
this._remoteStates.set(message.state.peerId, message.state);
|
|
4581
|
-
this.remoteStateChange.emit();
|
|
4582
|
-
}
|
|
4583
|
-
};
|
|
4584
|
-
|
|
4585
|
-
// packages/ui/react-ui-editor/src/hooks/defs.ts
|
|
4586
|
-
import { StateField as StateField7 } from "@codemirror/state";
|
|
4587
|
-
var modelState = StateField7.define({
|
|
4588
|
-
create: () => void 0,
|
|
4589
|
-
update: (model) => model
|
|
4590
|
-
});
|
|
4591
|
-
|
|
4592
|
-
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
4593
|
-
var useActionHandler = (view) => {
|
|
4594
|
-
return (action) => {
|
|
4595
|
-
if (!view) {
|
|
4596
|
-
return;
|
|
4597
|
-
}
|
|
4598
|
-
let inlineType, listType;
|
|
4599
|
-
switch (action.type) {
|
|
4600
|
-
case "heading":
|
|
4601
|
-
setHeading(parseInt(action.data))(view);
|
|
4602
|
-
break;
|
|
4603
|
-
case "strong":
|
|
4604
|
-
case "emphasis":
|
|
4605
|
-
case "strikethrough":
|
|
4606
|
-
case "code":
|
|
4607
|
-
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
4608
|
-
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
4609
|
-
break;
|
|
4610
|
-
case "list-ordered":
|
|
4611
|
-
case "list-bullet":
|
|
4612
|
-
case "list-task":
|
|
4613
|
-
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
4614
|
-
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
4615
|
-
break;
|
|
4616
|
-
case "blockquote":
|
|
4617
|
-
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
4618
|
-
break;
|
|
4619
|
-
case "codeblock":
|
|
4620
|
-
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
4621
|
-
break;
|
|
4622
|
-
case "table":
|
|
4623
|
-
insertTable(view);
|
|
4624
|
-
break;
|
|
4625
|
-
case "link":
|
|
4626
|
-
(action.data === false ? removeLink : addLink)(view);
|
|
4627
|
-
break;
|
|
4628
|
-
case "comment":
|
|
4629
|
-
createComment(view);
|
|
4630
|
-
break;
|
|
4631
|
-
}
|
|
4632
|
-
setTimeout(() => {
|
|
4633
|
-
if (!view.hasFocus) {
|
|
4634
|
-
view.focus();
|
|
4635
|
-
}
|
|
4636
|
-
});
|
|
4637
|
-
};
|
|
4638
|
-
};
|
|
4639
|
-
|
|
4640
|
-
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
4641
|
-
import { useRef as useRef3, useState as useState4 } from "react";
|
|
4642
|
-
var useEditorView = (id) => {
|
|
4643
|
-
const editorRef = useRef3(null);
|
|
4644
|
-
const [prev, setPrev] = useState4([
|
|
4645
|
-
null,
|
|
4646
|
-
""
|
|
4647
|
-
]);
|
|
4648
|
-
if (prev[0] !== editorRef.current) {
|
|
4649
|
-
setPrev([
|
|
4650
|
-
editorRef.current,
|
|
4651
|
-
id
|
|
4652
|
-
]);
|
|
4653
|
-
}
|
|
4654
|
-
return [
|
|
4655
|
-
editorRef,
|
|
4656
|
-
prev[1] !== id
|
|
4657
|
-
];
|
|
4658
|
-
};
|
|
4659
|
-
|
|
4660
|
-
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4661
|
-
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4662
|
-
import { EditorView as EditorView18 } from "@codemirror/view";
|
|
4663
|
-
import { useEffect as useEffect3, useRef as useRef4, useState as useState5 } from "react";
|
|
4664
|
-
import { log as log5 } from "@dxos/log";
|
|
4665
|
-
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4666
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4667
|
-
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}, deps) => {
|
|
4668
|
-
const onUpdate = useRef4();
|
|
4669
|
-
const [view, setView] = useState5();
|
|
4670
|
-
const parentRef = useRef4(null);
|
|
4671
|
-
useEffect3(() => {
|
|
4672
|
-
let view2;
|
|
4673
|
-
if (parentRef.current) {
|
|
4674
|
-
const state = EditorState3.create({
|
|
4675
|
-
doc,
|
|
4676
|
-
selection,
|
|
4677
|
-
extensions: [
|
|
4678
|
-
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4679
|
-
EditorView18.exceptionSink.of((err) => {
|
|
4680
|
-
log5.catch(err, void 0, {
|
|
4681
|
-
F: __dxlog_file6,
|
|
4682
|
-
L: 57,
|
|
4683
|
-
S: void 0,
|
|
4684
|
-
C: (f, a) => f(...a)
|
|
4685
|
-
});
|
|
4686
|
-
}),
|
|
4687
|
-
extensions,
|
|
4688
|
-
EditorView18.updateListener.of(() => {
|
|
4689
|
-
onUpdate.current?.();
|
|
4690
|
-
})
|
|
4691
|
-
].filter(isNotFalsy5)
|
|
4692
|
-
});
|
|
4693
|
-
view2 = new EditorView18({
|
|
4694
|
-
parent: parentRef.current,
|
|
4695
|
-
scrollTo,
|
|
4696
|
-
state,
|
|
4697
|
-
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4698
|
-
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4699
|
-
dispatchTransactions: (trs, view3) => {
|
|
4700
|
-
if (debug) {
|
|
4701
|
-
logChanges(trs);
|
|
4702
|
-
}
|
|
4703
|
-
view3.update(trs);
|
|
4704
|
-
}
|
|
4705
|
-
});
|
|
4706
|
-
setView(view2);
|
|
4707
|
-
}
|
|
4708
|
-
return () => {
|
|
4709
|
-
view2?.destroy();
|
|
4710
|
-
};
|
|
4711
|
-
}, deps);
|
|
4712
|
-
useEffect3(() => {
|
|
4713
|
-
if (view) {
|
|
4714
|
-
if (!selection && !view.state.selection.main.anchor) {
|
|
4715
|
-
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4716
|
-
}
|
|
4717
|
-
if (selection || scrollTo) {
|
|
4718
|
-
onUpdate.current = () => {
|
|
4719
|
-
onUpdate.current = void 0;
|
|
4720
|
-
view.dispatch({
|
|
4721
|
-
selection,
|
|
4722
|
-
effects: scrollTo && [
|
|
4723
|
-
scrollTo
|
|
4724
|
-
],
|
|
4725
|
-
scrollIntoView: !scrollTo
|
|
4726
|
-
});
|
|
4727
|
-
};
|
|
4728
|
-
}
|
|
4729
|
-
if (autoFocus) {
|
|
4730
|
-
view.focus();
|
|
4731
|
-
}
|
|
4732
|
-
}
|
|
4733
|
-
}, [
|
|
4734
|
-
view,
|
|
4735
|
-
autoFocus,
|
|
4736
|
-
selection,
|
|
4737
|
-
scrollTo
|
|
4738
|
-
]);
|
|
4739
|
-
return {
|
|
4740
|
-
parentRef,
|
|
4741
|
-
view
|
|
4742
|
-
};
|
|
4743
|
-
};
|
|
4744
|
-
var createDataExtensions = ({ readonly = false } = {}) => {
|
|
4745
|
-
return [
|
|
4746
|
-
//
|
|
4747
|
-
EditorState3.readOnly.of(readonly),
|
|
4748
|
-
EditorView18.editable.of(!readonly)
|
|
4749
|
-
];
|
|
4750
|
-
};
|
|
4751
|
-
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4752
|
-
return [
|
|
4753
|
-
//
|
|
4754
|
-
EditorView18.baseTheme(defaultTheme),
|
|
4755
|
-
theme && EditorView18.theme(theme),
|
|
4756
|
-
EditorView18.darkTheme.of(themeMode === "dark"),
|
|
4757
|
-
EditorView18.editorAttributes.of({
|
|
4758
|
-
class: slots?.editor?.className ?? ""
|
|
4759
|
-
}),
|
|
4760
|
-
EditorView18.contentAttributes.of({
|
|
4761
|
-
class: slots?.content?.className ?? ""
|
|
4762
|
-
})
|
|
4763
|
-
].filter(isNotFalsy5);
|
|
4764
|
-
};
|
|
4765
|
-
|
|
4766
|
-
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
4767
|
-
import get5 from "lodash.get";
|
|
4768
|
-
import { useState as useState6, useMemo as useMemo3 } from "react";
|
|
4769
|
-
import { generateName } from "@dxos/display-name";
|
|
4770
|
-
import { getRawDoc } from "@dxos/echo-schema";
|
|
4771
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
4772
|
-
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
4773
|
-
import { hueTokens } from "@dxos/react-ui-theme";
|
|
4774
|
-
import { hexToHue } from "@dxos/util";
|
|
4775
|
-
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
4776
|
-
var useTextExtensions = ({ id, text, space, identity }) => {
|
|
4777
|
-
const extensions = [
|
|
4778
|
-
automerge(text)
|
|
4779
|
-
];
|
|
4780
|
-
const peerId = identity?.identityKey.toHex();
|
|
4781
|
-
const { cursorLightValue, cursorDarkValue } = hueTokens[hexToHue(peerId ?? "0")];
|
|
4782
|
-
if (space && identity) {
|
|
4783
|
-
const awarenessProvider2 = new SpaceAwarenessProvider({
|
|
4784
|
-
space,
|
|
4785
|
-
channel: `awareness.${id}`,
|
|
4786
|
-
peerId: identity.identityKey.toHex(),
|
|
4787
|
-
info: {
|
|
4788
|
-
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
4789
|
-
color: cursorDarkValue,
|
|
4790
|
-
lightColor: cursorLightValue
|
|
4791
|
-
}
|
|
4792
|
-
});
|
|
4793
|
-
extensions.push(awareness(awarenessProvider2));
|
|
4794
|
-
}
|
|
4795
|
-
return extensions;
|
|
4796
|
-
};
|
|
4797
|
-
var useTextModel = (props) => useMemo3(() => createModel(props), Object.values(props));
|
|
4798
|
-
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4799
|
-
const [content, setContent] = useState6(defaultContent ?? "");
|
|
4800
|
-
return {
|
|
4801
|
-
id,
|
|
4802
|
-
content,
|
|
4803
|
-
setContent,
|
|
4804
|
-
text: () => content
|
|
4805
|
-
};
|
|
4806
|
-
};
|
|
4807
|
-
var createModel = ({ space, identity, text }) => {
|
|
4808
|
-
if (!text) {
|
|
4809
|
-
return void 0;
|
|
4810
|
-
}
|
|
4811
|
-
invariant3(isAutomergeObject(text), void 0, {
|
|
4812
|
-
F: __dxlog_file7,
|
|
4813
|
-
L: 87,
|
|
4814
|
-
S: void 0,
|
|
4815
|
-
A: [
|
|
4816
|
-
"isAutomergeObject(text)",
|
|
4817
|
-
""
|
|
4818
|
-
]
|
|
4819
|
-
});
|
|
4820
|
-
const obj = text;
|
|
4821
|
-
const doc = getRawDoc(obj, [
|
|
4822
|
-
obj.field
|
|
4823
|
-
]);
|
|
4824
|
-
const peerId = identity?.identityKey.toHex();
|
|
4825
|
-
const { cursorLightValue, cursorDarkValue } = hueTokens[hexToHue(peerId ?? "0")];
|
|
4826
|
-
const awarenessProvider2 = space && new SpaceAwarenessProvider({
|
|
4827
|
-
space,
|
|
4828
|
-
channel: `automerge.awareness.${obj.id}`,
|
|
4829
|
-
info: {
|
|
4830
|
-
displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
|
|
4831
|
-
color: cursorLightValue,
|
|
4832
|
-
lightColor: cursorDarkValue
|
|
4833
|
-
},
|
|
4834
|
-
peerId: identity?.identityKey.toHex() ?? "Anonymous"
|
|
4835
|
-
});
|
|
4836
|
-
const extensions = [
|
|
4837
|
-
modelState.init(() => model),
|
|
4838
|
-
automerge({
|
|
4839
|
-
handle: doc.handle,
|
|
4840
|
-
path: doc.path
|
|
4841
|
-
})
|
|
4842
|
-
];
|
|
4843
|
-
if (awarenessProvider2) {
|
|
4844
|
-
extensions.push(awareness(awarenessProvider2));
|
|
4845
|
-
}
|
|
4846
|
-
const model = {
|
|
4847
|
-
id: obj.id,
|
|
4848
|
-
content: doc,
|
|
4849
|
-
text: () => get5(doc.handle.docSync(), doc.path),
|
|
4850
|
-
extension: extensions,
|
|
4851
|
-
peer: identity ? {
|
|
4852
|
-
id: identity.identityKey.toHex(),
|
|
4853
|
-
name: identity.profile?.displayName
|
|
4854
|
-
} : void 0
|
|
4855
|
-
};
|
|
4856
|
-
return model;
|
|
4857
|
-
};
|
|
4858
4862
|
export {
|
|
4859
4863
|
BaseTextEditor,
|
|
4860
4864
|
Cursor,
|
|
@@ -4886,9 +4890,8 @@ export {
|
|
|
4886
4890
|
command,
|
|
4887
4891
|
comments,
|
|
4888
4892
|
compareFormatting,
|
|
4889
|
-
|
|
4893
|
+
createBasicExtensions,
|
|
4890
4894
|
createComment,
|
|
4891
|
-
createDataExtensions,
|
|
4892
4895
|
createMarkdownExtensions,
|
|
4893
4896
|
createThemeExtensions,
|
|
4894
4897
|
cursorLineMargin,
|
|
@@ -4919,7 +4922,6 @@ export {
|
|
|
4919
4922
|
markdownTagsExtensions,
|
|
4920
4923
|
markdownTheme,
|
|
4921
4924
|
mention,
|
|
4922
|
-
modelState,
|
|
4923
4925
|
outliner,
|
|
4924
4926
|
removeBlockquote,
|
|
4925
4927
|
removeCodeblock,
|