@mdxeditor/editor 1.0.1 → 1.1.1

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.
@@ -3,6 +3,7 @@ function isParent(node) {
3
3
  return node.children instanceof Array;
4
4
  }
5
5
  function importMarkdownToLexical({ root, markdown, visitors, syntaxExtensions, mdastExtensions }) {
6
+ var _a;
6
7
  const mdastRoot = fromMarkdown(markdown, {
7
8
  extensions: syntaxExtensions,
8
9
  mdastExtensions
@@ -10,6 +11,9 @@ function importMarkdownToLexical({ root, markdown, visitors, syntaxExtensions, m
10
11
  if (mdastRoot.children.length === 0) {
11
12
  mdastRoot.children.push({ type: "paragraph", children: [] });
12
13
  }
14
+ if (((_a = mdastRoot.children.at(-1)) == null ? void 0 : _a.type) !== "paragraph") {
15
+ mdastRoot.children.push({ type: "paragraph", children: [] });
16
+ }
13
17
  importMdastTreeToLexical({ root, mdastRoot, visitors });
14
18
  }
15
19
  function importMdastTreeToLexical({ root, mdastRoot, visitors }) {
@@ -72,10 +72,6 @@ export interface NestedEditorProps<T extends Mdast.Content> {
72
72
  * Whether or not the editor edits blocks (multiple paragraphs)
73
73
  */
74
74
  block?: boolean;
75
- /**
76
- * An emitter (usually constructed in the lexical node) that will activate the editor when the node is focused.
77
- */
78
- focusEmitter?: VoidEmitter;
79
75
  }
80
76
  /**
81
77
  * A nested editor React component that allows editing of the contents of complex markdown nodes that have nested markdown content (for example, custom directives or JSX elements). See the {@link NestedEditorProps} for more details on the compoment props.
@@ -44,7 +44,7 @@ function useLexicalNodeRemove() {
44
44
  }
45
45
  const NestedLexicalEditor = function(props) {
46
46
  const { getContent, getUpdatedMdastNode, contentEditableProps, block = false } = props;
47
- const { mdastNode, lexicalNode } = useNestedEditorContext();
47
+ const { mdastNode, lexicalNode, focusEmitter } = useNestedEditorContext();
48
48
  const updateMdastNode = useMdastNodeUpdater();
49
49
  const removeNode = useLexicalNodeRemove();
50
50
  const content = getContent(mdastNode);
@@ -66,11 +66,10 @@ const NestedLexicalEditor = function(props) {
66
66
  return editor2;
67
67
  });
68
68
  React__default.useEffect(() => {
69
- var _a;
70
- (_a = props.focusEmitter) == null ? void 0 : _a.subscribe(() => {
69
+ focusEmitter == null ? void 0 : focusEmitter.subscribe(() => {
71
70
  editor.focus();
72
71
  });
73
- }, [editor, props.focusEmitter]);
72
+ }, [editor, focusEmitter]);
74
73
  React__default.useEffect(() => {
75
74
  editor.update(() => {
76
75
  $getRoot().clear();
@@ -298,7 +298,7 @@ const coreSystem = system((r) => {
298
298
  $insertNodeToNearestRoot(node);
299
299
  }
300
300
  if (Object.hasOwn(node, "select") && typeof node.select === "function") {
301
- setTimeout(() => node.select(), 80);
301
+ setTimeout(() => node.select());
302
302
  }
303
303
  });
304
304
  }
@@ -1,17 +1,57 @@
1
1
  import React__default from "react";
2
- import { parseDiff, Diff, Hunk } from "react-diff-view";
3
- import { formatLines, diffLines } from "unidiff";
4
- import "../../node_modules/react-diff-view/style/index.css.js";
5
- import { corePluginHooks } from "../core/index.js";
6
2
  import { diffSourcePluginHooks } from "./index.js";
3
+ import { corePluginHooks } from "../core/index.js";
4
+ import { MergeView } from "@codemirror/merge";
5
+ import { EditorState } from "@codemirror/state";
6
+ import { EditorView } from "@codemirror/view";
7
+ import { COMMON_STATE_CONFIG_EXTENSIONS } from "./SourceEditor.js";
7
8
  const DiffViewer = () => {
8
9
  const [newText] = corePluginHooks.useEmitterValues("markdown");
9
10
  const [oldText] = diffSourcePluginHooks.useEmitterValues("diffMarkdown");
10
- const diffText = formatLines(diffLines(oldText, newText), { context: 3 });
11
- if (diffText.trim() === "")
12
- return /* @__PURE__ */ React__default.createElement("div", null, "No changes");
13
- const [diff] = parseDiff(diffText, { nearbySequences: "zip" });
14
- return /* @__PURE__ */ React__default.createElement(Diff, { viewType: "split", diffType: "modify", hunks: diff.hunks || [] }, (hunks) => hunks.map((hunk) => /* @__PURE__ */ React__default.createElement(Hunk, { key: hunk.content, hunk })));
11
+ const updateMarkdown = diffSourcePluginHooks.usePublisher("markdownSourceEditorValue");
12
+ return /* @__PURE__ */ React__default.createElement(CmMergeView, { oldMarkdown: oldText, newMarkdown: newText, onUpdate: updateMarkdown });
13
+ };
14
+ const CmMergeView = ({ oldMarkdown, newMarkdown, onUpdate }) => {
15
+ const cmMergeViewRef = React__default.useRef(null);
16
+ const ref = React__default.useCallback(
17
+ (el) => {
18
+ var _a;
19
+ if (el !== null) {
20
+ cmMergeViewRef.current = new MergeView({
21
+ renderRevertControl: () => {
22
+ const el2 = document.createElement("button");
23
+ el2.classList.add("cm-merge-revert");
24
+ el2.appendChild(document.createTextNode("⮕"));
25
+ return el2;
26
+ },
27
+ parent: el,
28
+ orientation: "a-b",
29
+ revertControls: "a-to-b",
30
+ gutter: true,
31
+ collapseUnchanged: { margin: 2, minSize: 3 },
32
+ a: {
33
+ doc: oldMarkdown,
34
+ extensions: [...COMMON_STATE_CONFIG_EXTENSIONS, EditorState.readOnly.of(true)]
35
+ },
36
+ b: {
37
+ doc: newMarkdown,
38
+ extensions: [
39
+ ...COMMON_STATE_CONFIG_EXTENSIONS,
40
+ EditorView.updateListener.of(({ state }) => {
41
+ const md = state.doc.toString();
42
+ onUpdate(md);
43
+ })
44
+ ]
45
+ }
46
+ });
47
+ } else {
48
+ (_a = cmMergeViewRef.current) == null ? void 0 : _a.destroy();
49
+ cmMergeViewRef.current = null;
50
+ }
51
+ },
52
+ [newMarkdown, oldMarkdown, onUpdate]
53
+ );
54
+ return /* @__PURE__ */ React__default.createElement("div", { ref });
15
55
  };
16
56
  export {
17
57
  DiffViewer
@@ -1,2 +1,4 @@
1
+ import { Extension } from '@codemirror/state';
1
2
  import React from 'react';
3
+ export declare const COMMON_STATE_CONFIG_EXTENSIONS: Extension[];
2
4
  export declare const SourceEditor: () => React.JSX.Element;
@@ -1,28 +1,44 @@
1
1
  import { markdown } from "@codemirror/lang-markdown";
2
- import { SandpackProvider, CodeEditor } from "@codesandbox/sandpack-react";
2
+ import { EditorState } from "@codemirror/state";
3
+ import { lineNumbers, EditorView } from "@codemirror/view";
4
+ import { basicLight } from "cm6-theme-basic-light";
5
+ import { basicSetup } from "codemirror";
3
6
  import React__default from "react";
4
7
  import { diffSourcePluginHooks } from "./index.js";
5
8
  import { corePluginHooks } from "../core/index.js";
6
- import { EditorView } from "@codemirror/view";
9
+ const COMMON_STATE_CONFIG_EXTENSIONS = [basicSetup, basicLight, markdown(), lineNumbers()];
7
10
  const SourceEditor = () => {
8
- const [markdown$1, readOnly] = corePluginHooks.useEmitterValues("markdown", "readOnly");
11
+ const [markdown2, readOnly] = corePluginHooks.useEmitterValues("markdown", "readOnly");
9
12
  const updateMarkdown = diffSourcePluginHooks.usePublisher("markdownSourceEditorValue");
10
- const codeMirrorRef = React__default.useRef(null);
11
- return /* @__PURE__ */ React__default.createElement("div", null, /* @__PURE__ */ React__default.createElement(React__default.Suspense, { fallback: null }, /* @__PURE__ */ React__default.createElement(SandpackProvider, null, /* @__PURE__ */ React__default.createElement(
12
- CodeEditor,
13
- {
14
- readOnly,
15
- extensions: [EditorView.lineWrapping],
16
- showLineNumbers: true,
17
- additionalLanguages: [{ name: "markdown", extensions: ["md"], language: markdown() }],
18
- initMode: "lazy",
19
- filePath: `file.md`,
20
- code: markdown$1,
21
- onCodeUpdate: updateMarkdown,
22
- ref: codeMirrorRef
23
- }
24
- ))));
13
+ const editorViewRef = React__default.useRef(null);
14
+ const ref = React__default.useCallback(
15
+ (el) => {
16
+ var _a;
17
+ if (el !== null) {
18
+ const extensions = [
19
+ ...COMMON_STATE_CONFIG_EXTENSIONS,
20
+ EditorView.updateListener.of(({ state }) => {
21
+ updateMarkdown(state.doc.toString());
22
+ })
23
+ ];
24
+ if (readOnly) {
25
+ extensions.push(EditorState.readOnly.of(true));
26
+ }
27
+ el.innerHTML = "";
28
+ editorViewRef.current = new EditorView({
29
+ parent: el,
30
+ state: EditorState.create({ doc: markdown2, extensions })
31
+ });
32
+ } else {
33
+ (_a = editorViewRef.current) == null ? void 0 : _a.destroy();
34
+ editorViewRef.current = null;
35
+ }
36
+ },
37
+ [markdown2, readOnly, updateMarkdown]
38
+ );
39
+ return /* @__PURE__ */ React__default.createElement("div", { ref, className: "cm-sourceView" });
25
40
  };
26
41
  export {
42
+ COMMON_STATE_CONFIG_EXTENSIONS,
27
43
  SourceEditor
28
44
  };
@@ -23,7 +23,7 @@ const diffSourceSystem = system(
23
23
  r.o.withLatestFrom(markdownSourceEditorValue)
24
24
  ),
25
25
  ([{ current }, markdownSourceFromEditor]) => {
26
- if (current === "source") {
26
+ if (current === "source" || current === "diff") {
27
27
  r.pub(setMarkdown, markdownSourceFromEditor);
28
28
  }
29
29
  }
@@ -11,6 +11,9 @@ function getLinkNodeInSelection(selection) {
11
11
  return null;
12
12
  }
13
13
  const node = getSelectedNode(selection);
14
+ if (node === null) {
15
+ return null;
16
+ }
14
17
  const parent = node.getParent();
15
18
  if ($isLinkNode(parent)) {
16
19
  return parent;