@dxos/react-ui-editor 0.3.11-main.f08de7a → 0.3.11-main.f437bee
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 +58 -57
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +6 -2
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +10 -10
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +2 -2
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/yjs.stories.d.ts +1 -1
- package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/index.d.ts +1 -0
- package/dist/types/src/extensions/automerge/index.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/package.json +22 -22
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +7 -4
- package/src/components/TextEditor/TextEditor.stories.tsx +3 -4
- package/src/components/TextEditor/TextEditor.tsx +59 -45
- package/src/extensions/autocomplete.ts +18 -17
- package/src/extensions/automerge/index.ts +1 -0
- package/src/hooks/useTextModel.ts +1 -1
- package/src/index.ts +2 -0
|
@@ -11,40 +11,41 @@ import { EditorView as EditorView12 } from "@codemirror/view";
|
|
|
11
11
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
12
12
|
import { vim } from "@replit/codemirror-vim";
|
|
13
13
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
14
|
-
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from "react";
|
|
14
|
+
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState, useRef } from "react";
|
|
15
15
|
import { generateName } from "@dxos/display-name";
|
|
16
16
|
import { useThemeContext } from "@dxos/react-ui";
|
|
17
17
|
import { getColorForValue, inputSurface, mx as mx3 } from "@dxos/react-ui-theme";
|
|
18
18
|
|
|
19
19
|
// packages/ui/react-ui-editor/src/extensions/autocomplete.ts
|
|
20
20
|
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
21
|
+
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
21
22
|
import { keymap } from "@codemirror/view";
|
|
22
23
|
var autocomplete = ({ onSearch }) => {
|
|
23
24
|
return [
|
|
24
25
|
// https://codemirror.net/docs/ref/#view.keymap
|
|
25
26
|
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
|
27
|
+
// TODO(burdon): Set custom keymap.
|
|
26
28
|
keymap.of(completionKeymap),
|
|
27
29
|
// https://codemirror.net/examples/autocompletion
|
|
28
30
|
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
|
29
31
|
autocompletion({
|
|
30
|
-
|
|
31
|
-
// defaultKeymap: false,
|
|
32
|
+
defaultKeymap: false,
|
|
32
33
|
// Don't start unless key press.
|
|
33
|
-
activateOnTyping: false
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
from: match.from,
|
|
44
|
-
options: onSearch(match.text.toLowerCase())
|
|
45
|
-
};
|
|
34
|
+
activateOnTyping: false
|
|
35
|
+
}),
|
|
36
|
+
// TODO(burdon): Option to create new page?
|
|
37
|
+
// TODO(burdon): Optional decoration via addToOptions
|
|
38
|
+
markdownLanguage.data.of({
|
|
39
|
+
autocomplete: (context) => {
|
|
40
|
+
const match = context.matchBefore(/\w*/);
|
|
41
|
+
if (!match || match.from === match.to && !context.explicit) {
|
|
42
|
+
return null;
|
|
46
43
|
}
|
|
47
|
-
|
|
44
|
+
return {
|
|
45
|
+
from: match.from,
|
|
46
|
+
options: onSearch(match.text.toLowerCase())
|
|
47
|
+
};
|
|
48
|
+
}
|
|
48
49
|
})
|
|
49
50
|
];
|
|
50
51
|
};
|
|
@@ -1708,7 +1709,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
1708
1709
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1709
1710
|
import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1710
1711
|
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1711
|
-
import { markdownLanguage as
|
|
1712
|
+
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1712
1713
|
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
1713
1714
|
import { languages } from "@codemirror/language-data";
|
|
1714
1715
|
import { searchKeymap } from "@codemirror/search";
|
|
@@ -1717,7 +1718,7 @@ import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/the
|
|
|
1717
1718
|
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView9, highlightActiveLine, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
|
|
1718
1719
|
|
|
1719
1720
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1720
|
-
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
1721
|
+
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
1721
1722
|
import { HighlightStyle } from "@codemirror/language";
|
|
1722
1723
|
import { tags, styleTags, Tag } from "@lezer/highlight";
|
|
1723
1724
|
import { Table } from "@lezer/markdown";
|
|
@@ -1904,7 +1905,7 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1904
1905
|
class: "font-mono"
|
|
1905
1906
|
}
|
|
1906
1907
|
], {
|
|
1907
|
-
scope:
|
|
1908
|
+
scope: markdownLanguage2,
|
|
1908
1909
|
all: {
|
|
1909
1910
|
fontFamily: getToken("fontFamily.body", []).join(",")
|
|
1910
1911
|
}
|
|
@@ -1936,7 +1937,7 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
1936
1937
|
// NOTE: This extends the parser; it doesn't affect rendering.
|
|
1937
1938
|
// https://github.github.com/gfm
|
|
1938
1939
|
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
1939
|
-
base:
|
|
1940
|
+
base: markdownLanguage3,
|
|
1940
1941
|
// Languages for syntax highlighting fenced code blocks.
|
|
1941
1942
|
codeLanguages: languages,
|
|
1942
1943
|
// Parser extensions.
|
|
@@ -2530,21 +2531,23 @@ var EditorModes = [
|
|
|
2530
2531
|
"default",
|
|
2531
2532
|
"vim"
|
|
2532
2533
|
];
|
|
2533
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: comments2, extensions = [], editorMode, slots = defaultSlots }, forwardedRef) => {
|
|
2534
|
-
const { themeMode } = useThemeContext();
|
|
2534
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, focus, selection, readonly, comments: comments2, extensions = [], editorMode, slots = defaultSlots }, forwardedRef) => {
|
|
2535
2535
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
2536
2536
|
tabBehavior: "limited"
|
|
2537
2537
|
});
|
|
2538
|
-
const
|
|
2539
|
-
const
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
state,
|
|
2538
|
+
const { themeMode } = useThemeContext();
|
|
2539
|
+
const rootRef = useRef(null);
|
|
2540
|
+
const [view, setView] = useState(null);
|
|
2541
|
+
useImperativeHandle(forwardedRef, () => view, [
|
|
2543
2542
|
view
|
|
2544
|
-
|
|
2543
|
+
]);
|
|
2544
|
+
useEffect(() => {
|
|
2545
|
+
if (view && focus) {
|
|
2546
|
+
view.focus();
|
|
2547
|
+
}
|
|
2548
|
+
}, [
|
|
2545
2549
|
view,
|
|
2546
|
-
|
|
2547
|
-
root
|
|
2550
|
+
focus
|
|
2548
2551
|
]);
|
|
2549
2552
|
const { awareness: awareness2, peer } = model;
|
|
2550
2553
|
useEffect(() => {
|
|
@@ -2581,11 +2584,12 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2581
2584
|
comments2
|
|
2582
2585
|
]);
|
|
2583
2586
|
useEffect(() => {
|
|
2584
|
-
if (!
|
|
2587
|
+
if (!model || !rootRef.current) {
|
|
2585
2588
|
return;
|
|
2586
2589
|
}
|
|
2587
|
-
const
|
|
2590
|
+
const state = EditorState2.create({
|
|
2588
2591
|
doc: model.text(),
|
|
2592
|
+
selection,
|
|
2589
2593
|
extensions: [
|
|
2590
2594
|
readonly && EditorState2.readOnly.of(readonly),
|
|
2591
2595
|
// TODO(burdon): Factor out VIM mode? (manage via MarkdownPlugin).
|
|
@@ -2602,19 +2606,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2602
2606
|
].filter(Boolean)
|
|
2603
2607
|
});
|
|
2604
2608
|
view?.destroy();
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
state: state2,
|
|
2609
|
-
parent: root
|
|
2610
|
-
})
|
|
2609
|
+
const newView = new EditorView12({
|
|
2610
|
+
parent: rootRef.current,
|
|
2611
|
+
state
|
|
2611
2612
|
});
|
|
2613
|
+
setView(newView);
|
|
2612
2614
|
return () => {
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
+
newView?.destroy();
|
|
2616
|
+
setView(null);
|
|
2615
2617
|
};
|
|
2616
2618
|
}, [
|
|
2617
|
-
|
|
2619
|
+
rootRef,
|
|
2618
2620
|
model,
|
|
2619
2621
|
readonly,
|
|
2620
2622
|
editorMode,
|
|
@@ -2623,12 +2625,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2623
2625
|
const handleKeyUp = useCallback((event) => {
|
|
2624
2626
|
const { key, altKey, shiftKey, metaKey, ctrlKey } = event;
|
|
2625
2627
|
switch (key) {
|
|
2626
|
-
case "Enter": {
|
|
2627
|
-
view?.contentDOM.focus();
|
|
2628
|
-
break;
|
|
2629
|
-
}
|
|
2630
2628
|
case "Escape": {
|
|
2631
|
-
editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) &&
|
|
2629
|
+
editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) && rootRef.current?.focus();
|
|
2632
2630
|
break;
|
|
2633
2631
|
}
|
|
2634
2632
|
}
|
|
@@ -2638,16 +2636,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2638
2636
|
]);
|
|
2639
2637
|
return /* @__PURE__ */ React.createElement("div", {
|
|
2640
2638
|
key: model.id,
|
|
2641
|
-
ref:
|
|
2639
|
+
ref: rootRef,
|
|
2642
2640
|
tabIndex: 0,
|
|
2643
2641
|
...slots?.root,
|
|
2644
2642
|
...editorMode !== "vim" && tabsterDOMAttribute,
|
|
2645
2643
|
onKeyUp: handleKeyUp
|
|
2646
2644
|
});
|
|
2647
2645
|
});
|
|
2648
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots
|
|
2646
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots, ...props }, forwardedRef) => {
|
|
2649
2647
|
const { themeMode } = useThemeContext();
|
|
2650
|
-
const
|
|
2648
|
+
const updatedSlots = defaultsDeep2({}, slots, defaultTextSlots);
|
|
2651
2649
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2652
2650
|
ref: forwardedRef,
|
|
2653
2651
|
readonly,
|
|
@@ -2655,17 +2653,17 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots:
|
|
|
2655
2653
|
basicBundle({
|
|
2656
2654
|
readonly,
|
|
2657
2655
|
themeMode,
|
|
2658
|
-
placeholder:
|
|
2656
|
+
placeholder: updatedSlots?.editor?.placeholder
|
|
2659
2657
|
}),
|
|
2660
2658
|
...extensions
|
|
2661
2659
|
],
|
|
2662
|
-
slots,
|
|
2660
|
+
slots: updatedSlots,
|
|
2663
2661
|
...props
|
|
2664
2662
|
});
|
|
2665
2663
|
});
|
|
2666
|
-
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots
|
|
2664
|
+
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots, ...props }, forwardedRef) => {
|
|
2667
2665
|
const { themeMode } = useThemeContext();
|
|
2668
|
-
const
|
|
2666
|
+
const updatedSlots = defaultsDeep2({}, slots, defaultMarkdownSlots);
|
|
2669
2667
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2670
2668
|
ref: forwardedRef,
|
|
2671
2669
|
readonly,
|
|
@@ -2673,11 +2671,11 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
|
|
|
2673
2671
|
markdownBundle({
|
|
2674
2672
|
readonly,
|
|
2675
2673
|
themeMode,
|
|
2676
|
-
placeholder:
|
|
2674
|
+
placeholder: updatedSlots?.editor?.placeholder
|
|
2677
2675
|
}),
|
|
2678
2676
|
...extensions
|
|
2679
2677
|
],
|
|
2680
|
-
slots,
|
|
2678
|
+
slots: updatedSlots,
|
|
2681
2679
|
...props
|
|
2682
2680
|
});
|
|
2683
2681
|
});
|
|
@@ -2983,7 +2981,7 @@ var modelState = StateField5.define({
|
|
|
2983
2981
|
});
|
|
2984
2982
|
var useTextModel = (props) => {
|
|
2985
2983
|
const { identity, space, text } = props;
|
|
2986
|
-
const [model, setModel] = useState2(
|
|
2984
|
+
const [model, setModel] = useState2();
|
|
2987
2985
|
useEffect2(() => setModel(createModel(props)), [
|
|
2988
2986
|
identity,
|
|
2989
2987
|
space,
|
|
@@ -3042,6 +3040,7 @@ var createAutomergeModel = ({ space, identity, text }) => {
|
|
|
3042
3040
|
export {
|
|
3043
3041
|
AwarenessProvider,
|
|
3044
3042
|
BaseTextEditor,
|
|
3043
|
+
CursorConverter,
|
|
3045
3044
|
Doc,
|
|
3046
3045
|
EditorModes,
|
|
3047
3046
|
MarkdownEditor,
|
|
@@ -3057,11 +3056,13 @@ export {
|
|
|
3057
3056
|
awareness,
|
|
3058
3057
|
basicBundle,
|
|
3059
3058
|
blast,
|
|
3059
|
+
callbackWrapper,
|
|
3060
3060
|
code2 as code,
|
|
3061
3061
|
codeTheme,
|
|
3062
3062
|
comments,
|
|
3063
3063
|
createAutomergeModel,
|
|
3064
3064
|
createYjsModel,
|
|
3065
|
+
cursorConverter,
|
|
3065
3066
|
defaultMarkdownSlots,
|
|
3066
3067
|
defaultOptions,
|
|
3067
3068
|
defaultSlots,
|