@mdxeditor/editor 2.5.1 → 2.7.0

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/MDXEditor.js CHANGED
@@ -37,7 +37,7 @@ const RichTextEditor = () => {
37
37
  editorWrappers$,
38
38
  placeholder$
39
39
  );
40
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, topAreaChildren.map((Child, index) => /* @__PURE__ */ React__default.createElement(Child, { key: index })), /* @__PURE__ */ React__default.createElement(RenderRecursiveWrappers, { wrappers: editorWrappers }, /* @__PURE__ */ React__default.createElement("div", { className: classNames(styles.rootContentEditableWrapper) }, /* @__PURE__ */ React__default.createElement(
40
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, topAreaChildren.map((Child, index) => /* @__PURE__ */ React__default.createElement(Child, { key: index })), /* @__PURE__ */ React__default.createElement(RenderRecursiveWrappers, { wrappers: editorWrappers }, /* @__PURE__ */ React__default.createElement("div", { className: (classNames(styles.rootContentEditableWrapper), "mdxeditor-root-contenteditable") }, /* @__PURE__ */ React__default.createElement(
41
41
  RichTextPlugin,
42
42
  {
43
43
  contentEditable: /* @__PURE__ */ React__default.createElement(ContentEditable, { className: classNames(styles.contentEditable, contentEditableClassName) }),
@@ -71,13 +71,12 @@ const EditorRootElement = ({ children, className }) => {
71
71
  const setEditorRootElementRef = usePublisher(editorRootElementRef$);
72
72
  React__default.useEffect(() => {
73
73
  const popupContainer = document.createElement("div");
74
- popupContainer.classList.add(styles.editorRoot);
75
- popupContainer.classList.add(styles.popupContainer);
76
- if (className) {
77
- className.trim().split(" ").forEach((c) => {
78
- popupContainer.classList.add(c);
79
- });
80
- }
74
+ popupContainer.classList.add(
75
+ "mdxeditor-popup-container",
76
+ styles.editorRoot,
77
+ styles.popupContainer,
78
+ ...(className ?? "").trim().split(" ").filter(Boolean)
79
+ );
81
80
  document.body.appendChild(popupContainer);
82
81
  editorRootElementRef.current = popupContainer;
83
82
  setEditorRootElementRef(editorRootElementRef);
@@ -85,7 +84,7 @@ const EditorRootElement = ({ children, className }) => {
85
84
  popupContainer.remove();
86
85
  };
87
86
  }, [className, editorRootElementRef, setEditorRootElementRef]);
88
- return /* @__PURE__ */ React__default.createElement("div", { className: classNames(styles.editorRoot, styles.editorWrapper, className, "mdxeditor") }, children);
87
+ return /* @__PURE__ */ React__default.createElement("div", { className: classNames("mdxeditor", styles.editorRoot, styles.editorWrapper, className) }, children);
89
88
  };
90
89
  const Methods = ({ mdxRef }) => {
91
90
  const realm = useRealm();
package/dist/index.d.ts CHANGED
@@ -836,6 +836,7 @@ export declare const diffSourcePlugin: (params?: {
836
836
  */
837
837
  export declare const DiffSourceToggleWrapper: React_2.FC<{
838
838
  children: React_2.ReactNode;
839
+ options?: ViewMode[];
839
840
  }>;
840
841
 
841
842
  /**
@@ -1761,6 +1762,17 @@ export declare const markdownShortcutPlugin: (params?: unknown) => RealmPlugin;
1761
1762
  */
1762
1763
  export declare const markdownSourceEditorValue$: NodeRef<string>;
1763
1764
 
1765
+ /**
1766
+ * A plugin that limits the maximum length of the text content of the editor.
1767
+ * Adapted from the Lexical plugin. https://github.com/facebook/lexical/blob/main/packages/lexical-playground/src/plugins/MaxLengthPlugin/index.tsx
1768
+ * @example
1769
+ * ```tsx
1770
+ * <MDXEditor plugins={[maxLengthPlugin(100)]} markdown={'hello world'} />
1771
+ * ```
1772
+ * @group Utilities
1773
+ */
1774
+ export declare const maxLengthPlugin: (params?: number | undefined) => RealmPlugin;
1775
+
1764
1776
  /**
1765
1777
  * A block-level HTML node.
1766
1778
  * @group HTML
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ import { disableAutoLink$, linkPlugin } from "./plugins/link/index.js";
12
12
  import { INSERT_IMAGE_COMMAND, closeImageDialog$, disableImageResize$, imageAutocompleteSuggestions$, imageDialogState$, imagePlugin, imagePreviewHandler$, imageUploadHandler$, insertImage$, openEditImageDialog$, openNewImageDialog$, saveImage$ } from "./plugins/image/index.js";
13
13
  import { frontmatterDialogOpen$, frontmatterPlugin, hasFrontmatter$, insertFrontmatter$, removeFrontmatter$ } from "./plugins/frontmatter/index.js";
14
14
  import { quotePlugin } from "./plugins/quote/index.js";
15
+ import { maxLengthPlugin } from "./plugins/maxlength/index.js";
15
16
  import { insertJsx$, isMdastJsxNode, jsxPlugin } from "./plugins/jsx/index.js";
16
17
  import { GenericJsxEditor } from "./jsx-editors/GenericJsxEditor.js";
17
18
  import { insertSandpack$, sandpackConfig$, sandpackPlugin } from "./plugins/sandpack/index.js";
@@ -243,6 +244,7 @@ export {
243
244
  markdownProcessingError$,
244
245
  markdownShortcutPlugin,
245
246
  markdownSourceEditorValue$,
247
+ maxLengthPlugin,
246
248
  mdastExtensions$,
247
249
  nestedEditorChildren$,
248
250
  noop,
@@ -6,7 +6,7 @@ import styles from "../../styles/ui.module.css.js";
6
6
  import { useCellValues } from "@mdxeditor/gurx";
7
7
  const DiffSourceWrapper = ({ children }) => {
8
8
  const [error, viewMode] = useCellValues(markdownProcessingError$, viewMode$);
9
- return /* @__PURE__ */ React__default.createElement("div", null, error ? /* @__PURE__ */ React__default.createElement("div", { className: styles.markdownParseError }, /* @__PURE__ */ React__default.createElement("p", null, error.error, "."), /* @__PURE__ */ React__default.createElement("p", null, "You can fix the errors in source mode and switch to rich text mode when you are ready.")) : null, /* @__PURE__ */ React__default.createElement("div", { style: { display: viewMode === "rich-text" && error == null ? "block" : "none" } }, children), viewMode === "diff" ? /* @__PURE__ */ React__default.createElement(DiffViewer, null) : null, viewMode === "source" ? /* @__PURE__ */ React__default.createElement(SourceEditor, null) : null);
9
+ return /* @__PURE__ */ React__default.createElement("div", { className: "mdxeditor-diff-source-wrapper" }, error ? /* @__PURE__ */ React__default.createElement("div", { className: styles.markdownParseError }, /* @__PURE__ */ React__default.createElement("p", null, error.error, "."), /* @__PURE__ */ React__default.createElement("p", null, "You can fix the errors in source mode and switch to rich text mode when you are ready.")) : null, /* @__PURE__ */ React__default.createElement("div", { className: "mdxeditor-rich-text-editor", style: { display: viewMode === "rich-text" && error == null ? "block" : "none" } }, children), viewMode === "diff" ? /* @__PURE__ */ React__default.createElement(DiffViewer, null) : null, viewMode === "source" ? /* @__PURE__ */ React__default.createElement(SourceEditor, null) : null);
10
10
  };
11
11
  export {
12
12
  DiffSourceWrapper
@@ -71,7 +71,7 @@ const DiffViewer = () => {
71
71
  cmMergeViewRef.current = null;
72
72
  };
73
73
  }, [onUpdate, cmExtensions]);
74
- return /* @__PURE__ */ React__default.createElement("div", { ref: elRef });
74
+ return /* @__PURE__ */ React__default.createElement("div", { ref: elRef, className: "mdxeditor-diff-editor" });
75
75
  };
76
76
  export {
77
77
  DiffViewer
@@ -52,7 +52,7 @@ const SourceEditor = () => {
52
52
  },
53
53
  [markdown2, readOnly, updateMarkdown, cmExtensions, triggerOnBlur]
54
54
  );
55
- return /* @__PURE__ */ React__default.createElement("div", { ref, className: "cm-sourceView" });
55
+ return /* @__PURE__ */ React__default.createElement("div", { ref, className: "cm-sourceView mdxeditor-source-editor" });
56
56
  };
57
57
  export {
58
58
  COMMON_STATE_CONFIG_EXTENSIONS,
@@ -0,0 +1,36 @@
1
+ import { trimTextContentFromAnchor } from "@lexical/selection";
2
+ import { $restoreEditorState } from "@lexical/utils";
3
+ import { RootNode, $getSelection, $isRangeSelection } from "lexical";
4
+ import { realmPlugin } from "../../RealmWithPlugins.js";
5
+ import { createRootEditorSubscription$ } from "../core/index.js";
6
+ const maxLengthPlugin = realmPlugin({
7
+ init: (realm, maxLength = Infinity) => {
8
+ realm.pub(createRootEditorSubscription$, (editor) => {
9
+ let lastRestoredEditorState = null;
10
+ return editor.registerNodeTransform(RootNode, (rootNode) => {
11
+ const selection = $getSelection();
12
+ if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
13
+ return;
14
+ }
15
+ const prevEditorState = editor.getEditorState();
16
+ const prevTextContentSize = prevEditorState.read(() => rootNode.getTextContentSize());
17
+ const textContentSize = rootNode.getTextContentSize();
18
+ if (prevTextContentSize !== textContentSize) {
19
+ const delCount = textContentSize - maxLength;
20
+ const anchor = selection.anchor;
21
+ if (delCount > 0) {
22
+ if (prevTextContentSize === maxLength && lastRestoredEditorState !== prevEditorState) {
23
+ lastRestoredEditorState = prevEditorState;
24
+ $restoreEditorState(editor, prevEditorState);
25
+ } else {
26
+ trimTextContentFromAnchor(editor, anchor, delCount);
27
+ }
28
+ }
29
+ }
30
+ });
31
+ });
32
+ }
33
+ });
34
+ export {
35
+ maxLengthPlugin
36
+ };
@@ -3,19 +3,28 @@ import { useCellValues, usePublisher } from "@mdxeditor/gurx";
3
3
  import React__default from "react";
4
4
  import styles from "../../../styles/ui.module.css.js";
5
5
  import { SingleChoiceToggleGroup } from "../primitives/toolbar.js";
6
- const DiffSourceToggleWrapper = ({ children }) => {
6
+ const DiffSourceToggleWrapper = ({
7
+ children,
8
+ options = ["rich-text", "diff", "source"]
9
+ }) => {
7
10
  const [viewMode, iconComponentFor] = useCellValues(viewMode$, iconComponentFor$);
8
11
  const changeViewMode = usePublisher(viewMode$);
12
+ const toggleGroupItems = [];
13
+ if (options.includes("rich-text")) {
14
+ toggleGroupItems.push({ title: "Rich text", contents: iconComponentFor("rich_text"), value: "rich-text" });
15
+ }
16
+ if (options.includes("diff")) {
17
+ toggleGroupItems.push({ title: "Diff mode", contents: iconComponentFor("difference"), value: "diff" });
18
+ }
19
+ if (options.includes("source")) {
20
+ toggleGroupItems.push({ title: "Source", contents: iconComponentFor("markdown"), value: "source" });
21
+ }
9
22
  return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, viewMode === "rich-text" ? children : viewMode === "diff" ? /* @__PURE__ */ React__default.createElement("span", { className: styles.toolbarTitleMode }, "Diff mode") : /* @__PURE__ */ React__default.createElement("span", { className: styles.toolbarTitleMode }, "Source mode"), /* @__PURE__ */ React__default.createElement("div", { style: { marginLeft: "auto", pointerEvents: "auto", opacity: 1 } }, /* @__PURE__ */ React__default.createElement(
10
23
  SingleChoiceToggleGroup,
11
24
  {
12
25
  className: styles.diffSourceToggle,
13
26
  value: viewMode,
14
- items: [
15
- { title: "Rich text", contents: iconComponentFor("rich_text"), value: "rich-text" },
16
- { title: "Diff mode", contents: iconComponentFor("difference"), value: "diff" },
17
- { title: "Source", contents: iconComponentFor("markdown"), value: "source" }
18
- ],
27
+ items: toggleGroupItems,
19
28
  onChange: (value) => changeViewMode(value || "rich-text")
20
29
  }
21
30
  )));
@@ -29,7 +29,15 @@ const SelectContent = ({
29
29
  className = styles.selectContainer
30
30
  }) => {
31
31
  const editorRootElementRef = useCellValue(editorRootElementRef$);
32
- return /* @__PURE__ */ React__default.createElement(RadixSelect.Portal, { container: editorRootElementRef == null ? void 0 : editorRootElementRef.current }, /* @__PURE__ */ React__default.createElement(RadixSelect.Content, { className, onCloseAutoFocus: (e) => e.preventDefault(), position: "popper" }, /* @__PURE__ */ React__default.createElement(RadixSelect.Viewport, { "data-editor-dropdown": true }, children)));
32
+ return /* @__PURE__ */ React__default.createElement(RadixSelect.Portal, { container: editorRootElementRef == null ? void 0 : editorRootElementRef.current }, /* @__PURE__ */ React__default.createElement(
33
+ RadixSelect.Content,
34
+ {
35
+ className: classNames(className, "mdxeditor-select-content"),
36
+ onCloseAutoFocus: (e) => e.preventDefault(),
37
+ position: "popper"
38
+ },
39
+ /* @__PURE__ */ React__default.createElement(RadixSelect.Viewport, { "data-editor-dropdown": true }, children)
40
+ ));
33
41
  };
34
42
  const SelectButtonTrigger = ({
35
43
  children,
@@ -22,7 +22,7 @@ const Root = ({ readOnly, children }) => {
22
22
  return /* @__PURE__ */ React__default.createElement(
23
23
  RadixToolbar.Root,
24
24
  {
25
- className: classNames(styles.toolbarRoot, { [styles.readOnlyToolbarRoot]: readOnly }),
25
+ className: classNames("mdxeditor-toolbar", styles.toolbarRoot, { [styles.readOnlyToolbarRoot]: readOnly }),
26
26
  ...readOnly ? { tabIndex: -1 } : {}
27
27
  },
28
28
  children
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "*.css"
12
12
  ],
13
13
  "type": "module",
14
- "version": "2.5.1",
14
+ "version": "2.7.0",
15
15
  "description": "React component for rich text markdown editing",
16
16
  "scripts": {
17
17
  "build": "vite build",