@dxos/react-ui-editor 0.3.11-main.cb8120f → 0.3.11-main.ccc0ca3
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 +362 -45
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +1 -2
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +1 -1
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts +23 -0
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +23 -7
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +10 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/index.d.ts +2 -0
- package/dist/types/src/components/Toolbar/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/basic.d.ts +1 -1
- package/dist/types/src/extensions/basic.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/markdown/bundle.d.ts +2 -2
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts +2 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useActionHandler.d.ts +2 -2
- package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
- package/dist/types/src/hooks/useEditorView.d.ts +17 -0
- package/dist/types/src/hooks/useEditorView.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextEditor.d.ts +36 -14
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/package.json +26 -25
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +2 -3
- package/src/components/TextEditor/TextEditor.tsx +23 -13
- package/src/components/TextEditor/comments.stories.tsx +3 -3
- package/src/components/TextEditor/hooks.stories.tsx +106 -0
- package/src/components/Toolbar/Toolbar.stories.tsx +7 -3
- package/src/components/Toolbar/Toolbar.tsx +120 -69
- package/src/components/Toolbar/index.ts +5 -0
- package/src/components/index.ts +1 -0
- package/src/extensions/automerge/update-automerge.ts +7 -7
- package/src/extensions/basic.ts +15 -13
- package/src/extensions/comments.ts +2 -2
- package/src/extensions/markdown/bundle.ts +10 -5
- package/src/extensions/markdown/formatting.ts +31 -2
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useActionHandler.ts +22 -5
- package/src/hooks/useEditorView.ts +29 -0
- package/src/hooks/useTextEditor.ts +143 -19
- package/src/themes/default.ts +3 -1
|
@@ -8,14 +8,13 @@ import { tags as tags2 } from "@lezer/highlight";
|
|
|
8
8
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
9
9
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
10
10
|
import { EditorView as EditorView13 } from "@codemirror/view";
|
|
11
|
-
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
12
11
|
import { vim } from "@replit/codemirror-vim";
|
|
13
12
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
14
13
|
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState } from "react";
|
|
15
14
|
import { log as log2 } from "@dxos/log";
|
|
16
15
|
import { useThemeContext } from "@dxos/react-ui";
|
|
17
16
|
import { attentionSurface, mx as mx3 } from "@dxos/react-ui-theme";
|
|
18
|
-
import {
|
|
17
|
+
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
19
18
|
|
|
20
19
|
// packages/ui/react-ui-editor/src/extensions/autocomplete.ts
|
|
21
20
|
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
@@ -125,18 +124,18 @@ var updateAutomerge = (field, handle, transactions, state) => {
|
|
|
125
124
|
return void 0;
|
|
126
125
|
}
|
|
127
126
|
const newHeads = handle.changeAt(lastHeads, (doc) => {
|
|
128
|
-
const
|
|
127
|
+
const invertedTransactions = [];
|
|
129
128
|
for (const tr of transactions) {
|
|
130
129
|
tr.changes.iterChanges((fromA, toA, _fromB, _toB, insert) => {
|
|
131
|
-
|
|
132
|
-
fromA,
|
|
133
|
-
toA,
|
|
130
|
+
invertedTransactions.push({
|
|
131
|
+
from: fromA,
|
|
132
|
+
del: toA - fromA,
|
|
134
133
|
insert
|
|
135
134
|
});
|
|
136
135
|
});
|
|
137
136
|
}
|
|
138
|
-
|
|
139
|
-
A2.splice(doc, path.slice(),
|
|
137
|
+
invertedTransactions.reverse().forEach(({ from, del, insert }) => {
|
|
138
|
+
A2.splice(doc, path.slice(), from, del, insert.toString());
|
|
140
139
|
});
|
|
141
140
|
});
|
|
142
141
|
return newHeads ?? void 0;
|
|
@@ -637,18 +636,19 @@ import { history } from "@codemirror/commands";
|
|
|
637
636
|
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
638
637
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
639
638
|
import { drawSelection, EditorView as EditorView3, highlightActiveLine, placeholder } from "@codemirror/view";
|
|
640
|
-
|
|
641
|
-
|
|
639
|
+
import { isNotFalsy } from "@dxos/util";
|
|
640
|
+
var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => [
|
|
641
|
+
lineWrapping && EditorView3.lineWrapping,
|
|
642
642
|
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
643
643
|
bracketMatching(),
|
|
644
644
|
closeBrackets(),
|
|
645
645
|
drawSelection(),
|
|
646
646
|
highlightActiveLine(),
|
|
647
647
|
history(),
|
|
648
|
-
_placeholder
|
|
648
|
+
_placeholder && placeholder(_placeholder),
|
|
649
649
|
// https://github.com/codemirror/theme-one-dark
|
|
650
650
|
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
|
|
651
|
-
];
|
|
651
|
+
].filter(isNotFalsy);
|
|
652
652
|
|
|
653
653
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
|
654
654
|
import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
|
|
@@ -1086,7 +1086,7 @@ var commentMark = Decoration2.mark({
|
|
|
1086
1086
|
var commentCurrentMark = Decoration2.mark({
|
|
1087
1087
|
class: "cm-comment-current"
|
|
1088
1088
|
});
|
|
1089
|
-
var
|
|
1089
|
+
var focusComment = (view, id, center = true) => {
|
|
1090
1090
|
const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
|
|
1091
1091
|
if (!comment?.comment.cursor) {
|
|
1092
1092
|
return;
|
|
@@ -1293,7 +1293,7 @@ var createComment = (view) => {
|
|
|
1293
1293
|
current: id
|
|
1294
1294
|
}),
|
|
1295
1295
|
selection: {
|
|
1296
|
-
anchor:
|
|
1296
|
+
anchor: to
|
|
1297
1297
|
}
|
|
1298
1298
|
});
|
|
1299
1299
|
return true;
|
|
@@ -1453,6 +1453,7 @@ import { searchKeymap } from "@codemirror/search";
|
|
|
1453
1453
|
import { EditorState } from "@codemirror/state";
|
|
1454
1454
|
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
1455
1455
|
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView7, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
|
|
1456
|
+
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
1456
1457
|
|
|
1457
1458
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1458
1459
|
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
@@ -1643,11 +1644,11 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1643
1644
|
};
|
|
1644
1645
|
|
|
1645
1646
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1646
|
-
var
|
|
1647
|
+
var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
|
|
1647
1648
|
return [
|
|
1649
|
+
lineWrapping && EditorView7.lineWrapping,
|
|
1648
1650
|
EditorState.allowMultipleSelections.of(true),
|
|
1649
1651
|
EditorState.tabSize.of(2),
|
|
1650
|
-
EditorView7.lineWrapping,
|
|
1651
1652
|
// https://github.com/codemirror/basic-setup
|
|
1652
1653
|
bracketMatching2(),
|
|
1653
1654
|
closeBrackets2(),
|
|
@@ -1657,7 +1658,7 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
1657
1658
|
highlightActiveLine2(),
|
|
1658
1659
|
history2(),
|
|
1659
1660
|
indentOnInput(),
|
|
1660
|
-
_placeholder
|
|
1661
|
+
_placeholder && placeholder2(_placeholder),
|
|
1661
1662
|
// Main extension.
|
|
1662
1663
|
// https://github.com/codemirror/lang-markdown
|
|
1663
1664
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -1692,7 +1693,7 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
1692
1693
|
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1693
1694
|
...standardKeymap
|
|
1694
1695
|
])
|
|
1695
|
-
];
|
|
1696
|
+
].filter(isNotFalsy2);
|
|
1696
1697
|
};
|
|
1697
1698
|
|
|
1698
1699
|
// packages/ui/react-ui-editor/src/extensions/markdown/code.ts
|
|
@@ -1810,6 +1811,7 @@ var code2 = () => {
|
|
|
1810
1811
|
};
|
|
1811
1812
|
|
|
1812
1813
|
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
1814
|
+
import { snippet } from "@codemirror/autocomplete";
|
|
1813
1815
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
1814
1816
|
import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
|
|
1815
1817
|
import { Decoration as Decoration4, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
@@ -1818,8 +1820,8 @@ var setHeading = (level) => (view) => {
|
|
|
1818
1820
|
const changes = [];
|
|
1819
1821
|
for (const range of ranges) {
|
|
1820
1822
|
const { number } = doc.lineAt(range.anchor);
|
|
1821
|
-
const { from } = doc.line(number);
|
|
1822
|
-
const line = doc.sliceString(from,
|
|
1823
|
+
const { from, to } = doc.line(number);
|
|
1824
|
+
const line = doc.sliceString(from, to);
|
|
1823
1825
|
const [_, marks, spaces] = line.match(/(#+)(\s+)/) ?? [];
|
|
1824
1826
|
const current = marks?.length ?? 0;
|
|
1825
1827
|
if (level !== current) {
|
|
@@ -1858,6 +1860,31 @@ var toggleStyle = (mark2) => (view) => {
|
|
|
1858
1860
|
}
|
|
1859
1861
|
return true;
|
|
1860
1862
|
};
|
|
1863
|
+
var snippets = {
|
|
1864
|
+
codeblock: snippet([
|
|
1865
|
+
"```#{lang}",
|
|
1866
|
+
" #{}",
|
|
1867
|
+
"```"
|
|
1868
|
+
].join("\n")),
|
|
1869
|
+
table: snippet([
|
|
1870
|
+
"| #{col1} | #{col2} |",
|
|
1871
|
+
"| ---- | ---- |",
|
|
1872
|
+
"| #{val1} | #{val2} |",
|
|
1873
|
+
"| #{val3} | #{val4} |"
|
|
1874
|
+
].join("\n"))
|
|
1875
|
+
};
|
|
1876
|
+
var insertCodeblock = (view) => {
|
|
1877
|
+
const { selection: { main }, doc } = view.state;
|
|
1878
|
+
const { number } = doc.lineAt(main.anchor);
|
|
1879
|
+
const { from } = doc.line(number);
|
|
1880
|
+
snippets.codeblock(view, null, from, from);
|
|
1881
|
+
};
|
|
1882
|
+
var insertTable = (view) => {
|
|
1883
|
+
const { selection: { main }, doc } = view.state;
|
|
1884
|
+
const { number } = doc.lineAt(main.anchor);
|
|
1885
|
+
const { from } = doc.line(number);
|
|
1886
|
+
snippets.table(view, null, from, from);
|
|
1887
|
+
};
|
|
1861
1888
|
var toggleBold = toggleStyle("**");
|
|
1862
1889
|
var toggleItalic = toggleStyle("_");
|
|
1863
1890
|
var toggleStrikethrough = toggleStyle("~~");
|
|
@@ -2552,8 +2579,9 @@ var defaultTheme = {
|
|
|
2552
2579
|
outline: "none"
|
|
2553
2580
|
},
|
|
2554
2581
|
".cm-scroller": {
|
|
2555
|
-
overflow:
|
|
2556
|
-
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
2582
|
+
// overflow: 'visible',
|
|
2583
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(","),
|
|
2584
|
+
lineHeight: 1.4
|
|
2557
2585
|
},
|
|
2558
2586
|
".cm-content": {
|
|
2559
2587
|
padding: 0,
|
|
@@ -2764,9 +2792,6 @@ var EditorModes = [
|
|
|
2764
2792
|
"vim"
|
|
2765
2793
|
];
|
|
2766
2794
|
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo, selection, editorMode, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
|
|
2767
|
-
const tabsterDOMAttribute = useFocusableGroup({
|
|
2768
|
-
tabBehavior: "limited"
|
|
2769
|
-
});
|
|
2770
2795
|
const { themeMode } = useThemeContext();
|
|
2771
2796
|
const rootRef = useRef(null);
|
|
2772
2797
|
const [view, setView] = useState(null);
|
|
@@ -2774,7 +2799,15 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2774
2799
|
view
|
|
2775
2800
|
]);
|
|
2776
2801
|
useEffect2(() => {
|
|
2777
|
-
if (autoFocus) {
|
|
2802
|
+
if (autoFocus && !view?.hasFocus) {
|
|
2803
|
+
if (view?.state.selection.main?.from === 0) {
|
|
2804
|
+
const { to } = view.state.doc.lineAt(0);
|
|
2805
|
+
view?.dispatch({
|
|
2806
|
+
selection: {
|
|
2807
|
+
anchor: to
|
|
2808
|
+
}
|
|
2809
|
+
});
|
|
2810
|
+
}
|
|
2778
2811
|
view?.focus();
|
|
2779
2812
|
}
|
|
2780
2813
|
}, [
|
|
@@ -2793,7 +2826,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2793
2826
|
EditorView13.exceptionSink.of((err) => {
|
|
2794
2827
|
log2.catch(err, void 0, {
|
|
2795
2828
|
F: __dxlog_file3,
|
|
2796
|
-
L:
|
|
2829
|
+
L: 134,
|
|
2797
2830
|
S: void 0,
|
|
2798
2831
|
C: (f, a) => f(...a)
|
|
2799
2832
|
});
|
|
@@ -2815,11 +2848,11 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2815
2848
|
// Storage and replication.
|
|
2816
2849
|
// NOTE: This must come before user extensions.
|
|
2817
2850
|
model.extension,
|
|
2818
|
-
// TODO(burdon): Factor out (
|
|
2851
|
+
// TODO(burdon): Factor out? (Requires special handling for Escape/Enter below).
|
|
2819
2852
|
editorMode === "vim" && vim(),
|
|
2820
2853
|
// Custom.
|
|
2821
2854
|
...extensions
|
|
2822
|
-
].filter(
|
|
2855
|
+
].filter(isNotFalsy3)
|
|
2823
2856
|
});
|
|
2824
2857
|
const newView = new EditorView13({
|
|
2825
2858
|
state,
|
|
@@ -2856,7 +2889,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2856
2889
|
}
|
|
2857
2890
|
case "Escape": {
|
|
2858
2891
|
if (editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey)) {
|
|
2859
|
-
|
|
2892
|
+
view?.focus();
|
|
2860
2893
|
}
|
|
2861
2894
|
break;
|
|
2862
2895
|
}
|
|
@@ -2869,9 +2902,9 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2869
2902
|
key: model.id,
|
|
2870
2903
|
role: "none",
|
|
2871
2904
|
tabIndex: 0,
|
|
2872
|
-
onKeyUp: handleKeyUp,
|
|
2873
2905
|
...slots.root,
|
|
2874
|
-
...editorMode !==
|
|
2906
|
+
// {...(editorMode !== 'vim' && tabsterDOMAttribute)}
|
|
2907
|
+
onKeyUp: handleKeyUp,
|
|
2875
2908
|
ref: rootRef
|
|
2876
2909
|
});
|
|
2877
2910
|
});
|
|
@@ -2882,7 +2915,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
2882
2915
|
ref: forwardedRef,
|
|
2883
2916
|
readonly,
|
|
2884
2917
|
extensions: [
|
|
2885
|
-
|
|
2918
|
+
createBasicBundle({
|
|
2886
2919
|
themeMode,
|
|
2887
2920
|
placeholder: placeholder3,
|
|
2888
2921
|
lineWrapping
|
|
@@ -2901,7 +2934,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2901
2934
|
ref: forwardedRef,
|
|
2902
2935
|
readonly,
|
|
2903
2936
|
extensions: [
|
|
2904
|
-
|
|
2937
|
+
createMarkdownExtensions({
|
|
2905
2938
|
themeMode,
|
|
2906
2939
|
placeholder: placeholder3
|
|
2907
2940
|
}),
|
|
@@ -2928,6 +2961,167 @@ var defaultMarkdownSlots = {
|
|
|
2928
2961
|
...defaultSlots
|
|
2929
2962
|
};
|
|
2930
2963
|
|
|
2964
|
+
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
2965
|
+
import { At, CaretRight, ChatText, Code, Image, Link, ListBullets, ListChecks, ListNumbers, TextStrikethrough, Table as Table2, TextB, TextItalic } from "@phosphor-icons/react";
|
|
2966
|
+
import { createContext } from "@radix-ui/react-context";
|
|
2967
|
+
import React2 from "react";
|
|
2968
|
+
import { Button, DensityProvider, Select } from "@dxos/react-ui";
|
|
2969
|
+
import { getSize } from "@dxos/react-ui-theme";
|
|
2970
|
+
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
2971
|
+
var ToolbarRoot = ({ children, onAction }) => {
|
|
2972
|
+
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
2973
|
+
onAction
|
|
2974
|
+
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
2975
|
+
density: "fine"
|
|
2976
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
2977
|
+
role: "toolbar",
|
|
2978
|
+
className: "flex w-full shrink-0 p-2 gap-4 items-center whitespace-nowrap overflow-hidden"
|
|
2979
|
+
}, children)));
|
|
2980
|
+
};
|
|
2981
|
+
var ToolbarButton = ({ Icon, onClick, title }) => {
|
|
2982
|
+
const { onAction } = useToolbarContext("ToolbarButton");
|
|
2983
|
+
const handleClick = () => {
|
|
2984
|
+
const action = onClick();
|
|
2985
|
+
if (action) {
|
|
2986
|
+
onAction?.(action);
|
|
2987
|
+
}
|
|
2988
|
+
};
|
|
2989
|
+
return /* @__PURE__ */ React2.createElement(Button, {
|
|
2990
|
+
variant: "ghost",
|
|
2991
|
+
classNames: "p-2",
|
|
2992
|
+
onClick: handleClick,
|
|
2993
|
+
title
|
|
2994
|
+
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
2995
|
+
className: getSize(5)
|
|
2996
|
+
}));
|
|
2997
|
+
};
|
|
2998
|
+
var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
2999
|
+
className: "grow"
|
|
3000
|
+
});
|
|
3001
|
+
var MarkdownHeading = () => {
|
|
3002
|
+
const { onAction } = useToolbarContext("MarkdownFormatting");
|
|
3003
|
+
return /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
3004
|
+
defaultValue: "0",
|
|
3005
|
+
onValueChange: (value) => onAction?.({
|
|
3006
|
+
type: "heading",
|
|
3007
|
+
data: parseInt(value)
|
|
3008
|
+
})
|
|
3009
|
+
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
3010
|
+
classNames: "w-[8rem]"
|
|
3011
|
+
}), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
3012
|
+
value: "0"
|
|
3013
|
+
}, "Paragraph"), [
|
|
3014
|
+
1,
|
|
3015
|
+
2,
|
|
3016
|
+
3,
|
|
3017
|
+
4,
|
|
3018
|
+
5,
|
|
3019
|
+
6
|
|
3020
|
+
].map((level) => /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
3021
|
+
key: level,
|
|
3022
|
+
value: String(level)
|
|
3023
|
+
}, "Heading ", level))))));
|
|
3024
|
+
};
|
|
3025
|
+
var MarkdownStyles = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3026
|
+
role: "none"
|
|
3027
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3028
|
+
Icon: TextB,
|
|
3029
|
+
title: "Bold",
|
|
3030
|
+
onClick: () => ({
|
|
3031
|
+
type: "bold"
|
|
3032
|
+
})
|
|
3033
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3034
|
+
Icon: TextItalic,
|
|
3035
|
+
title: "Italic",
|
|
3036
|
+
onClick: () => ({
|
|
3037
|
+
type: "italic"
|
|
3038
|
+
})
|
|
3039
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3040
|
+
Icon: TextStrikethrough,
|
|
3041
|
+
title: "Strike-through",
|
|
3042
|
+
onClick: () => ({
|
|
3043
|
+
type: "strikethrough"
|
|
3044
|
+
})
|
|
3045
|
+
}));
|
|
3046
|
+
var MarkdownLists = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3047
|
+
role: "none"
|
|
3048
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3049
|
+
Icon: ListBullets,
|
|
3050
|
+
title: "Bullet list",
|
|
3051
|
+
onClick: () => ({
|
|
3052
|
+
type: "list"
|
|
3053
|
+
})
|
|
3054
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3055
|
+
Icon: ListNumbers,
|
|
3056
|
+
title: "Numbered list",
|
|
3057
|
+
onClick: () => ({
|
|
3058
|
+
type: "list-ordered"
|
|
3059
|
+
})
|
|
3060
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3061
|
+
Icon: ListChecks,
|
|
3062
|
+
title: "Task list",
|
|
3063
|
+
onClick: () => ({
|
|
3064
|
+
type: "list-tasks"
|
|
3065
|
+
})
|
|
3066
|
+
}));
|
|
3067
|
+
var MarkdownBlocks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3068
|
+
role: "none"
|
|
3069
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3070
|
+
Icon: CaretRight,
|
|
3071
|
+
title: "Block quite",
|
|
3072
|
+
onClick: () => ({
|
|
3073
|
+
type: "blockquote"
|
|
3074
|
+
})
|
|
3075
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3076
|
+
Icon: Code,
|
|
3077
|
+
title: "Code block",
|
|
3078
|
+
onClick: () => ({
|
|
3079
|
+
type: "codeblock"
|
|
3080
|
+
})
|
|
3081
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3082
|
+
Icon: Table2,
|
|
3083
|
+
title: "Table",
|
|
3084
|
+
onClick: () => ({
|
|
3085
|
+
type: "table"
|
|
3086
|
+
})
|
|
3087
|
+
}));
|
|
3088
|
+
var MarkdownLinks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3089
|
+
role: "none"
|
|
3090
|
+
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3091
|
+
Icon: Link,
|
|
3092
|
+
title: "Link",
|
|
3093
|
+
onClick: () => ({
|
|
3094
|
+
type: "link"
|
|
3095
|
+
})
|
|
3096
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3097
|
+
Icon: At,
|
|
3098
|
+
title: "Mention",
|
|
3099
|
+
onClick: () => ({
|
|
3100
|
+
type: "mention"
|
|
3101
|
+
})
|
|
3102
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3103
|
+
Icon: Image,
|
|
3104
|
+
title: "Image",
|
|
3105
|
+
onClick: () => ({
|
|
3106
|
+
type: "image"
|
|
3107
|
+
})
|
|
3108
|
+
}));
|
|
3109
|
+
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), /* @__PURE__ */ React2.createElement(MarkdownLinks, null));
|
|
3110
|
+
var MarkdownExtended = () => /* @__PURE__ */ React2.createElement(Toolbar.Button, {
|
|
3111
|
+
Icon: ChatText,
|
|
3112
|
+
title: "Create comment",
|
|
3113
|
+
onClick: () => ({
|
|
3114
|
+
type: "comment"
|
|
3115
|
+
})
|
|
3116
|
+
});
|
|
3117
|
+
var Toolbar = {
|
|
3118
|
+
Root: ToolbarRoot,
|
|
3119
|
+
Button: ToolbarButton,
|
|
3120
|
+
Separator: ToolbarSeparator,
|
|
3121
|
+
Markdown: MarkdownStandard,
|
|
3122
|
+
Extended: MarkdownExtended
|
|
3123
|
+
};
|
|
3124
|
+
|
|
2931
3125
|
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
2932
3126
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
2933
3127
|
import { Context as Context2 } from "@dxos/context";
|
|
@@ -3061,19 +3255,28 @@ var useActionHandler = (view) => {
|
|
|
3061
3255
|
case "list":
|
|
3062
3256
|
toggleList(view);
|
|
3063
3257
|
break;
|
|
3258
|
+
case "codeblock":
|
|
3259
|
+
insertCodeblock(view);
|
|
3260
|
+
break;
|
|
3261
|
+
case "table":
|
|
3262
|
+
insertTable(view);
|
|
3263
|
+
break;
|
|
3064
3264
|
case "comment":
|
|
3065
3265
|
createComment(view);
|
|
3066
3266
|
break;
|
|
3067
3267
|
}
|
|
3068
3268
|
setTimeout(() => {
|
|
3069
3269
|
view.focus();
|
|
3270
|
+
view.dispatch({
|
|
3271
|
+
selection: view.state.selection
|
|
3272
|
+
});
|
|
3070
3273
|
});
|
|
3071
3274
|
};
|
|
3072
3275
|
};
|
|
3073
3276
|
|
|
3074
|
-
// packages/ui/react-ui-editor/src/hooks/
|
|
3277
|
+
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
3075
3278
|
import { useState as useState2 } from "react";
|
|
3076
|
-
var
|
|
3279
|
+
var useEditorView = () => {
|
|
3077
3280
|
const [view, setView] = useState2(null);
|
|
3078
3281
|
return [
|
|
3079
3282
|
(ref) => {
|
|
@@ -3083,18 +3286,125 @@ var useTextEditor = () => {
|
|
|
3083
3286
|
];
|
|
3084
3287
|
};
|
|
3085
3288
|
|
|
3289
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
3290
|
+
import { EditorSelection, EditorState as EditorState3 } from "@codemirror/state";
|
|
3291
|
+
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
3292
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
3293
|
+
import { log as log4 } from "@dxos/log";
|
|
3294
|
+
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
3295
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
3296
|
+
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}) => {
|
|
3297
|
+
const onUpdate = useRef2();
|
|
3298
|
+
const [view, setView] = useState3();
|
|
3299
|
+
const parentRef = useRef2(null);
|
|
3300
|
+
useEffect3(() => {
|
|
3301
|
+
if (parentRef.current) {
|
|
3302
|
+
const state = EditorState3.create({
|
|
3303
|
+
doc,
|
|
3304
|
+
selection,
|
|
3305
|
+
extensions: [
|
|
3306
|
+
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
3307
|
+
EditorView14.exceptionSink.of((err) => {
|
|
3308
|
+
log4.catch(err, void 0, {
|
|
3309
|
+
F: __dxlog_file5,
|
|
3310
|
+
L: 57,
|
|
3311
|
+
S: void 0,
|
|
3312
|
+
C: (f, a) => f(...a)
|
|
3313
|
+
});
|
|
3314
|
+
}),
|
|
3315
|
+
extensions,
|
|
3316
|
+
EditorView14.updateListener.of(() => {
|
|
3317
|
+
onUpdate.current?.();
|
|
3318
|
+
})
|
|
3319
|
+
].filter(isNotFalsy4)
|
|
3320
|
+
});
|
|
3321
|
+
const view2 = new EditorView14({
|
|
3322
|
+
parent: parentRef.current,
|
|
3323
|
+
scrollTo,
|
|
3324
|
+
state,
|
|
3325
|
+
// NOTE: Uncomment to debug/monitor all transactions.
|
|
3326
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
3327
|
+
dispatchTransactions: (trs, view3) => {
|
|
3328
|
+
if (debug) {
|
|
3329
|
+
logChanges(trs);
|
|
3330
|
+
}
|
|
3331
|
+
view3.update(trs);
|
|
3332
|
+
}
|
|
3333
|
+
});
|
|
3334
|
+
setView(view2);
|
|
3335
|
+
}
|
|
3336
|
+
return () => {
|
|
3337
|
+
view?.destroy();
|
|
3338
|
+
};
|
|
3339
|
+
}, [
|
|
3340
|
+
parentRef
|
|
3341
|
+
]);
|
|
3342
|
+
useEffect3(() => {
|
|
3343
|
+
if (view) {
|
|
3344
|
+
if (!selection && !view.state.selection.main.anchor) {
|
|
3345
|
+
selection = EditorSelection.single(view.state.doc.line(1).to);
|
|
3346
|
+
}
|
|
3347
|
+
if (selection || scrollTo) {
|
|
3348
|
+
onUpdate.current = () => {
|
|
3349
|
+
onUpdate.current = void 0;
|
|
3350
|
+
view.dispatch({
|
|
3351
|
+
selection,
|
|
3352
|
+
effects: scrollTo && [
|
|
3353
|
+
scrollTo
|
|
3354
|
+
],
|
|
3355
|
+
scrollIntoView: !scrollTo
|
|
3356
|
+
});
|
|
3357
|
+
};
|
|
3358
|
+
}
|
|
3359
|
+
if (autoFocus) {
|
|
3360
|
+
view.focus();
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
}, [
|
|
3364
|
+
view,
|
|
3365
|
+
autoFocus,
|
|
3366
|
+
selection,
|
|
3367
|
+
scrollTo
|
|
3368
|
+
]);
|
|
3369
|
+
return {
|
|
3370
|
+
parentRef,
|
|
3371
|
+
view
|
|
3372
|
+
};
|
|
3373
|
+
};
|
|
3374
|
+
var createDataExtensions = ({ readonly = false } = {}) => {
|
|
3375
|
+
return [
|
|
3376
|
+
//
|
|
3377
|
+
EditorState3.readOnly.of(readonly),
|
|
3378
|
+
EditorView14.editable.of(!readonly)
|
|
3379
|
+
];
|
|
3380
|
+
};
|
|
3381
|
+
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
3382
|
+
return [
|
|
3383
|
+
//
|
|
3384
|
+
EditorView14.baseTheme(defaultTheme),
|
|
3385
|
+
theme && EditorView14.theme(theme),
|
|
3386
|
+
EditorView14.darkTheme.of(themeMode === "dark"),
|
|
3387
|
+
EditorView14.editorAttributes.of({
|
|
3388
|
+
class: slots?.editor?.className ?? ""
|
|
3389
|
+
}),
|
|
3390
|
+
EditorView14.contentAttributes.of({
|
|
3391
|
+
class: slots?.content?.className ?? ""
|
|
3392
|
+
})
|
|
3393
|
+
].filter(isNotFalsy4);
|
|
3394
|
+
};
|
|
3395
|
+
|
|
3086
3396
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
3087
3397
|
import get4 from "lodash.get";
|
|
3088
|
-
import { useEffect as
|
|
3398
|
+
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
3089
3399
|
import { generateName } from "@dxos/display-name";
|
|
3090
3400
|
import { getRawDoc } from "@dxos/echo-schema";
|
|
3091
3401
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
3092
3402
|
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
3093
|
-
var
|
|
3403
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
3094
3404
|
var useTextModel = (props) => {
|
|
3095
3405
|
const { identity, space, text } = props;
|
|
3096
|
-
const [model, setModel] =
|
|
3097
|
-
|
|
3406
|
+
const [model, setModel] = useState4();
|
|
3407
|
+
useEffect4(() => setModel(createModel(props)), [
|
|
3098
3408
|
identity,
|
|
3099
3409
|
space,
|
|
3100
3410
|
text
|
|
@@ -3103,7 +3413,7 @@ var useTextModel = (props) => {
|
|
|
3103
3413
|
};
|
|
3104
3414
|
var createModel = ({ space, identity, text }) => {
|
|
3105
3415
|
invariant3(isAutomergeObject(text), void 0, {
|
|
3106
|
-
F:
|
|
3416
|
+
F: __dxlog_file6,
|
|
3107
3417
|
L: 34,
|
|
3108
3418
|
S: void 0,
|
|
3109
3419
|
A: [
|
|
@@ -3158,33 +3468,39 @@ export {
|
|
|
3158
3468
|
SpaceAwarenessProvider,
|
|
3159
3469
|
TextEditor,
|
|
3160
3470
|
TextKind,
|
|
3471
|
+
Toolbar,
|
|
3161
3472
|
YText,
|
|
3162
3473
|
YXmlFragment,
|
|
3163
3474
|
autocomplete,
|
|
3164
3475
|
automerge,
|
|
3165
3476
|
awareness,
|
|
3166
3477
|
awarenessProvider,
|
|
3167
|
-
basicBundle,
|
|
3168
3478
|
blast,
|
|
3169
3479
|
callbackWrapper,
|
|
3170
3480
|
code2 as code,
|
|
3171
3481
|
codeTheme,
|
|
3172
3482
|
comments,
|
|
3483
|
+
createBasicBundle,
|
|
3173
3484
|
createComment,
|
|
3485
|
+
createDataExtensions,
|
|
3486
|
+
createMarkdownExtensions,
|
|
3487
|
+
createThemeExtensions,
|
|
3174
3488
|
defaultMarkdownSlots,
|
|
3175
3489
|
defaultOptions,
|
|
3176
3490
|
defaultSlots,
|
|
3177
3491
|
defaultTextSlots,
|
|
3178
3492
|
defaultTheme,
|
|
3493
|
+
focusComment,
|
|
3179
3494
|
formatting,
|
|
3180
3495
|
getToken,
|
|
3181
3496
|
heading2 as heading,
|
|
3182
3497
|
hr,
|
|
3183
3498
|
image,
|
|
3499
|
+
insertCodeblock,
|
|
3500
|
+
insertTable,
|
|
3184
3501
|
link,
|
|
3185
3502
|
listener,
|
|
3186
3503
|
logChanges,
|
|
3187
|
-
markdownBundle,
|
|
3188
3504
|
markdownHighlightStyle,
|
|
3189
3505
|
markdownTags,
|
|
3190
3506
|
markdownTagsExtensions,
|
|
@@ -3193,7 +3509,6 @@ export {
|
|
|
3193
3509
|
modelState,
|
|
3194
3510
|
outliner,
|
|
3195
3511
|
setComments,
|
|
3196
|
-
setFocus,
|
|
3197
3512
|
setHeading,
|
|
3198
3513
|
setSelection,
|
|
3199
3514
|
table,
|
|
@@ -3208,7 +3523,9 @@ export {
|
|
|
3208
3523
|
typewriter,
|
|
3209
3524
|
useActionHandler,
|
|
3210
3525
|
useComments,
|
|
3526
|
+
useEditorView,
|
|
3211
3527
|
useTextEditor,
|
|
3212
|
-
useTextModel
|
|
3528
|
+
useTextModel,
|
|
3529
|
+
useToolbarContext
|
|
3213
3530
|
};
|
|
3214
3531
|
//# sourceMappingURL=index.mjs.map
|