@dxos/react-ui-editor 0.4.8-main.27faba7 → 0.4.8-main.512e4c8
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 +920 -1084
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +18 -34
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +79 -5
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.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 +1 -15
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/index.d.ts +0 -1
- package/dist/types/src/extensions/automerge/index.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts +2 -1
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +2 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/cursor-line-margin.d.ts +6 -7
- package/dist/types/src/extensions/cursor-line-margin.d.ts.map +1 -1
- package/dist/types/src/extensions/doc.d.ts +3 -0
- package/dist/types/src/extensions/doc.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +1 -1
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +5 -4
- 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/hooks/defs.d.ts +0 -11
- package/dist/types/src/hooks/defs.d.ts.map +1 -1
- package/dist/types/src/hooks/extension-utils.d.ts +54 -0
- package/dist/types/src/hooks/extension-utils.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +1 -2
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +3 -44
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.stories.d.ts +6 -0
- package/dist/types/src/hooks/useTextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts +0 -3
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/package.json +24 -24
- package/src/components/TextEditor/TextEditor.stories.tsx +510 -23
- package/src/components/TextEditor/TextEditor.tsx +37 -149
- package/src/components/Toolbar/Toolbar.stories.tsx +46 -42
- package/src/extensions/automerge/automerge.stories.tsx +14 -16
- package/src/extensions/automerge/automerge.ts +2 -1
- package/src/extensions/automerge/cursor.ts +1 -1
- package/src/extensions/automerge/defs.ts +1 -22
- package/src/extensions/automerge/index.ts +0 -1
- package/src/extensions/automerge/sync.ts +2 -9
- package/src/extensions/automerge/update-automerge.ts +2 -1
- package/src/extensions/command/state.ts +1 -1
- package/src/extensions/comments.ts +8 -4
- package/src/extensions/cursor-line-margin.ts +17 -18
- package/src/extensions/doc.ts +14 -0
- package/src/extensions/index.ts +1 -1
- package/src/extensions/markdown/bundle.ts +11 -28
- package/src/extensions/markdown/decorate.ts +1 -3
- package/src/extensions/markdown/formatting.ts +15 -10
- package/src/extensions/markdown/image.ts +1 -0
- package/src/extensions/markdown/table.ts +11 -3
- package/src/hooks/defs.ts +0 -15
- package/src/hooks/extension-utils.ts +185 -0
- package/src/hooks/index.ts +1 -2
- package/src/hooks/useTextEditor.stories.tsx +39 -34
- package/src/hooks/useTextEditor.ts +11 -120
- package/src/index.ts +1 -1
- package/src/themes/default.ts +1 -28
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +0 -103
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +0 -1
- package/dist/types/src/extensions/outliner.d.ts +0 -4
- package/dist/types/src/extensions/outliner.d.ts.map +0 -1
- package/dist/types/src/hooks/useEditorView.d.ts +0 -20
- package/dist/types/src/hooks/useEditorView.d.ts.map +0 -1
- package/dist/types/src/hooks/useTextModel.d.ts +0 -33
- package/dist/types/src/hooks/useTextModel.d.ts.map +0 -1
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +0 -524
- package/src/extensions/outliner.ts +0 -12
- package/src/hooks/useEditorView.ts +0 -32
- package/src/hooks/useTextModel.ts +0 -121
|
@@ -29,16 +29,12 @@ 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
|
|
33
|
-
import { EditorView as
|
|
32
|
+
import { EditorState } from "@codemirror/state";
|
|
33
|
+
import { EditorView as EditorView15 } from "@codemirror/view";
|
|
34
34
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
35
|
-
import
|
|
36
|
-
import
|
|
37
|
-
import {
|
|
38
|
-
import { log as log9 } from "@dxos/log";
|
|
39
|
-
import { useThemeContext } from "@dxos/react-ui";
|
|
40
|
-
import { focusRing } from "@dxos/react-ui-theme";
|
|
41
|
-
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
35
|
+
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2 } from "react";
|
|
36
|
+
import { log as log7 } from "@dxos/log";
|
|
37
|
+
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
42
38
|
|
|
43
39
|
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
|
44
40
|
import { StateField } from "@codemirror/state";
|
|
@@ -243,7 +239,6 @@ var cursorConverter = ({ handle, path }) => ({
|
|
|
243
239
|
|
|
244
240
|
// packages/ui/react-ui-editor/src/extensions/automerge/defs.ts
|
|
245
241
|
import { Annotation, StateEffect } from "@codemirror/state";
|
|
246
|
-
import get2 from "lodash.get";
|
|
247
242
|
var getPath = (state, field) => state.field(field).path;
|
|
248
243
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
249
244
|
var updateHeadsEffect = StateEffect.define({});
|
|
@@ -1110,8 +1105,8 @@ var commandState = StateField3.define({
|
|
|
1110
1105
|
}
|
|
1111
1106
|
return state;
|
|
1112
1107
|
},
|
|
1113
|
-
provide: (
|
|
1114
|
-
showTooltip.from(
|
|
1108
|
+
provide: (field) => [
|
|
1109
|
+
showTooltip.from(field, (value) => value.tooltip ?? null)
|
|
1115
1110
|
]
|
|
1116
1111
|
});
|
|
1117
1112
|
var openEffect = StateEffect2.define();
|
|
@@ -1293,10 +1288,10 @@ var inlineUrl = mx(code, "px-1");
|
|
|
1293
1288
|
var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
|
|
1294
1289
|
|
|
1295
1290
|
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
|
1296
|
-
import
|
|
1291
|
+
import get2 from "lodash.get";
|
|
1297
1292
|
import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
1298
1293
|
var tokens = tailwindConfig({}).theme;
|
|
1299
|
-
var getToken = (path, defaultValue = void 0) =>
|
|
1294
|
+
var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue);
|
|
1300
1295
|
|
|
1301
1296
|
// packages/ui/react-ui-editor/src/styles/layout.ts
|
|
1302
1297
|
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
|
@@ -1735,12 +1730,14 @@ var focusComment = (view, id, center = true) => {
|
|
|
1735
1730
|
var useComments = (view, id, comments2 = []) => {
|
|
1736
1731
|
useEffect(() => {
|
|
1737
1732
|
if (view) {
|
|
1738
|
-
view.
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1733
|
+
if (id === view.state.facet(documentId)) {
|
|
1734
|
+
view.dispatch({
|
|
1735
|
+
effects: setComments.of({
|
|
1736
|
+
id,
|
|
1737
|
+
comments: comments2
|
|
1738
|
+
})
|
|
1739
|
+
});
|
|
1740
|
+
}
|
|
1744
1741
|
}
|
|
1745
1742
|
}, [
|
|
1746
1743
|
id,
|
|
@@ -1750,74 +1747,97 @@ var useComments = (view, id, comments2 = []) => {
|
|
|
1750
1747
|
};
|
|
1751
1748
|
|
|
1752
1749
|
// packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts
|
|
1753
|
-
import {
|
|
1750
|
+
import { Transaction } from "@codemirror/state";
|
|
1754
1751
|
import { EditorView as EditorView8 } from "@codemirror/view";
|
|
1755
1752
|
import { log as log4 } from "@dxos/log";
|
|
1756
1753
|
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
|
-
});
|
|
1760
1754
|
var annotation = "cursorLineMargin";
|
|
1761
1755
|
var lineAtPos = (s, pos) => s.doc.lineAt(pos).number;
|
|
1762
|
-
var cursorLineMargin =
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
|
-
|
|
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;
|
|
1756
|
+
var cursorLineMargin = (options = {
|
|
1757
|
+
lines: 3
|
|
1758
|
+
}) => {
|
|
1759
|
+
const { lines } = options;
|
|
1760
|
+
if (!lines || lines <= 0) {
|
|
1761
|
+
return [];
|
|
1790
1762
|
}
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
const oldMainLine = lineAtPos(startState, head);
|
|
1794
|
-
if (needsScrollTop && oldMainLine < mainLine) {
|
|
1763
|
+
return EditorView8.updateListener.of(({ transactions, state, selectionSet, startState, view }) => {
|
|
1764
|
+
if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
|
|
1795
1765
|
return;
|
|
1796
1766
|
}
|
|
1797
|
-
|
|
1767
|
+
const s = state;
|
|
1768
|
+
const { main } = s.selection;
|
|
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 - lines;
|
|
1779
|
+
if (needsScrollTop && needsScrollBot) {
|
|
1780
|
+
log4.warn("is cursorScrollMargin too large for the editor size?", void 0, {
|
|
1781
|
+
F: __dxlog_file5,
|
|
1782
|
+
L: 65,
|
|
1783
|
+
S: void 0,
|
|
1784
|
+
C: (f, a) => f(...a)
|
|
1785
|
+
});
|
|
1798
1786
|
return;
|
|
1799
1787
|
}
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
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) {
|
|
1795
|
+
return;
|
|
1796
|
+
}
|
|
1797
|
+
if (needsScrollBot && oldMainLine > mainLine) {
|
|
1798
|
+
return;
|
|
1799
|
+
}
|
|
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 * lines
|
|
1806
|
+
})
|
|
1807
|
+
});
|
|
1807
1808
|
});
|
|
1809
|
+
};
|
|
1810
|
+
|
|
1811
|
+
// packages/ui/react-ui-editor/src/extensions/doc.ts
|
|
1812
|
+
import { Facet as Facet5 } from "@codemirror/state";
|
|
1813
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1814
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/doc.ts";
|
|
1815
|
+
var documentId2 = Facet5.define({
|
|
1816
|
+
combine: (providers) => {
|
|
1817
|
+
invariant2(providers.length <= 1, void 0, {
|
|
1818
|
+
F: __dxlog_file6,
|
|
1819
|
+
L: 11,
|
|
1820
|
+
S: void 0,
|
|
1821
|
+
A: [
|
|
1822
|
+
"providers.length <= 1",
|
|
1823
|
+
""
|
|
1824
|
+
]
|
|
1825
|
+
});
|
|
1826
|
+
return providers[0];
|
|
1827
|
+
}
|
|
1808
1828
|
});
|
|
1809
1829
|
|
|
1810
1830
|
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
|
1811
1831
|
import { EditorView as EditorView9 } from "@codemirror/view";
|
|
1812
1832
|
import { log as log5 } from "@dxos/log";
|
|
1813
|
-
var
|
|
1833
|
+
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/dnd.ts";
|
|
1814
1834
|
var dnd = () => {
|
|
1815
1835
|
return EditorView9.domEventHandlers({
|
|
1816
1836
|
drop: (event, view) => {
|
|
1817
1837
|
log5.info("domEventHandlersDrop", {
|
|
1818
1838
|
event
|
|
1819
1839
|
}, {
|
|
1820
|
-
F:
|
|
1840
|
+
F: __dxlog_file7,
|
|
1821
1841
|
L: 14,
|
|
1822
1842
|
S: void 0,
|
|
1823
1843
|
C: (f, a) => f(...a)
|
|
@@ -1841,16 +1861,14 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
1841
1861
|
};
|
|
1842
1862
|
|
|
1843
1863
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1844
|
-
import {
|
|
1845
|
-
import {
|
|
1864
|
+
import { closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1865
|
+
import { historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1846
1866
|
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1847
|
-
import {
|
|
1867
|
+
import { defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
1848
1868
|
import { languages } from "@codemirror/language-data";
|
|
1849
1869
|
import { searchKeymap } from "@codemirror/search";
|
|
1850
|
-
import { EditorState } from "@codemirror/state";
|
|
1851
1870
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
1852
|
-
import {
|
|
1853
|
-
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
1871
|
+
import { keymap as keymap5 } from "@codemirror/view";
|
|
1854
1872
|
|
|
1855
1873
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1856
1874
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -2041,19 +2059,8 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
2041
2059
|
};
|
|
2042
2060
|
|
|
2043
2061
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
2044
|
-
var createMarkdownExtensions = ({ themeMode
|
|
2062
|
+
var createMarkdownExtensions = ({ themeMode } = {}) => {
|
|
2045
2063
|
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),
|
|
2057
2064
|
// Main extension.
|
|
2058
2065
|
// https://github.com/codemirror/lang-markdown
|
|
2059
2066
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -2088,13 +2095,13 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
2088
2095
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
2089
2096
|
...standardKeymap
|
|
2090
2097
|
])
|
|
2091
|
-
]
|
|
2098
|
+
];
|
|
2092
2099
|
};
|
|
2093
2100
|
|
|
2094
2101
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
|
2095
2102
|
import { syntaxTree } from "@codemirror/language";
|
|
2096
2103
|
import { RangeSetBuilder as RangeSetBuilder2, StateEffect as StateEffect4 } from "@codemirror/state";
|
|
2097
|
-
import { EditorView as
|
|
2104
|
+
import { EditorView as EditorView11, Decoration as Decoration5, WidgetType as WidgetType3, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
2098
2105
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
2099
2106
|
var HorizontalRuleWidget = class extends WidgetType3 {
|
|
2100
2107
|
toDOM() {
|
|
@@ -2302,15 +2309,15 @@ var decorateMarkdown = (options = {}) => {
|
|
|
2302
2309
|
}
|
|
2303
2310
|
}, {
|
|
2304
2311
|
provide: (plugin) => [
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2312
|
+
EditorView11.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
2313
|
+
EditorView11.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
2314
|
+
EditorView11.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration5.none)
|
|
2308
2315
|
]
|
|
2309
2316
|
}),
|
|
2310
2317
|
formattingStyles
|
|
2311
2318
|
];
|
|
2312
2319
|
};
|
|
2313
|
-
var formattingStyles =
|
|
2320
|
+
var formattingStyles = EditorView11.baseTheme({
|
|
2314
2321
|
"& .cm-code": {
|
|
2315
2322
|
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
2316
2323
|
},
|
|
@@ -2363,7 +2370,7 @@ var formattingStyles = EditorView12.baseTheme({
|
|
|
2363
2370
|
import { snippet } from "@codemirror/autocomplete";
|
|
2364
2371
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2365
2372
|
import { EditorSelection } from "@codemirror/state";
|
|
2366
|
-
import { EditorView as
|
|
2373
|
+
import { EditorView as EditorView12, keymap as keymap6 } from "@codemirror/view";
|
|
2367
2374
|
import { useState, useMemo } from "react";
|
|
2368
2375
|
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;
|
|
2369
2376
|
var Inline;
|
|
@@ -3018,8 +3025,8 @@ var removeList = (type) => ({ state, dispatch }) => {
|
|
|
3018
3025
|
return true;
|
|
3019
3026
|
};
|
|
3020
3027
|
var toggleList = (type) => (target) => {
|
|
3021
|
-
const
|
|
3022
|
-
const active =
|
|
3028
|
+
const formatting = getFormatting(target.state);
|
|
3029
|
+
const active = formatting.listStyle === (type === 1 ? "bullet" : type === 0 ? "ordered" : "task");
|
|
3023
3030
|
return (active ? removeList(type) : addList(type))(target);
|
|
3024
3031
|
};
|
|
3025
3032
|
var renumberListItems = (item, counter, changes, doc) => {
|
|
@@ -3233,7 +3240,7 @@ var removeCodeblock = ({ state, dispatch }) => {
|
|
|
3233
3240
|
var toggleCodeblock = (target) => {
|
|
3234
3241
|
return (getFormatting(target.state).blockType === "codeblock" ? removeCodeblock : addCodeblock)(target);
|
|
3235
3242
|
};
|
|
3236
|
-
var
|
|
3243
|
+
var formattingKeymap = (options = {}) => {
|
|
3237
3244
|
return [
|
|
3238
3245
|
keymap6.of([
|
|
3239
3246
|
{
|
|
@@ -3433,7 +3440,7 @@ var getFormatting = (state) => {
|
|
|
3433
3440
|
};
|
|
3434
3441
|
var useFormattingState = () => {
|
|
3435
3442
|
const [state, setState] = useState(null);
|
|
3436
|
-
const observer = useMemo(() =>
|
|
3443
|
+
const observer = useMemo(() => EditorView12.updateListener.of((update2) => {
|
|
3437
3444
|
if (update2.docChanged || update2.selectionSet) {
|
|
3438
3445
|
const newState = getFormatting(update2.state);
|
|
3439
3446
|
if (!state || !compareFormatting(state, newState)) {
|
|
@@ -3450,7 +3457,7 @@ var useFormattingState = () => {
|
|
|
3450
3457
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
3451
3458
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3452
3459
|
import { StateField as StateField5 } from "@codemirror/state";
|
|
3453
|
-
import { Decoration as Decoration6, EditorView as
|
|
3460
|
+
import { Decoration as Decoration6, EditorView as EditorView13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3454
3461
|
var image = (options = {}) => {
|
|
3455
3462
|
return StateField5.define({
|
|
3456
3463
|
create: (state) => {
|
|
@@ -3477,7 +3484,7 @@ var image = (options = {}) => {
|
|
|
3477
3484
|
add: buildDecorations2(from, to, tr.state)
|
|
3478
3485
|
});
|
|
3479
3486
|
},
|
|
3480
|
-
provide: (field) =>
|
|
3487
|
+
provide: (field) => EditorView13.decorations.from(field)
|
|
3481
3488
|
});
|
|
3482
3489
|
};
|
|
3483
3490
|
var preloaded = /* @__PURE__ */ new Set();
|
|
@@ -3565,12 +3572,12 @@ var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
|
|
|
3565
3572
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
3566
3573
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
3567
3574
|
import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField6 } from "@codemirror/state";
|
|
3568
|
-
import { Decoration as Decoration7, EditorView as
|
|
3575
|
+
import { Decoration as Decoration7, EditorView as EditorView14, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
3569
3576
|
var table = (options = {}) => {
|
|
3570
3577
|
return StateField6.define({
|
|
3571
3578
|
create: (state) => update(state, options),
|
|
3572
3579
|
update: (_, tr) => update(tr.state, options),
|
|
3573
|
-
provide: (field) =>
|
|
3580
|
+
provide: (field) => EditorView14.decorations.from(field)
|
|
3574
3581
|
});
|
|
3575
3582
|
};
|
|
3576
3583
|
var update = (state, options) => {
|
|
@@ -3614,9 +3621,11 @@ var update = (state, options) => {
|
|
|
3614
3621
|
});
|
|
3615
3622
|
tables.forEach((table2) => {
|
|
3616
3623
|
const hide2 = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3624
|
+
if (hide2) {
|
|
3625
|
+
builder.add(table2.from, table2.to, Decoration7.replace({
|
|
3626
|
+
widget: new TableWidget(table2)
|
|
3627
|
+
}));
|
|
3628
|
+
}
|
|
3620
3629
|
builder.add(table2.from, table2.to, Decoration7.mark({
|
|
3621
3630
|
class: "cm-table"
|
|
3622
3631
|
}));
|
|
@@ -3663,7 +3672,7 @@ var TableWidget = class extends WidgetType5 {
|
|
|
3663
3672
|
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
|
3664
3673
|
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
3665
3674
|
import { log as log6 } from "@dxos/log";
|
|
3666
|
-
var
|
|
3675
|
+
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
|
|
3667
3676
|
var mention = ({ onSearch }) => {
|
|
3668
3677
|
return autocompletion2({
|
|
3669
3678
|
// TODO(burdon): Not working.
|
|
@@ -3678,7 +3687,7 @@ var mention = ({ onSearch }) => {
|
|
|
3678
3687
|
log6.info("completion context", {
|
|
3679
3688
|
context
|
|
3680
3689
|
}, {
|
|
3681
|
-
F:
|
|
3690
|
+
F: __dxlog_file8,
|
|
3682
3691
|
L: 26,
|
|
3683
3692
|
S: void 0,
|
|
3684
3693
|
C: (f, a) => f(...a)
|
|
@@ -3727,11 +3736,6 @@ var EditorModes = {
|
|
|
3727
3736
|
]
|
|
3728
3737
|
};
|
|
3729
3738
|
|
|
3730
|
-
// packages/ui/react-ui-editor/src/extensions/outliner.ts
|
|
3731
|
-
var outliner = (options = {}) => {
|
|
3732
|
-
return [];
|
|
3733
|
-
};
|
|
3734
|
-
|
|
3735
3739
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
3736
3740
|
import { keymap as keymap8 } from "@codemirror/view";
|
|
3737
3741
|
var defaultItems = [
|
|
@@ -3789,263 +3793,577 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
3789
3793
|
];
|
|
3790
3794
|
};
|
|
3791
3795
|
|
|
3792
|
-
// packages/ui/react-ui-editor/src/
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3796
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
3797
|
+
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
3798
|
+
var instanceCount = 0;
|
|
3799
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, className, autoFocus, scrollTo = EditorView15.scrollIntoView(0), moveToEndOfLine, debug, dataTestId }, forwardedRef) => {
|
|
3800
|
+
const [instanceId] = useState2(() => `text-editor-${++instanceCount}`);
|
|
3801
|
+
const tabsterDOMAttribute = useFocusableGroup({
|
|
3802
|
+
tabBehavior: "limited"
|
|
3803
|
+
});
|
|
3804
|
+
const rootRef = useRef(null);
|
|
3805
|
+
const [view, setView] = useState2(null);
|
|
3806
|
+
useImperativeHandle(forwardedRef, () => view, [
|
|
3807
|
+
view
|
|
3808
|
+
]);
|
|
3809
|
+
useEffect2(() => {
|
|
3810
|
+
if (autoFocus) {
|
|
3811
|
+
view?.focus();
|
|
3812
|
+
}
|
|
3813
|
+
}, [
|
|
3814
|
+
view,
|
|
3815
|
+
autoFocus
|
|
3816
|
+
]);
|
|
3817
|
+
useEffect2(() => {
|
|
3818
|
+
log7("updating", {
|
|
3819
|
+
id,
|
|
3820
|
+
instanceId
|
|
3821
|
+
}, {
|
|
3822
|
+
F: __dxlog_file9,
|
|
3823
|
+
L: 88,
|
|
3824
|
+
S: void 0,
|
|
3825
|
+
C: (f, a) => f(...a)
|
|
3818
3826
|
});
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3827
|
+
const state = EditorState.create({
|
|
3828
|
+
doc,
|
|
3829
|
+
selection,
|
|
3830
|
+
extensions: [
|
|
3831
|
+
id && documentId2.of(id),
|
|
3832
|
+
// TODO(burdon): NOTE: Doesn't catch errors in keymap functions.
|
|
3833
|
+
EditorView15.exceptionSink.of((err) => {
|
|
3834
|
+
log7.catch(err, void 0, {
|
|
3835
|
+
F: __dxlog_file9,
|
|
3836
|
+
L: 101,
|
|
3837
|
+
S: void 0,
|
|
3838
|
+
C: (f, a) => f(...a)
|
|
3839
|
+
});
|
|
3840
|
+
}),
|
|
3841
|
+
// Focus.
|
|
3842
|
+
EditorView15.updateListener.of((update2) => {
|
|
3843
|
+
update2.transactions.forEach((transaction) => {
|
|
3844
|
+
if (transaction.isUserEvent("focus.container")) {
|
|
3845
|
+
rootRef.current?.focus();
|
|
3846
|
+
}
|
|
3847
|
+
});
|
|
3848
|
+
}),
|
|
3849
|
+
extensions
|
|
3850
|
+
].filter(isNotFalsy2)
|
|
3851
|
+
});
|
|
3852
|
+
const view2 = new EditorView15({
|
|
3853
|
+
state,
|
|
3854
|
+
parent: rootRef.current,
|
|
3855
|
+
scrollTo,
|
|
3856
|
+
// NOTE: Uncomment to debug/monitor all transactions.
|
|
3857
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
3858
|
+
dispatchTransactions: (trs, view3) => {
|
|
3859
|
+
if (debug) {
|
|
3860
|
+
logChanges(trs);
|
|
3828
3861
|
}
|
|
3862
|
+
view3.update(trs);
|
|
3829
3863
|
}
|
|
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
3864
|
});
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
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;
|
|
3865
|
+
setView(view2);
|
|
3866
|
+
if (moveToEndOfLine) {
|
|
3867
|
+
const { to } = view2.state.doc.lineAt(0);
|
|
3868
|
+
view2?.dispatch({
|
|
3869
|
+
selection: {
|
|
3870
|
+
anchor: to
|
|
3871
|
+
}
|
|
3872
|
+
});
|
|
3901
3873
|
}
|
|
3902
|
-
|
|
3903
|
-
|
|
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;
|
|
3874
|
+
if (state.facet(editorMode).noTabster) {
|
|
3875
|
+
rootRef.current?.removeAttribute("data-tabster");
|
|
3935
3876
|
}
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
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
|
-
""
|
|
3877
|
+
return () => {
|
|
3878
|
+
view2?.destroy();
|
|
3879
|
+
setView(null);
|
|
3880
|
+
};
|
|
3881
|
+
}, [
|
|
3882
|
+
doc,
|
|
3883
|
+
selection,
|
|
3884
|
+
extensions
|
|
3951
3885
|
]);
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
3886
|
+
const handleKeyUp = useCallback((event) => {
|
|
3887
|
+
const { key } = event;
|
|
3888
|
+
switch (key) {
|
|
3889
|
+
case "Enter": {
|
|
3890
|
+
view?.focus();
|
|
3891
|
+
break;
|
|
3892
|
+
}
|
|
3893
|
+
}
|
|
3894
|
+
}, [
|
|
3895
|
+
view
|
|
3896
|
+
]);
|
|
3897
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
3898
|
+
role: "none",
|
|
3899
|
+
ref: rootRef,
|
|
3900
|
+
tabIndex: 0,
|
|
3901
|
+
className,
|
|
3902
|
+
"data-testid": dataTestId,
|
|
3903
|
+
...tabsterDOMAttribute,
|
|
3904
|
+
onKeyUp: handleKeyUp
|
|
3905
|
+
});
|
|
3906
|
+
});
|
|
3974
3907
|
|
|
3975
|
-
// packages/ui/react-ui-editor/src/
|
|
3976
|
-
import
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
3908
|
+
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
3909
|
+
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";
|
|
3910
|
+
import { createContext } from "@radix-ui/react-context";
|
|
3911
|
+
import React2, { useRef as useRef2, useState as useState3 } from "react";
|
|
3912
|
+
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
3913
|
+
import { getSize } from "@dxos/react-ui-theme";
|
|
3914
|
+
var tooltipProps = {
|
|
3915
|
+
side: "top",
|
|
3916
|
+
classNames: "z-10"
|
|
3917
|
+
};
|
|
3918
|
+
var HeadingIcons = {
|
|
3919
|
+
"0": Paragraph,
|
|
3920
|
+
"1": TextHOne,
|
|
3921
|
+
"2": TextHTwo,
|
|
3922
|
+
"3": TextHThree,
|
|
3923
|
+
"4": TextHFour,
|
|
3924
|
+
"5": TextHFive,
|
|
3925
|
+
"6": TextHSix
|
|
3926
|
+
};
|
|
3927
|
+
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
3928
|
+
var ToolbarRoot = ({ children, onAction, classNames, state }) => {
|
|
3929
|
+
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
3930
|
+
onAction,
|
|
3931
|
+
state
|
|
3932
|
+
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
3933
|
+
density: "fine"
|
|
3934
|
+
}, /* @__PURE__ */ React2.createElement(ElevationProvider, {
|
|
3935
|
+
elevation: "chrome"
|
|
3936
|
+
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.Root, {
|
|
3937
|
+
classNames: [
|
|
3938
|
+
"is-full shrink-0 overflow-x-auto p-1",
|
|
3939
|
+
classNames
|
|
3940
|
+
]
|
|
3941
|
+
}, children))));
|
|
3942
|
+
};
|
|
3943
|
+
var buttonStyles = "min-bs-0 p-2";
|
|
3944
|
+
var iconStyles = getSize(5);
|
|
3945
|
+
var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
3946
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
3947
|
+
asChild: true
|
|
3948
|
+
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
|
|
3949
|
+
variant: "ghost",
|
|
3950
|
+
...props,
|
|
3951
|
+
classNames: buttonStyles
|
|
3952
|
+
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
3953
|
+
className: iconStyles
|
|
3954
|
+
}), /* @__PURE__ */ React2.createElement("span", {
|
|
3955
|
+
className: "sr-only"
|
|
3956
|
+
}, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
3957
|
+
};
|
|
3958
|
+
var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3959
|
+
role: "separator",
|
|
3960
|
+
className: "grow"
|
|
3961
|
+
});
|
|
3962
|
+
var MarkdownHeading = () => {
|
|
3963
|
+
const { t } = useTranslation(translationKey);
|
|
3964
|
+
const { onAction, state } = useToolbarContext("MarkdownFormatting");
|
|
3965
|
+
const blockType = state ? state.blockType : "paragraph";
|
|
3966
|
+
const header = blockType && /heading(\d)/.exec(blockType);
|
|
3967
|
+
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
3968
|
+
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
3969
|
+
const suppressNextTooltip = useRef2(false);
|
|
3970
|
+
const [tooltipOpen, setTooltipOpen] = useState3(false);
|
|
3971
|
+
const [selectOpen, setSelectOpen] = useState3(false);
|
|
3972
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
|
|
3973
|
+
open: tooltipOpen,
|
|
3974
|
+
onOpenChange: (nextOpen) => {
|
|
3975
|
+
if (nextOpen && suppressNextTooltip.current) {
|
|
3976
|
+
suppressNextTooltip.current = false;
|
|
3977
|
+
return setTooltipOpen(false);
|
|
3978
|
+
} else {
|
|
3979
|
+
return setTooltipOpen(nextOpen);
|
|
3980
|
+
}
|
|
3981
|
+
}
|
|
3982
|
+
}, /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
3983
|
+
disabled: value === null,
|
|
3984
|
+
value: value ?? "0",
|
|
3985
|
+
open: selectOpen,
|
|
3986
|
+
onOpenChange: (nextOpen) => {
|
|
3987
|
+
if (!nextOpen) {
|
|
3988
|
+
suppressNextTooltip.current = true;
|
|
3989
|
+
}
|
|
3990
|
+
return setSelectOpen(nextOpen);
|
|
3991
|
+
},
|
|
3992
|
+
onValueChange: (value2) => onAction?.({
|
|
3993
|
+
type: "heading",
|
|
3994
|
+
data: parseInt(value2)
|
|
3995
|
+
})
|
|
3996
|
+
}, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
3997
|
+
asChild: true
|
|
3998
|
+
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
|
|
3999
|
+
asChild: true
|
|
4000
|
+
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
4001
|
+
variant: "ghost",
|
|
4002
|
+
classNames: buttonStyles
|
|
4003
|
+
}, /* @__PURE__ */ React2.createElement("span", {
|
|
4004
|
+
className: "sr-only"
|
|
4005
|
+
}, t("heading label")), /* @__PURE__ */ React2.createElement(HeadingIcon, {
|
|
4006
|
+
className: iconStyles
|
|
4007
|
+
})))), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.ScrollUpButton, null), /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
4008
|
+
value: "0"
|
|
4009
|
+
}, /* @__PURE__ */ React2.createElement(Paragraph, {
|
|
4010
|
+
className: iconStyles
|
|
4011
|
+
})), [
|
|
4012
|
+
1,
|
|
4013
|
+
2,
|
|
4014
|
+
3,
|
|
4015
|
+
4,
|
|
4016
|
+
5,
|
|
4017
|
+
6
|
|
4018
|
+
].map((level) => /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
4019
|
+
key: level,
|
|
4020
|
+
value: String(level)
|
|
4021
|
+
}, level === 1 && /* @__PURE__ */ React2.createElement(TextHOne, {
|
|
4022
|
+
className: iconStyles
|
|
4023
|
+
}), level === 2 && /* @__PURE__ */ React2.createElement(TextHTwo, {
|
|
4024
|
+
className: iconStyles
|
|
4025
|
+
}), level === 3 && /* @__PURE__ */ React2.createElement(TextHThree, {
|
|
4026
|
+
className: iconStyles
|
|
4027
|
+
}), level === 4 && /* @__PURE__ */ React2.createElement(TextHFour, {
|
|
4028
|
+
className: iconStyles
|
|
4029
|
+
}), level === 5 && /* @__PURE__ */ React2.createElement(TextHFive, {
|
|
4030
|
+
className: iconStyles
|
|
4031
|
+
}), level === 6 && /* @__PURE__ */ React2.createElement(TextHSix, {
|
|
4032
|
+
className: iconStyles
|
|
4033
|
+
})))), /* @__PURE__ */ React2.createElement(Select.ScrollDownButton, null), /* @__PURE__ */ React2.createElement(Select.Arrow, null)))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4034
|
+
};
|
|
4035
|
+
var markdownStyles = [
|
|
4036
|
+
{
|
|
4037
|
+
type: "strong",
|
|
4038
|
+
Icon: TextB,
|
|
4039
|
+
getState: (state) => state.strong
|
|
4026
4040
|
},
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
borderLeft: "2px solid black"
|
|
4041
|
+
{
|
|
4042
|
+
type: "emphasis",
|
|
4043
|
+
Icon: TextItalic,
|
|
4044
|
+
getState: (state) => state.emphasis
|
|
4032
4045
|
},
|
|
4033
|
-
|
|
4034
|
-
|
|
4046
|
+
{
|
|
4047
|
+
type: "strikethrough",
|
|
4048
|
+
Icon: TextStrikethrough,
|
|
4049
|
+
getState: (state) => state.strikethrough
|
|
4035
4050
|
},
|
|
4036
|
-
|
|
4037
|
-
|
|
4051
|
+
{
|
|
4052
|
+
type: "code",
|
|
4053
|
+
Icon: Code,
|
|
4054
|
+
getState: (state) => state.code
|
|
4038
4055
|
},
|
|
4039
|
-
|
|
4040
|
-
|
|
4056
|
+
{
|
|
4057
|
+
type: "link",
|
|
4058
|
+
Icon: Link,
|
|
4059
|
+
getState: (state) => state.link
|
|
4060
|
+
}
|
|
4061
|
+
];
|
|
4062
|
+
var MarkdownStyles = () => {
|
|
4063
|
+
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4064
|
+
const { t } = useTranslation(translationKey);
|
|
4065
|
+
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4066
|
+
type: "multiple",
|
|
4067
|
+
value: markdownStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)
|
|
4068
|
+
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4069
|
+
key: type,
|
|
4070
|
+
value: type,
|
|
4071
|
+
Icon,
|
|
4072
|
+
disabled: state?.blockType === "codeblock",
|
|
4073
|
+
onClick: state ? () => onAction?.({
|
|
4074
|
+
type,
|
|
4075
|
+
data: !getState(state)
|
|
4076
|
+
}) : void 0
|
|
4077
|
+
}, t(`${type} label`))));
|
|
4078
|
+
};
|
|
4079
|
+
var markdownLists = [
|
|
4080
|
+
{
|
|
4081
|
+
type: "list-bullet",
|
|
4082
|
+
Icon: ListBullets,
|
|
4083
|
+
getState: (state) => state.listStyle === "bullet"
|
|
4041
4084
|
},
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
paddingInline: 0
|
|
4085
|
+
{
|
|
4086
|
+
type: "list-ordered",
|
|
4087
|
+
Icon: ListNumbers,
|
|
4088
|
+
getState: (state) => state.listStyle === "ordered"
|
|
4047
4089
|
},
|
|
4048
|
-
|
|
4090
|
+
{
|
|
4091
|
+
type: "list-task",
|
|
4092
|
+
Icon: ListChecks,
|
|
4093
|
+
getState: (state) => state.listStyle === "task"
|
|
4094
|
+
}
|
|
4095
|
+
];
|
|
4096
|
+
var MarkdownLists = () => {
|
|
4097
|
+
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4098
|
+
const { t } = useTranslation(translationKey);
|
|
4099
|
+
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4100
|
+
type: "single",
|
|
4101
|
+
value: state?.listStyle ? `list-${state.listStyle}` : ""
|
|
4102
|
+
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4103
|
+
key: type,
|
|
4104
|
+
value: type,
|
|
4105
|
+
Icon,
|
|
4106
|
+
onClick: state ? () => onAction?.({
|
|
4107
|
+
type,
|
|
4108
|
+
data: !getState(state)
|
|
4109
|
+
}) : void 0
|
|
4110
|
+
}, t(`${type} label`))));
|
|
4111
|
+
};
|
|
4112
|
+
var markdownBlocks = [
|
|
4113
|
+
{
|
|
4114
|
+
type: "blockquote",
|
|
4115
|
+
Icon: Quotes,
|
|
4116
|
+
getState: (state) => state.blockQuote
|
|
4117
|
+
},
|
|
4118
|
+
{
|
|
4119
|
+
type: "codeblock",
|
|
4120
|
+
Icon: CodeBlock,
|
|
4121
|
+
getState: (state) => state.blockType === "codeblock"
|
|
4122
|
+
},
|
|
4123
|
+
{
|
|
4124
|
+
type: "table",
|
|
4125
|
+
Icon: Table2,
|
|
4126
|
+
getState: (state) => state.blockType === "tablecell",
|
|
4127
|
+
disabled: (state) => !state.blankLine
|
|
4128
|
+
}
|
|
4129
|
+
];
|
|
4130
|
+
var MarkdownBlocks = () => {
|
|
4131
|
+
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4132
|
+
const { t } = useTranslation(translationKey);
|
|
4133
|
+
const value = markdownBlocks.find(({ getState }) => state && getState(state));
|
|
4134
|
+
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4135
|
+
type: "single",
|
|
4136
|
+
value: value?.type ?? ""
|
|
4137
|
+
}, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4138
|
+
key: type,
|
|
4139
|
+
value: type,
|
|
4140
|
+
Icon,
|
|
4141
|
+
disabled: !state || disabled?.(state),
|
|
4142
|
+
onClick: state ? () => onAction?.({
|
|
4143
|
+
type,
|
|
4144
|
+
data: !getState(state)
|
|
4145
|
+
}) : void 0
|
|
4146
|
+
}, t(`${type} label`))));
|
|
4147
|
+
};
|
|
4148
|
+
var MarkdownStandard = () => /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(MarkdownHeading, null), /* @__PURE__ */ React2.createElement(MarkdownStyles, null), /* @__PURE__ */ React2.createElement(MarkdownLists, null), /* @__PURE__ */ React2.createElement(MarkdownBlocks, null));
|
|
4149
|
+
var MarkdownExtended = () => {
|
|
4150
|
+
const { onAction } = useToolbarContext("MarkdownStyles");
|
|
4151
|
+
const { t } = useTranslation(translationKey);
|
|
4152
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4153
|
+
asChild: true
|
|
4154
|
+
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
|
|
4155
|
+
variant: "ghost",
|
|
4156
|
+
"data-testid": "editor.toolbar.comment",
|
|
4157
|
+
onClick: () => onAction?.({
|
|
4158
|
+
type: "comment"
|
|
4159
|
+
}),
|
|
4160
|
+
classNames: buttonStyles
|
|
4161
|
+
}, /* @__PURE__ */ React2.createElement(ChatText, {
|
|
4162
|
+
className: iconStyles
|
|
4163
|
+
}), /* @__PURE__ */ React2.createElement("span", {
|
|
4164
|
+
className: "sr-only"
|
|
4165
|
+
}, t("comment label")))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("comment label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4166
|
+
};
|
|
4167
|
+
var Toolbar = {
|
|
4168
|
+
Root: ToolbarRoot,
|
|
4169
|
+
Button: ToolbarButton,
|
|
4170
|
+
Separator: ToolbarSeparator,
|
|
4171
|
+
Markdown: MarkdownStandard,
|
|
4172
|
+
Extended: MarkdownExtended
|
|
4173
|
+
};
|
|
4174
|
+
|
|
4175
|
+
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
4176
|
+
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
4177
|
+
import { Context as Context2 } from "@dxos/context";
|
|
4178
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
4179
|
+
import { log as log8 } from "@dxos/log";
|
|
4180
|
+
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
|
|
4181
|
+
var DEBOUNCE_INTERVAL = 100;
|
|
4182
|
+
var SpaceAwarenessProvider = class {
|
|
4183
|
+
constructor(params) {
|
|
4184
|
+
this._remoteStates = /* @__PURE__ */ new Map();
|
|
4185
|
+
this.remoteStateChange = new Event2();
|
|
4186
|
+
this._space = params.space;
|
|
4187
|
+
this._channel = params.channel;
|
|
4188
|
+
this._peerId = params.peerId;
|
|
4189
|
+
this._info = params.info;
|
|
4190
|
+
}
|
|
4191
|
+
open() {
|
|
4192
|
+
this._ctx = new Context2();
|
|
4193
|
+
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
4194
|
+
if (this._localState) {
|
|
4195
|
+
await this._space.postMessage(this._channel, {
|
|
4196
|
+
kind: "post",
|
|
4197
|
+
state: this._localState
|
|
4198
|
+
});
|
|
4199
|
+
await sleep(DEBOUNCE_INTERVAL);
|
|
4200
|
+
}
|
|
4201
|
+
});
|
|
4202
|
+
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
4203
|
+
switch (message.payload.kind) {
|
|
4204
|
+
case "query": {
|
|
4205
|
+
this._handleQueryMessage();
|
|
4206
|
+
break;
|
|
4207
|
+
}
|
|
4208
|
+
case "post": {
|
|
4209
|
+
this._handlePostMessage(message.payload);
|
|
4210
|
+
break;
|
|
4211
|
+
}
|
|
4212
|
+
}
|
|
4213
|
+
}));
|
|
4214
|
+
void this._space.postMessage(this._channel, {
|
|
4215
|
+
kind: "query"
|
|
4216
|
+
}).catch((err) => {
|
|
4217
|
+
log8.debug("failed to query awareness", {
|
|
4218
|
+
err
|
|
4219
|
+
}, {
|
|
4220
|
+
F: __dxlog_file10,
|
|
4221
|
+
L: 89,
|
|
4222
|
+
S: this,
|
|
4223
|
+
C: (f, a) => f(...a)
|
|
4224
|
+
});
|
|
4225
|
+
});
|
|
4226
|
+
}
|
|
4227
|
+
close() {
|
|
4228
|
+
void this._ctx?.dispose();
|
|
4229
|
+
this._ctx = void 0;
|
|
4230
|
+
this._postTask = void 0;
|
|
4231
|
+
}
|
|
4232
|
+
getRemoteStates() {
|
|
4233
|
+
return Array.from(this._remoteStates.values());
|
|
4234
|
+
}
|
|
4235
|
+
update(position) {
|
|
4236
|
+
invariant3(this._postTask, void 0, {
|
|
4237
|
+
F: __dxlog_file10,
|
|
4238
|
+
L: 104,
|
|
4239
|
+
S: this,
|
|
4240
|
+
A: [
|
|
4241
|
+
"this._postTask",
|
|
4242
|
+
""
|
|
4243
|
+
]
|
|
4244
|
+
});
|
|
4245
|
+
this._localState = {
|
|
4246
|
+
peerId: this._peerId,
|
|
4247
|
+
position,
|
|
4248
|
+
info: this._info
|
|
4249
|
+
};
|
|
4250
|
+
this._postTask.schedule();
|
|
4251
|
+
}
|
|
4252
|
+
_handleQueryMessage() {
|
|
4253
|
+
invariant3(this._postTask, void 0, {
|
|
4254
|
+
F: __dxlog_file10,
|
|
4255
|
+
L: 115,
|
|
4256
|
+
S: this,
|
|
4257
|
+
A: [
|
|
4258
|
+
"this._postTask",
|
|
4259
|
+
""
|
|
4260
|
+
]
|
|
4261
|
+
});
|
|
4262
|
+
this._postTask.schedule();
|
|
4263
|
+
}
|
|
4264
|
+
_handlePostMessage(message) {
|
|
4265
|
+
invariant3(message.kind === "post", void 0, {
|
|
4266
|
+
F: __dxlog_file10,
|
|
4267
|
+
L: 120,
|
|
4268
|
+
S: this,
|
|
4269
|
+
A: [
|
|
4270
|
+
"message.kind === 'post'",
|
|
4271
|
+
""
|
|
4272
|
+
]
|
|
4273
|
+
});
|
|
4274
|
+
this._remoteStates.set(message.state.peerId, message.state);
|
|
4275
|
+
this.remoteStateChange.emit();
|
|
4276
|
+
}
|
|
4277
|
+
};
|
|
4278
|
+
|
|
4279
|
+
// packages/ui/react-ui-editor/src/hooks/extension-utils.ts
|
|
4280
|
+
import { closeBrackets } from "@codemirror/autocomplete";
|
|
4281
|
+
import { history } from "@codemirror/commands";
|
|
4282
|
+
import { bracketMatching } from "@codemirror/language";
|
|
4283
|
+
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
4284
|
+
import { EditorView as EditorView16, crosshairCursor, drawSelection, dropCursor, highlightActiveLine, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
|
4285
|
+
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
4286
|
+
import { useMemo as useMemo2 } from "react";
|
|
4287
|
+
import { generateName } from "@dxos/display-name";
|
|
4288
|
+
import { createDocAccessor, getTextContent } from "@dxos/echo-schema";
|
|
4289
|
+
import { log as log9 } from "@dxos/log";
|
|
4290
|
+
import { hueTokens } from "@dxos/react-ui-theme";
|
|
4291
|
+
import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
4292
|
+
|
|
4293
|
+
// packages/ui/react-ui-editor/src/themes/default.ts
|
|
4294
|
+
import get3 from "lodash.get";
|
|
4295
|
+
var defaultTheme = {
|
|
4296
|
+
//
|
|
4297
|
+
// Main layout:
|
|
4298
|
+
// https://codemirror.net/examples/styling
|
|
4299
|
+
//
|
|
4300
|
+
// <div class="cm-editor [cm-focused] [generated classes]">
|
|
4301
|
+
// <div class="cm-scroller">
|
|
4302
|
+
// <div class="cm-gutters">
|
|
4303
|
+
// <div class="cm-gutter [...]">
|
|
4304
|
+
// <div class="cm-gutterElement">...</div>
|
|
4305
|
+
// </div>
|
|
4306
|
+
// </div>
|
|
4307
|
+
// <div class="cm-content" role="textbox" contenteditable="true">
|
|
4308
|
+
// <div class="cm-line"></div>
|
|
4309
|
+
// </div>
|
|
4310
|
+
// <div class="cm-selectionLayer">
|
|
4311
|
+
// <div class="cm-selectionBackground"></div>
|
|
4312
|
+
// </div>
|
|
4313
|
+
// <div class="cm-cursorLayer">
|
|
4314
|
+
// <div class="cm-cursor"></div>
|
|
4315
|
+
// </div>
|
|
4316
|
+
// </div>
|
|
4317
|
+
// </div>
|
|
4318
|
+
//
|
|
4319
|
+
"&": {},
|
|
4320
|
+
"&.cm-focused": {
|
|
4321
|
+
outline: "none"
|
|
4322
|
+
},
|
|
4323
|
+
// NOTE: See https://codemirror.net/docs/guide (DOM Structure).
|
|
4324
|
+
".cm-scroller": {
|
|
4325
|
+
// TODO(burdon): Reconcile with docs: https://codemirror.net/docs/guide
|
|
4326
|
+
// 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.
|
|
4327
|
+
overflowY: "auto",
|
|
4328
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(","),
|
|
4329
|
+
lineHeight: 1.5
|
|
4330
|
+
},
|
|
4331
|
+
".cm-content": {
|
|
4332
|
+
// TODO(burdon): Is it possible to remove the padding value from CM's default theme?
|
|
4333
|
+
// padding: 'unset',
|
|
4334
|
+
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
|
4335
|
+
fontSize: "16px"
|
|
4336
|
+
},
|
|
4337
|
+
"&light .cm-content": {
|
|
4338
|
+
color: get3(tokens, "extend.semanticColors.base.fg.light", "black"),
|
|
4339
|
+
caretColor: "black"
|
|
4340
|
+
},
|
|
4341
|
+
"&dark .cm-content": {
|
|
4342
|
+
color: get3(tokens, "extend.semanticColors.base.fg.dark", "white"),
|
|
4343
|
+
caretColor: "white"
|
|
4344
|
+
},
|
|
4345
|
+
//
|
|
4346
|
+
// Cursor
|
|
4347
|
+
//
|
|
4348
|
+
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
4349
|
+
borderLeft: "2px solid black"
|
|
4350
|
+
},
|
|
4351
|
+
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
4352
|
+
borderLeft: "2px solid white"
|
|
4353
|
+
},
|
|
4354
|
+
"&light .cm-placeholder": {
|
|
4355
|
+
color: get3(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
4356
|
+
},
|
|
4357
|
+
"&dark .cm-placeholder": {
|
|
4358
|
+
color: get3(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
4359
|
+
},
|
|
4360
|
+
//
|
|
4361
|
+
// line
|
|
4362
|
+
//
|
|
4363
|
+
".cm-line": {
|
|
4364
|
+
paddingInline: 0
|
|
4365
|
+
},
|
|
4366
|
+
".cm-activeLine": {
|
|
4049
4367
|
background: "transparent"
|
|
4050
4368
|
},
|
|
4051
4369
|
//
|
|
@@ -4058,36 +4376,36 @@ var defaultTheme = {
|
|
|
4058
4376
|
// Selection
|
|
4059
4377
|
//
|
|
4060
4378
|
"&light .cm-selectionBackground": {
|
|
4061
|
-
background:
|
|
4379
|
+
background: get3(tokens, "extend.colors.primary.100")
|
|
4062
4380
|
},
|
|
4063
4381
|
"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
4064
|
-
background:
|
|
4382
|
+
background: get3(tokens, "extend.colors.primary.200")
|
|
4065
4383
|
},
|
|
4066
4384
|
"&dark .cm-selectionBackground": {
|
|
4067
|
-
background:
|
|
4385
|
+
background: get3(tokens, "extend.colors.primary.700")
|
|
4068
4386
|
},
|
|
4069
4387
|
"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
4070
|
-
background:
|
|
4388
|
+
background: get3(tokens, "extend.colors.primary.600")
|
|
4071
4389
|
},
|
|
4072
4390
|
//
|
|
4073
4391
|
// Search
|
|
4074
4392
|
//
|
|
4075
4393
|
"&light .cm-searchMatch": {
|
|
4076
|
-
backgroundColor:
|
|
4394
|
+
backgroundColor: get3(tokens, "extend.colors.yellow.100")
|
|
4077
4395
|
},
|
|
4078
4396
|
"&dark .cm-searchMatch": {
|
|
4079
|
-
backgroundColor:
|
|
4397
|
+
backgroundColor: get3(tokens, "extend.colors.yellow.700")
|
|
4080
4398
|
},
|
|
4081
4399
|
//
|
|
4082
4400
|
// link
|
|
4083
4401
|
//
|
|
4084
4402
|
".cm-link": {
|
|
4085
|
-
color:
|
|
4403
|
+
color: get3(tokens, "extend.colors.primary.500"),
|
|
4086
4404
|
textDecorationLine: "underline",
|
|
4087
4405
|
textDecorationThickness: "1px",
|
|
4088
4406
|
textUnderlineOffset: "2px",
|
|
4089
4407
|
borderRadius: ".125rem",
|
|
4090
|
-
fontFamily:
|
|
4408
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
4091
4409
|
},
|
|
4092
4410
|
//
|
|
4093
4411
|
// tooltip
|
|
@@ -4110,7 +4428,7 @@ var defaultTheme = {
|
|
|
4110
4428
|
display: "none"
|
|
4111
4429
|
},
|
|
4112
4430
|
".cm-completionLabel": {
|
|
4113
|
-
fontFamily:
|
|
4431
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
4114
4432
|
},
|
|
4115
4433
|
".cm-completionMatchedText": {
|
|
4116
4434
|
textDecoration: "none"
|
|
@@ -4119,15 +4437,15 @@ var defaultTheme = {
|
|
|
4119
4437
|
// table
|
|
4120
4438
|
//
|
|
4121
4439
|
".cm-table *": {
|
|
4122
|
-
fontFamily: `${
|
|
4440
|
+
fontFamily: `${get3(tokens, "fontFamily.mono", []).join(",")} !important`,
|
|
4123
4441
|
textDecoration: "none !important"
|
|
4124
4442
|
},
|
|
4125
4443
|
".cm-table-head": {
|
|
4126
4444
|
padding: "2px 16px 2px 0px",
|
|
4127
|
-
borderBottom: `1px solid ${
|
|
4445
|
+
borderBottom: `1px solid ${get3(tokens, "extend.colors.neutral.500")}`,
|
|
4128
4446
|
fontWeight: 100,
|
|
4129
4447
|
textAlign: "left",
|
|
4130
|
-
color:
|
|
4448
|
+
color: get3(tokens, "extend.colors.neutral.500")
|
|
4131
4449
|
},
|
|
4132
4450
|
".cm-table-cell": {
|
|
4133
4451
|
padding: "2px 16px 2px 0px"
|
|
@@ -4174,738 +4492,265 @@ var defaultTheme = {
|
|
|
4174
4492
|
* </div
|
|
4175
4493
|
*/
|
|
4176
4494
|
".cm-panels": {
|
|
4177
|
-
border: `1px solid ${
|
|
4495
|
+
border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`
|
|
4178
4496
|
},
|
|
4179
4497
|
".cm-panel": {
|
|
4180
|
-
background:
|
|
4181
|
-
fontFamily:
|
|
4498
|
+
background: get3(tokens, "extend.colors.neutral.50"),
|
|
4499
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
4182
4500
|
},
|
|
4183
4501
|
".cm-button": {
|
|
4184
4502
|
margin: "4px",
|
|
4185
|
-
fontFamily:
|
|
4186
|
-
background:
|
|
4503
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(","),
|
|
4504
|
+
background: get3(tokens, "extend.colors.neutral.100"),
|
|
4187
4505
|
backgroundImage: "none",
|
|
4188
4506
|
border: "none",
|
|
4189
4507
|
"&:hover": {
|
|
4190
|
-
background:
|
|
4508
|
+
background: get3(tokens, "extend.colors.neutral.200")
|
|
4191
4509
|
},
|
|
4192
4510
|
"&:active": {
|
|
4193
|
-
background:
|
|
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, {
|
|
4476
|
-
F: __dxlog_file11,
|
|
4477
|
-
L: 123,
|
|
4478
|
-
S: void 0,
|
|
4479
|
-
C: (f, a) => f(...a)
|
|
4480
|
-
});
|
|
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(),
|
|
4495
|
-
// Focus.
|
|
4496
|
-
EditorView17.updateListener.of((update2) => {
|
|
4497
|
-
update2.transactions.forEach((transaction) => {
|
|
4498
|
-
if (transaction.isUserEvent("focus.container")) {
|
|
4499
|
-
rootRef.current?.focus();
|
|
4500
|
-
}
|
|
4501
|
-
});
|
|
4502
|
-
}),
|
|
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)
|
|
4512
|
-
});
|
|
4513
|
-
const view2 = new EditorView17({
|
|
4514
|
-
state,
|
|
4515
|
-
parent: rootRef.current,
|
|
4516
|
-
scrollTo,
|
|
4517
|
-
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4518
|
-
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4519
|
-
dispatchTransactions: (trs, view3) => {
|
|
4520
|
-
if (debug) {
|
|
4521
|
-
logChanges(trs);
|
|
4522
|
-
}
|
|
4523
|
-
view3.update(trs);
|
|
4524
|
-
}
|
|
4525
|
-
});
|
|
4526
|
-
setView(view2);
|
|
4527
|
-
if (moveToEndOfLine) {
|
|
4528
|
-
const { to } = view2.state.doc.lineAt(0);
|
|
4529
|
-
view2?.dispatch({
|
|
4530
|
-
selection: {
|
|
4531
|
-
anchor: to
|
|
4532
|
-
}
|
|
4533
|
-
});
|
|
4534
|
-
}
|
|
4535
|
-
if (state.facet(editorMode).noTabster) {
|
|
4536
|
-
rootRef.current.removeAttribute("data-tabster");
|
|
4537
|
-
}
|
|
4538
|
-
return () => {
|
|
4539
|
-
view2?.destroy();
|
|
4540
|
-
setView(null);
|
|
4541
|
-
};
|
|
4542
|
-
}, [
|
|
4543
|
-
rootRef,
|
|
4544
|
-
extensions,
|
|
4545
|
-
model,
|
|
4546
|
-
readonly,
|
|
4547
|
-
themeMode
|
|
4548
|
-
]);
|
|
4549
|
-
const handleKeyUp = useCallback((event) => {
|
|
4550
|
-
const { key } = event;
|
|
4551
|
-
switch (key) {
|
|
4552
|
-
case "Enter": {
|
|
4553
|
-
view?.focus();
|
|
4554
|
-
break;
|
|
4555
|
-
}
|
|
4556
|
-
}
|
|
4557
|
-
}, [
|
|
4558
|
-
view
|
|
4559
|
-
]);
|
|
4560
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
4561
|
-
role: "none",
|
|
4562
|
-
ref: rootRef,
|
|
4563
|
-
key: model.id,
|
|
4564
|
-
tabIndex: 0,
|
|
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
|
|
4618
|
-
});
|
|
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
|
-
};
|
|
4634
|
-
|
|
4635
|
-
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
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";
|
|
4637
|
-
import { createContext } from "@radix-ui/react-context";
|
|
4638
|
-
import React2, { useRef as useRef4, useState as useState6 } from "react";
|
|
4639
|
-
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
4640
|
-
import { getSize } from "@dxos/react-ui-theme";
|
|
4641
|
-
var tooltipProps = {
|
|
4642
|
-
side: "top",
|
|
4643
|
-
classNames: "z-10"
|
|
4644
|
-
};
|
|
4645
|
-
var HeadingIcons = {
|
|
4646
|
-
"0": Paragraph,
|
|
4647
|
-
"1": TextHOne,
|
|
4648
|
-
"2": TextHTwo,
|
|
4649
|
-
"3": TextHThree,
|
|
4650
|
-
"4": TextHFour,
|
|
4651
|
-
"5": TextHFive,
|
|
4652
|
-
"6": TextHSix
|
|
4653
|
-
};
|
|
4654
|
-
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
4655
|
-
var ToolbarRoot = ({ children, onAction, classNames, state }) => {
|
|
4656
|
-
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
4657
|
-
onAction,
|
|
4658
|
-
state
|
|
4659
|
-
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
4660
|
-
density: "fine"
|
|
4661
|
-
}, /* @__PURE__ */ React2.createElement(ElevationProvider, {
|
|
4662
|
-
elevation: "chrome"
|
|
4663
|
-
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.Root, {
|
|
4664
|
-
classNames: [
|
|
4665
|
-
"is-full shrink-0 overflow-x-auto p-1",
|
|
4666
|
-
classNames
|
|
4667
|
-
]
|
|
4668
|
-
}, children))));
|
|
4669
|
-
};
|
|
4670
|
-
var buttonStyles = "min-bs-0 p-2";
|
|
4671
|
-
var iconStyles = getSize(5);
|
|
4672
|
-
var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
4673
|
-
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4674
|
-
asChild: true
|
|
4675
|
-
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
|
|
4676
|
-
variant: "ghost",
|
|
4677
|
-
...props,
|
|
4678
|
-
classNames: buttonStyles
|
|
4679
|
-
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
4680
|
-
className: iconStyles
|
|
4681
|
-
}), /* @__PURE__ */ React2.createElement("span", {
|
|
4682
|
-
className: "sr-only"
|
|
4683
|
-
}, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4684
|
-
};
|
|
4685
|
-
var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
4686
|
-
role: "separator",
|
|
4687
|
-
className: "grow"
|
|
4688
|
-
});
|
|
4689
|
-
var MarkdownHeading = () => {
|
|
4690
|
-
const { t } = useTranslation(translationKey);
|
|
4691
|
-
const { onAction, state } = useToolbarContext("MarkdownFormatting");
|
|
4692
|
-
const blockType = state ? state.blockType : "paragraph";
|
|
4693
|
-
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4694
|
-
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4695
|
-
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
4696
|
-
const suppressNextTooltip = useRef4(false);
|
|
4697
|
-
const [tooltipOpen, setTooltipOpen] = useState6(false);
|
|
4698
|
-
const [selectOpen, setSelectOpen] = useState6(false);
|
|
4699
|
-
return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
|
|
4700
|
-
open: tooltipOpen,
|
|
4701
|
-
onOpenChange: (nextOpen) => {
|
|
4702
|
-
if (nextOpen && suppressNextTooltip.current) {
|
|
4703
|
-
suppressNextTooltip.current = false;
|
|
4704
|
-
return setTooltipOpen(false);
|
|
4705
|
-
} else {
|
|
4706
|
-
return setTooltipOpen(nextOpen);
|
|
4707
|
-
}
|
|
4708
|
-
}
|
|
4709
|
-
}, /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
4710
|
-
disabled: value === null,
|
|
4711
|
-
value: value ?? "0",
|
|
4712
|
-
open: selectOpen,
|
|
4713
|
-
onOpenChange: (nextOpen) => {
|
|
4714
|
-
if (!nextOpen) {
|
|
4715
|
-
suppressNextTooltip.current = true;
|
|
4716
|
-
}
|
|
4717
|
-
return setSelectOpen(nextOpen);
|
|
4718
|
-
},
|
|
4719
|
-
onValueChange: (value2) => onAction?.({
|
|
4720
|
-
type: "heading",
|
|
4721
|
-
data: parseInt(value2)
|
|
4722
|
-
})
|
|
4723
|
-
}, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4724
|
-
asChild: true
|
|
4725
|
-
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
|
|
4726
|
-
asChild: true
|
|
4727
|
-
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
4728
|
-
variant: "ghost",
|
|
4729
|
-
classNames: buttonStyles
|
|
4730
|
-
}, /* @__PURE__ */ React2.createElement("span", {
|
|
4731
|
-
className: "sr-only"
|
|
4732
|
-
}, t("heading label")), /* @__PURE__ */ React2.createElement(HeadingIcon, {
|
|
4733
|
-
className: iconStyles
|
|
4734
|
-
})))), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.ScrollUpButton, null), /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
4735
|
-
value: "0"
|
|
4736
|
-
}, /* @__PURE__ */ React2.createElement(Paragraph, {
|
|
4737
|
-
className: iconStyles
|
|
4738
|
-
})), [
|
|
4739
|
-
1,
|
|
4740
|
-
2,
|
|
4741
|
-
3,
|
|
4742
|
-
4,
|
|
4743
|
-
5,
|
|
4744
|
-
6
|
|
4745
|
-
].map((level) => /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
4746
|
-
key: level,
|
|
4747
|
-
value: String(level)
|
|
4748
|
-
}, level === 1 && /* @__PURE__ */ React2.createElement(TextHOne, {
|
|
4749
|
-
className: iconStyles
|
|
4750
|
-
}), level === 2 && /* @__PURE__ */ React2.createElement(TextHTwo, {
|
|
4751
|
-
className: iconStyles
|
|
4752
|
-
}), level === 3 && /* @__PURE__ */ React2.createElement(TextHThree, {
|
|
4753
|
-
className: iconStyles
|
|
4754
|
-
}), level === 4 && /* @__PURE__ */ React2.createElement(TextHFour, {
|
|
4755
|
-
className: iconStyles
|
|
4756
|
-
}), level === 5 && /* @__PURE__ */ React2.createElement(TextHFive, {
|
|
4757
|
-
className: iconStyles
|
|
4758
|
-
}), level === 6 && /* @__PURE__ */ React2.createElement(TextHSix, {
|
|
4759
|
-
className: iconStyles
|
|
4760
|
-
})))), /* @__PURE__ */ React2.createElement(Select.ScrollDownButton, null), /* @__PURE__ */ React2.createElement(Select.Arrow, null)))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4761
|
-
};
|
|
4762
|
-
var markdownStyles = [
|
|
4763
|
-
{
|
|
4764
|
-
type: "strong",
|
|
4765
|
-
Icon: TextB,
|
|
4766
|
-
getState: (state) => state.strong
|
|
4767
|
-
},
|
|
4768
|
-
{
|
|
4769
|
-
type: "emphasis",
|
|
4770
|
-
Icon: TextItalic,
|
|
4771
|
-
getState: (state) => state.emphasis
|
|
4772
|
-
},
|
|
4773
|
-
{
|
|
4774
|
-
type: "strikethrough",
|
|
4775
|
-
Icon: TextStrikethrough,
|
|
4776
|
-
getState: (state) => state.strikethrough
|
|
4777
|
-
},
|
|
4778
|
-
{
|
|
4779
|
-
type: "code",
|
|
4780
|
-
Icon: Code,
|
|
4781
|
-
getState: (state) => state.code
|
|
4782
|
-
},
|
|
4783
|
-
{
|
|
4784
|
-
type: "link",
|
|
4785
|
-
Icon: Link,
|
|
4786
|
-
getState: (state) => state.link
|
|
4787
|
-
}
|
|
4788
|
-
];
|
|
4789
|
-
var MarkdownStyles = () => {
|
|
4790
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4791
|
-
const { t } = useTranslation(translationKey);
|
|
4792
|
-
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4793
|
-
type: "multiple",
|
|
4794
|
-
value: markdownStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)
|
|
4795
|
-
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4796
|
-
key: type,
|
|
4797
|
-
value: type,
|
|
4798
|
-
Icon,
|
|
4799
|
-
disabled: state?.blockType === "codeblock",
|
|
4800
|
-
onClick: state ? () => onAction?.({
|
|
4801
|
-
type,
|
|
4802
|
-
data: !getState(state)
|
|
4803
|
-
}) : void 0
|
|
4804
|
-
}, t(`${type} label`))));
|
|
4805
|
-
};
|
|
4806
|
-
var markdownLists = [
|
|
4807
|
-
{
|
|
4808
|
-
type: "list-bullet",
|
|
4809
|
-
Icon: ListBullets,
|
|
4810
|
-
getState: (state) => state.listStyle === "bullet"
|
|
4811
|
-
},
|
|
4812
|
-
{
|
|
4813
|
-
type: "list-ordered",
|
|
4814
|
-
Icon: ListNumbers,
|
|
4815
|
-
getState: (state) => state.listStyle === "ordered"
|
|
4511
|
+
background: get3(tokens, "extend.colors.neutral.300"),
|
|
4512
|
+
backgroundImage: "none"
|
|
4513
|
+
}
|
|
4816
4514
|
},
|
|
4817
|
-
{
|
|
4818
|
-
|
|
4819
|
-
Icon: ListChecks,
|
|
4820
|
-
getState: (state) => state.listStyle === "task"
|
|
4515
|
+
".cm-panel input[type=checkbox]": {
|
|
4516
|
+
marginRight: "0.4rem !important"
|
|
4821
4517
|
}
|
|
4822
|
-
];
|
|
4823
|
-
var MarkdownLists = () => {
|
|
4824
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4825
|
-
const { t } = useTranslation(translationKey);
|
|
4826
|
-
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4827
|
-
type: "single",
|
|
4828
|
-
value: state?.listStyle ? `list-${state.listStyle}` : ""
|
|
4829
|
-
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4830
|
-
key: type,
|
|
4831
|
-
value: type,
|
|
4832
|
-
Icon,
|
|
4833
|
-
onClick: state ? () => onAction?.({
|
|
4834
|
-
type,
|
|
4835
|
-
data: !getState(state)
|
|
4836
|
-
}) : void 0
|
|
4837
|
-
}, t(`${type} label`))));
|
|
4838
4518
|
};
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4519
|
+
|
|
4520
|
+
// packages/ui/react-ui-editor/src/hooks/extension-utils.ts
|
|
4521
|
+
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/extension-utils.ts";
|
|
4522
|
+
var defaults = {
|
|
4523
|
+
bracketMatching: true,
|
|
4524
|
+
closeBrackets: true,
|
|
4525
|
+
drawSelection: true,
|
|
4526
|
+
editable: true,
|
|
4527
|
+
history: true,
|
|
4528
|
+
lineWrapping: true
|
|
4529
|
+
};
|
|
4530
|
+
var createBasicExtensions = (_props) => {
|
|
4531
|
+
const props = defaultsDeep2({}, _props, defaults);
|
|
4532
|
+
return [
|
|
4533
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4534
|
+
EditorView16.exceptionSink.of((err) => {
|
|
4535
|
+
log9.catch(err, void 0, {
|
|
4536
|
+
F: __dxlog_file11,
|
|
4537
|
+
L: 79,
|
|
4538
|
+
S: void 0,
|
|
4539
|
+
C: (f, a) => f(...a)
|
|
4540
|
+
});
|
|
4541
|
+
}),
|
|
4542
|
+
props.allowMultipleSelections && EditorState2.allowMultipleSelections.of(true),
|
|
4543
|
+
props.bracketMatching && bracketMatching(),
|
|
4544
|
+
props.closeBrackets && closeBrackets(),
|
|
4545
|
+
props.crosshairCursor && crosshairCursor(),
|
|
4546
|
+
props.dropCursor && dropCursor(),
|
|
4547
|
+
props.drawSelection && drawSelection(),
|
|
4548
|
+
props.highlightActiveLine && highlightActiveLine(),
|
|
4549
|
+
props.history && history(),
|
|
4550
|
+
props.lineNumbers && lineNumbers(),
|
|
4551
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
4552
|
+
props.placeholder && placeholder(props.placeholder),
|
|
4553
|
+
props.readonly && [
|
|
4554
|
+
EditorState2.readOnly.of(true),
|
|
4555
|
+
EditorView16.editable.of(false)
|
|
4556
|
+
],
|
|
4557
|
+
props.scrollPastEnd && scrollPastEnd(),
|
|
4558
|
+
props.tabSize && EditorState2.tabSize.of(props.tabSize)
|
|
4559
|
+
].filter(isNotFalsy3);
|
|
4560
|
+
};
|
|
4561
|
+
var defaultSlots = {
|
|
4562
|
+
editor: {
|
|
4563
|
+
className: "w-full bs-full"
|
|
4849
4564
|
},
|
|
4850
|
-
{
|
|
4851
|
-
|
|
4852
|
-
Icon: Table2,
|
|
4853
|
-
getState: (state) => state.blockType === "tablecell",
|
|
4854
|
-
disabled: (state) => !state.blankLine
|
|
4565
|
+
content: {
|
|
4566
|
+
className: "!p-2"
|
|
4855
4567
|
}
|
|
4856
|
-
];
|
|
4857
|
-
var MarkdownBlocks = () => {
|
|
4858
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
|
4859
|
-
const { t } = useTranslation(translationKey);
|
|
4860
|
-
const value = markdownBlocks.find(({ getState }) => state && getState(state));
|
|
4861
|
-
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4862
|
-
type: "single",
|
|
4863
|
-
value: value?.type ?? ""
|
|
4864
|
-
}, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4865
|
-
key: type,
|
|
4866
|
-
value: type,
|
|
4867
|
-
Icon,
|
|
4868
|
-
disabled: !state || disabled?.(state),
|
|
4869
|
-
onClick: state ? () => onAction?.({
|
|
4870
|
-
type,
|
|
4871
|
-
data: !getState(state)
|
|
4872
|
-
}) : void 0
|
|
4873
|
-
}, t(`${type} label`))));
|
|
4874
4568
|
};
|
|
4875
|
-
var
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
"data-testid": "editor.toolbar.comment",
|
|
4884
|
-
onClick: () => onAction?.({
|
|
4885
|
-
type: "comment"
|
|
4569
|
+
var createThemeExtensions = ({ theme, themeMode, slots: _slots } = {}) => {
|
|
4570
|
+
const slots = defaultsDeep2({}, _slots, defaultSlots);
|
|
4571
|
+
return [
|
|
4572
|
+
EditorView16.baseTheme(defaultTheme),
|
|
4573
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
4574
|
+
theme && EditorView16.theme(theme),
|
|
4575
|
+
slots.editor?.className && EditorView16.editorAttributes.of({
|
|
4576
|
+
class: slots.editor.className
|
|
4886
4577
|
}),
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
className: "sr-only"
|
|
4892
|
-
}, t("comment label")))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("comment label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4578
|
+
slots.content?.className && EditorView16.contentAttributes.of({
|
|
4579
|
+
class: slots.content.className
|
|
4580
|
+
})
|
|
4581
|
+
].filter(isNotFalsy3);
|
|
4893
4582
|
};
|
|
4894
|
-
var
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4583
|
+
var createDataExtensions = ({ id, text, space, identity }) => {
|
|
4584
|
+
const extensions = [
|
|
4585
|
+
automerge(text)
|
|
4586
|
+
];
|
|
4587
|
+
if (space && identity) {
|
|
4588
|
+
const peerId = identity?.identityKey.toHex();
|
|
4589
|
+
const { cursorLightValue, cursorDarkValue } = hueTokens[identity?.profile?.data?.hue ?? hexToHue(peerId ?? "0")];
|
|
4590
|
+
const awarenessProvider2 = new SpaceAwarenessProvider({
|
|
4591
|
+
space,
|
|
4592
|
+
channel: `awareness.${id}`,
|
|
4593
|
+
peerId: identity.identityKey.toHex(),
|
|
4594
|
+
info: {
|
|
4595
|
+
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
4596
|
+
color: cursorDarkValue,
|
|
4597
|
+
lightColor: cursorLightValue
|
|
4598
|
+
}
|
|
4599
|
+
});
|
|
4600
|
+
extensions.push(awareness(awarenessProvider2));
|
|
4601
|
+
}
|
|
4602
|
+
return extensions;
|
|
4603
|
+
};
|
|
4604
|
+
var useDocAccessor = (text) => {
|
|
4605
|
+
return useMemo2(() => ({
|
|
4606
|
+
id: text.id,
|
|
4607
|
+
doc: getTextContent(text),
|
|
4608
|
+
accessor: createDocAccessor(text)
|
|
4609
|
+
}), [
|
|
4610
|
+
text
|
|
4611
|
+
]);
|
|
4612
|
+
};
|
|
4613
|
+
|
|
4614
|
+
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
4615
|
+
var useActionHandler = (view) => {
|
|
4616
|
+
return (action) => {
|
|
4617
|
+
if (!view) {
|
|
4618
|
+
return;
|
|
4619
|
+
}
|
|
4620
|
+
let inlineType, listType;
|
|
4621
|
+
switch (action.type) {
|
|
4622
|
+
case "heading":
|
|
4623
|
+
setHeading(parseInt(action.data))(view);
|
|
4624
|
+
break;
|
|
4625
|
+
case "strong":
|
|
4626
|
+
case "emphasis":
|
|
4627
|
+
case "strikethrough":
|
|
4628
|
+
case "code":
|
|
4629
|
+
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
4630
|
+
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
4631
|
+
break;
|
|
4632
|
+
case "list-ordered":
|
|
4633
|
+
case "list-bullet":
|
|
4634
|
+
case "list-task":
|
|
4635
|
+
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
4636
|
+
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
4637
|
+
break;
|
|
4638
|
+
case "blockquote":
|
|
4639
|
+
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
4640
|
+
break;
|
|
4641
|
+
case "codeblock":
|
|
4642
|
+
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
4643
|
+
break;
|
|
4644
|
+
case "table":
|
|
4645
|
+
insertTable(view);
|
|
4646
|
+
break;
|
|
4647
|
+
case "link":
|
|
4648
|
+
(action.data === false ? removeLink : addLink)(view);
|
|
4649
|
+
break;
|
|
4650
|
+
case "comment":
|
|
4651
|
+
createComment(view);
|
|
4652
|
+
break;
|
|
4653
|
+
}
|
|
4654
|
+
setTimeout(() => {
|
|
4655
|
+
if (!view.hasFocus) {
|
|
4656
|
+
view.focus();
|
|
4657
|
+
}
|
|
4658
|
+
});
|
|
4659
|
+
};
|
|
4660
|
+
};
|
|
4661
|
+
|
|
4662
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4663
|
+
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4664
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
4665
|
+
import { useEffect as useEffect3, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
|
|
4666
|
+
import { log as log10 } from "@dxos/log";
|
|
4667
|
+
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
4668
|
+
var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4669
|
+
var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
4670
|
+
let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo3(cb, deps ?? []);
|
|
4671
|
+
const onUpdate = useRef3();
|
|
4672
|
+
const [view, setView] = useState4();
|
|
4673
|
+
const parentRef = useRef3(null);
|
|
4674
|
+
useEffect3(() => {
|
|
4675
|
+
let view2;
|
|
4676
|
+
if (parentRef.current) {
|
|
4677
|
+
const state = EditorState3.create({
|
|
4678
|
+
doc,
|
|
4679
|
+
selection,
|
|
4680
|
+
extensions: [
|
|
4681
|
+
id && documentId2.of(id),
|
|
4682
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4683
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4684
|
+
log10.catch(err, void 0, {
|
|
4685
|
+
F: __dxlog_file12,
|
|
4686
|
+
L: 44,
|
|
4687
|
+
S: void 0,
|
|
4688
|
+
C: (f, a) => f(...a)
|
|
4689
|
+
});
|
|
4690
|
+
}),
|
|
4691
|
+
extensions,
|
|
4692
|
+
EditorView17.updateListener.of(() => {
|
|
4693
|
+
onUpdate.current?.();
|
|
4694
|
+
})
|
|
4695
|
+
].filter(isNotFalsy4)
|
|
4696
|
+
});
|
|
4697
|
+
view2 = new EditorView17({
|
|
4698
|
+
parent: parentRef.current,
|
|
4699
|
+
scrollTo,
|
|
4700
|
+
state,
|
|
4701
|
+
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4702
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4703
|
+
dispatchTransactions: (trs, view3) => {
|
|
4704
|
+
if (debug) {
|
|
4705
|
+
logChanges(trs);
|
|
4706
|
+
}
|
|
4707
|
+
view3.update(trs);
|
|
4708
|
+
}
|
|
4709
|
+
});
|
|
4710
|
+
setView(view2);
|
|
4711
|
+
}
|
|
4712
|
+
return () => {
|
|
4713
|
+
view2?.destroy();
|
|
4714
|
+
};
|
|
4715
|
+
}, deps);
|
|
4716
|
+
useEffect3(() => {
|
|
4717
|
+
if (view) {
|
|
4718
|
+
if (!selection && !view.state.selection.main.anchor) {
|
|
4719
|
+
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
4720
|
+
}
|
|
4721
|
+
if (selection || scrollTo) {
|
|
4722
|
+
onUpdate.current = () => {
|
|
4723
|
+
onUpdate.current = void 0;
|
|
4724
|
+
view.dispatch({
|
|
4725
|
+
selection,
|
|
4726
|
+
effects: scrollTo && [
|
|
4727
|
+
scrollTo
|
|
4728
|
+
],
|
|
4729
|
+
scrollIntoView: !scrollTo
|
|
4730
|
+
});
|
|
4731
|
+
};
|
|
4732
|
+
}
|
|
4733
|
+
if (autoFocus) {
|
|
4734
|
+
view.focus();
|
|
4735
|
+
}
|
|
4736
|
+
}
|
|
4737
|
+
}, [
|
|
4738
|
+
view,
|
|
4739
|
+
autoFocus,
|
|
4740
|
+
selection,
|
|
4741
|
+
scrollTo
|
|
4742
|
+
]);
|
|
4743
|
+
return {
|
|
4744
|
+
parentRef,
|
|
4745
|
+
view
|
|
4746
|
+
};
|
|
4900
4747
|
};
|
|
4901
4748
|
export {
|
|
4902
|
-
BaseTextEditor,
|
|
4903
4749
|
Cursor,
|
|
4904
4750
|
Doc,
|
|
4905
4751
|
EditorModes,
|
|
4906
4752
|
Inline,
|
|
4907
4753
|
List,
|
|
4908
|
-
MarkdownEditor,
|
|
4909
4754
|
RemoteSelectionsDecorator,
|
|
4910
4755
|
SpaceAwarenessProvider,
|
|
4911
4756
|
TextEditor,
|
|
@@ -4925,29 +4770,26 @@ export {
|
|
|
4925
4770
|
awarenessProvider,
|
|
4926
4771
|
blast,
|
|
4927
4772
|
callbackWrapper,
|
|
4928
|
-
codeTheme,
|
|
4929
4773
|
command,
|
|
4930
4774
|
comments,
|
|
4931
4775
|
compareFormatting,
|
|
4932
4776
|
createBasicExtensions,
|
|
4933
4777
|
createComment,
|
|
4778
|
+
createDataExtensions,
|
|
4934
4779
|
createMarkdownExtensions,
|
|
4935
4780
|
createThemeExtensions,
|
|
4936
4781
|
cursorLineMargin,
|
|
4937
|
-
cursorLineMarginFacet,
|
|
4938
4782
|
decorateMarkdown,
|
|
4939
|
-
defaultMarkdownSlots,
|
|
4940
4783
|
defaultOptions,
|
|
4941
|
-
defaultSlots,
|
|
4942
|
-
defaultTextSlots,
|
|
4943
4784
|
defaultTheme,
|
|
4944
4785
|
dnd,
|
|
4786
|
+
documentId2 as documentId,
|
|
4945
4787
|
editorFillLayoutEditor,
|
|
4946
4788
|
editorFillLayoutRoot,
|
|
4947
4789
|
editorMode,
|
|
4948
4790
|
editorWithToolbarLayout,
|
|
4949
4791
|
focusComment,
|
|
4950
|
-
|
|
4792
|
+
formattingKeymap,
|
|
4951
4793
|
getFormatting,
|
|
4952
4794
|
getToken,
|
|
4953
4795
|
image,
|
|
@@ -4959,9 +4801,7 @@ export {
|
|
|
4959
4801
|
markdownHighlightStyle,
|
|
4960
4802
|
markdownTags,
|
|
4961
4803
|
markdownTagsExtensions,
|
|
4962
|
-
markdownTheme,
|
|
4963
4804
|
mention,
|
|
4964
|
-
outliner,
|
|
4965
4805
|
removeBlockquote,
|
|
4966
4806
|
removeCodeblock,
|
|
4967
4807
|
removeLink,
|
|
@@ -4974,7 +4814,6 @@ export {
|
|
|
4974
4814
|
setStyle,
|
|
4975
4815
|
table,
|
|
4976
4816
|
tags2 as tags,
|
|
4977
|
-
textTheme,
|
|
4978
4817
|
toggleBlockquote,
|
|
4979
4818
|
toggleCodeblock,
|
|
4980
4819
|
toggleEmphasis,
|
|
@@ -4987,12 +4826,9 @@ export {
|
|
|
4987
4826
|
typewriter,
|
|
4988
4827
|
useActionHandler,
|
|
4989
4828
|
useComments,
|
|
4990
|
-
|
|
4829
|
+
useDocAccessor,
|
|
4991
4830
|
useFormattingState,
|
|
4992
|
-
useInMemoryTextModel,
|
|
4993
4831
|
useTextEditor,
|
|
4994
|
-
useTextExtensions,
|
|
4995
|
-
useTextModel,
|
|
4996
4832
|
useToolbarContext
|
|
4997
4833
|
};
|
|
4998
4834
|
//# sourceMappingURL=index.mjs.map
|