@nkzw/mdx-editor 0.1.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.
Files changed (148) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -0
  3. package/UPSTREAM.md +21 -0
  4. package/dist/EditorIcon.js +75 -0
  5. package/dist/FormatConstants.js +20 -0
  6. package/dist/MDXEditor.js +189 -0
  7. package/dist/MarkdownEditor.js +281 -0
  8. package/dist/PersistentMarkdownEditor.js +358 -0
  9. package/dist/RealmWithPlugins.js +35 -0
  10. package/dist/core.d.ts +3232 -0
  11. package/dist/core.js +354 -0
  12. package/dist/defaultSvgIcons.js +371 -0
  13. package/dist/directive-editors/AdmonitionDirectiveDescriptor.js +28 -0
  14. package/dist/directive-editors/GenericDirectiveEditor.js +37 -0
  15. package/dist/exportMarkdownFromLexical.js +262 -0
  16. package/dist/horizontalRuleShortcut.js +37 -0
  17. package/dist/importMarkdownToLexical.js +172 -0
  18. package/dist/index.d.ts +86 -0
  19. package/dist/index.js +8 -0
  20. package/dist/jsx-editors/GenericJsxEditor.js +84 -0
  21. package/dist/mdastUtilHtmlComment.js +125 -0
  22. package/dist/persistence.d.ts +128 -0
  23. package/dist/persistence.js +4 -0
  24. package/dist/plugins/codeblock/CodeBlockNode.js +183 -0
  25. package/dist/plugins/codeblock/CodeBlockVisitor.js +14 -0
  26. package/dist/plugins/codeblock/MdastCodeVisitor.js +23 -0
  27. package/dist/plugins/codeblock/findCodeBlockDescriptor.js +8 -0
  28. package/dist/plugins/codeblock/index.js +46 -0
  29. package/dist/plugins/codemirror/CodeMirrorEditor.js +145 -0
  30. package/dist/plugins/codemirror/index.js +115 -0
  31. package/dist/plugins/codemirror/useCodeMirrorRef.js +101 -0
  32. package/dist/plugins/core/GenericHTMLNode.js +118 -0
  33. package/dist/plugins/core/LexicalGenericHTMLNodeVisitor.js +15 -0
  34. package/dist/plugins/core/LexicalLinebreakVisitor.js +10 -0
  35. package/dist/plugins/core/LexicalParagraphVisitor.js +10 -0
  36. package/dist/plugins/core/LexicalRootVisitor.js +10 -0
  37. package/dist/plugins/core/LexicalTextVisitor.js +160 -0
  38. package/dist/plugins/core/MdastBreakVisitor.js +10 -0
  39. package/dist/plugins/core/MdastFormattingVisitor.js +81 -0
  40. package/dist/plugins/core/MdastHTMLNode.js +120 -0
  41. package/dist/plugins/core/MdastHTMLVisitor.js +17 -0
  42. package/dist/plugins/core/MdastParagraphVisitor.js +23 -0
  43. package/dist/plugins/core/MdastRootVisitor.js +9 -0
  44. package/dist/plugins/core/MdastTextVisitor.js +16 -0
  45. package/dist/plugins/core/NestedLexicalEditor.js +221 -0
  46. package/dist/plugins/core/PropertyPopover.js +75 -0
  47. package/dist/plugins/core/SharedHistoryPlugin.js +10 -0
  48. package/dist/plugins/core/index.js +692 -0
  49. package/dist/plugins/core/ui/DownshiftAutoComplete.js +89 -0
  50. package/dist/plugins/core/ui/PopoverUtils.js +22 -0
  51. package/dist/plugins/diff-source/DiffSourceWrapper.js +24 -0
  52. package/dist/plugins/diff-source/DiffViewer.js +84 -0
  53. package/dist/plugins/diff-source/SourceEditor.js +60 -0
  54. package/dist/plugins/diff-source/index.js +27 -0
  55. package/dist/plugins/directives/DirectiveNode.js +107 -0
  56. package/dist/plugins/directives/DirectiveVisitor.js +10 -0
  57. package/dist/plugins/directives/MdastDirectiveVisitor.js +30 -0
  58. package/dist/plugins/directives/index.js +45 -0
  59. package/dist/plugins/frontmatter/FrontmatterEditor.js +137 -0
  60. package/dist/plugins/frontmatter/FrontmatterNode.js +70 -0
  61. package/dist/plugins/frontmatter/LexicalFrontmatterVisitor.js +10 -0
  62. package/dist/plugins/frontmatter/MdastFrontmatterVisitor.js +10 -0
  63. package/dist/plugins/frontmatter/index.js +113 -0
  64. package/dist/plugins/headings/LexicalHeadingVisitor.js +11 -0
  65. package/dist/plugins/headings/MdastHeadingVisitor.js +10 -0
  66. package/dist/plugins/headings/index.js +63 -0
  67. package/dist/plugins/image/EditImageToolbar.js +58 -0
  68. package/dist/plugins/image/ImageDialog.js +132 -0
  69. package/dist/plugins/image/ImageEditor.js +279 -0
  70. package/dist/plugins/image/ImageNode.js +187 -0
  71. package/dist/plugins/image/ImagePlaceholder.js +9 -0
  72. package/dist/plugins/image/ImageResizer.js +223 -0
  73. package/dist/plugins/image/LexicalImageVisitor.js +42 -0
  74. package/dist/plugins/image/MdastImageVisitor.js +91 -0
  75. package/dist/plugins/image/index.js +364 -0
  76. package/dist/plugins/jsx/LexicalJsxNode.js +103 -0
  77. package/dist/plugins/jsx/LexicalJsxVisitor.js +27 -0
  78. package/dist/plugins/jsx/LexicalMdxExpressionNode.js +130 -0
  79. package/dist/plugins/jsx/LexicalMdxExpressionVisitor.js +14 -0
  80. package/dist/plugins/jsx/MdastMdxExpressionVisitor.js +11 -0
  81. package/dist/plugins/jsx/MdastMdxJsEsmVisitor.js +8 -0
  82. package/dist/plugins/jsx/MdastMdxJsxElementVisitor.js +28 -0
  83. package/dist/plugins/jsx/index.js +97 -0
  84. package/dist/plugins/jsx/jsxTagName.js +7 -0
  85. package/dist/plugins/link/AutoLinkPlugin.js +18 -0
  86. package/dist/plugins/link/LexicalLinkVisitor.js +10 -0
  87. package/dist/plugins/link/MdastLinkVisitor.js +14 -0
  88. package/dist/plugins/link/index.js +34 -0
  89. package/dist/plugins/link-dialog/LinkDialog.js +262 -0
  90. package/dist/plugins/link-dialog/index.js +304 -0
  91. package/dist/plugins/lists/CheckListPlugin.js +270 -0
  92. package/dist/plugins/lists/LexicalListItemVisitor.js +41 -0
  93. package/dist/plugins/lists/LexicalListVisitor.js +13 -0
  94. package/dist/plugins/lists/MdastListItemVisitor.js +11 -0
  95. package/dist/plugins/lists/MdastListVisitor.js +19 -0
  96. package/dist/plugins/lists/NotesListItemNode.js +22 -0
  97. package/dist/plugins/lists/index.js +111 -0
  98. package/dist/plugins/markdown-shortcut/index.js +114 -0
  99. package/dist/plugins/maxlength/index.js +36 -0
  100. package/dist/plugins/quote/LexicalQuoteVisitor.js +10 -0
  101. package/dist/plugins/quote/MdastBlockQuoteVisitor.js +10 -0
  102. package/dist/plugins/quote/index.js +18 -0
  103. package/dist/plugins/remote/index.js +52 -0
  104. package/dist/plugins/search/index.js +360 -0
  105. package/dist/plugins/table/LexicalTableVisitor.js +10 -0
  106. package/dist/plugins/table/MdastTableVisitor.js +10 -0
  107. package/dist/plugins/table/TableEditor.js +527 -0
  108. package/dist/plugins/table/TableNode.js +208 -0
  109. package/dist/plugins/table/index.js +66 -0
  110. package/dist/plugins/thematic-break/LexicalThematicBreakVisitor.js +10 -0
  111. package/dist/plugins/thematic-break/MdastThematicBreakVisitor.js +10 -0
  112. package/dist/plugins/thematic-break/index.js +27 -0
  113. package/dist/plugins/toolbar/components/BlockTypeSelect.js +62 -0
  114. package/dist/plugins/toolbar/components/BoldItalicUnderlineToggles.js +98 -0
  115. package/dist/plugins/toolbar/components/ChangeAdmonitionType.js +43 -0
  116. package/dist/plugins/toolbar/components/ChangeCodeMirrorLanguage.js +42 -0
  117. package/dist/plugins/toolbar/components/CodeToggle.js +21 -0
  118. package/dist/plugins/toolbar/components/CreateLink.js +24 -0
  119. package/dist/plugins/toolbar/components/DiffSourceToggleWrapper.js +42 -0
  120. package/dist/plugins/toolbar/components/HighlightToggle.js +28 -0
  121. package/dist/plugins/toolbar/components/InsertAdmonition.js +34 -0
  122. package/dist/plugins/toolbar/components/InsertCodeBlock.js +23 -0
  123. package/dist/plugins/toolbar/components/InsertFrontmatter.js +28 -0
  124. package/dist/plugins/toolbar/components/InsertImage.js +29 -0
  125. package/dist/plugins/toolbar/components/InsertTable.js +25 -0
  126. package/dist/plugins/toolbar/components/InsertThematicBreak.js +23 -0
  127. package/dist/plugins/toolbar/components/KitchenSinkToolbar.js +82 -0
  128. package/dist/plugins/toolbar/components/ListsToggle.js +29 -0
  129. package/dist/plugins/toolbar/components/UndoRedo.js +60 -0
  130. package/dist/plugins/toolbar/index.js +32 -0
  131. package/dist/plugins/toolbar/primitives/DialogButton.js +130 -0
  132. package/dist/plugins/toolbar/primitives/TooltipWrap.js +17 -0
  133. package/dist/plugins/toolbar/primitives/select.js +76 -0
  134. package/dist/plugins/toolbar/primitives/toolbar.js +144 -0
  135. package/dist/registerCodeBoundaryEscape.js +40 -0
  136. package/dist/styles/lexical-theme.module.css.js +62 -0
  137. package/dist/styles/lexicalTheme.js +32 -0
  138. package/dist/styles/ui.module.css.js +296 -0
  139. package/dist/styles.css +2838 -0
  140. package/dist/utils/detectMac.js +16 -0
  141. package/dist/utils/fp.js +44 -0
  142. package/dist/utils/isPartOftheEditorUI.js +12 -0
  143. package/dist/utils/lexicalHelpers.js +185 -0
  144. package/dist/utils/makeHslTransparent.js +6 -0
  145. package/dist/utils/mergeStyleAttributes.js +22 -0
  146. package/dist/utils/uuid4.js +10 -0
  147. package/dist/utils/voidEmitter.js +15 -0
  148. package/package.json +133 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Petyo Ivanov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # @nkzw/mdx-editor
2
+
3
+ A fast, polished inline Markdown editor for React. It is a maintained fork of [`@mdxeditor/editor`](https://github.com/mdx-editor/editor) with upgraded Lexical internals and editing behavior tuned for keyboard-first document and comment authoring.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ pnpm add @nkzw/mdx-editor
9
+ ```
10
+
11
+ ```tsx
12
+ import { MarkdownEditor } from '@nkzw/mdx-editor'
13
+ import '@nkzw/mdx-editor/styles.css'
14
+
15
+ export function Editor() {
16
+ const [markdown, setMarkdown] = useState('# Hello')
17
+
18
+ return <MarkdownEditor onChange={setMarkdown} value={markdown} />
19
+ }
20
+ ```
21
+
22
+ The default editor includes headings, lists, quotes, links, tables, thematic breaks, fenced code blocks, Markdown shortcuts, and canonical Markdown serialization. It intentionally has no toolbar.
23
+
24
+ ## Embedded editors
25
+
26
+ ```tsx
27
+ <MarkdownEditor
28
+ colorScheme="inherit"
29
+ density="compact"
30
+ onChange={setDraft}
31
+ value={draft}
32
+ variant="embedded"
33
+ />
34
+ ```
35
+
36
+ Use `onKeyDown` for host application shortcuts and `onHeightChange` when the editor lives inside a virtualized layout.
37
+
38
+ ## Persistence
39
+
40
+ File and network synchronization are optional:
41
+
42
+ ```tsx
43
+ import {
44
+ PersistentMarkdownEditor,
45
+ type MarkdownPersistenceAdapter
46
+ } from '@nkzw/mdx-editor/persistence'
47
+
48
+ const adapter: MarkdownPersistenceAdapter<Document> = {
49
+ async save({ content, document, keepalive }) {
50
+ // Save with document.version as the optimistic concurrency token.
51
+ return { document: await save(content, document, keepalive), status: 'saved' }
52
+ }
53
+ }
54
+ ```
55
+
56
+ The persistence layer includes debounced saves, a maximum save wait, lifecycle flushing, optimistic concurrency, same-content conflict suppression, disk update reconciliation, and default conflict/error UI.
57
+
58
+ ## Styling
59
+
60
+ Defaults reproduce the original Notes document editor. Override variables on the editor class:
61
+
62
+ ```css
63
+ .comment-editor {
64
+ --mdx-editor-bg: transparent;
65
+ --mdx-editor-border: transparent;
66
+ --mdx-editor-font-size: 13px;
67
+ --mdx-editor-line-height: 1.45;
68
+ --mdx-editor-padding: 9px 10px 10px;
69
+ }
70
+ ```
71
+
72
+ The primary variables are `--mdx-editor-bg`, `--mdx-editor-border`, `--mdx-editor-text`, `--mdx-editor-muted`, `--mdx-editor-accent`, `--mdx-editor-accent-soft`, `--mdx-editor-code-bg`, `--mdx-editor-hover`, `--mdx-editor-selection`, `--mdx-editor-table-stripe`, `--mdx-editor-font`, `--mdx-editor-mono-font`, `--mdx-editor-radius`, `--mdx-editor-padding`, `--mdx-editor-font-size`, and `--mdx-editor-line-height`.
73
+
74
+ ## Advanced API
75
+
76
+ The complete low-level fork is available from:
77
+
78
+ ```ts
79
+ import { MDXEditor, realmPlugin } from '@nkzw/mdx-editor/core'
80
+ ```
81
+
82
+ See [UPSTREAM.md](./UPSTREAM.md) for the upstream baseline and maintained patch set.
83
+
84
+ ## License
85
+
86
+ MIT. Original MDXEditor copyright and license are retained in [LICENSE](./LICENSE).
package/UPSTREAM.md ADDED
@@ -0,0 +1,21 @@
1
+ # Upstream
2
+
3
+ This package is a source fork of [`@mdxeditor/editor`](https://github.com/mdx-editor/editor).
4
+
5
+ - Upstream version: `4.0.4`
6
+ - Upstream tag: `v4.0.4`
7
+ - Upstream commit: `d0990c33be0441c841232613d03bde16447b8203`
8
+ - License: MIT, retained in `LICENSE`
9
+
10
+ ## Maintained changes
11
+
12
+ - Upgrade all Lexical packages from `0.35.0` to `0.45.0`.
13
+ - Use TypeScript's `bundler` module resolution for Lexical's package exports.
14
+ - Use the canonical Lexical extension horizontal-rule type during Markdown export.
15
+ - Fix inline-code delimiter conversion, IME completion, boundary-arrow navigation, and undo behavior.
16
+ - Fix first/last list import and caret behavior when removing the first list item.
17
+ - Add the `---` plus Enter horizontal-rule shortcut without an extra blank line.
18
+ - Refine links, icons, and table editing controls.
19
+ - Add a high-level controlled `MarkdownEditor` API and optional persistence adapter.
20
+
21
+ When syncing upstream, preserve these changes as focused commits and run `pnpm check`.
@@ -0,0 +1,75 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import styles from "./styles/ui.module.css.js";
3
+ const EditorIcon = ({ className, name }) => {
4
+ const paths = {
5
+ "add-column": /* @__PURE__ */ jsxs(Fragment, { children: [
6
+ /* @__PURE__ */ jsx("rect", { x: "7", y: "3", width: "10", height: "18", rx: "2" }),
7
+ /* @__PURE__ */ jsx("path", { d: "M3 9v6M1 12h4" })
8
+ ] }),
9
+ "add-row": /* @__PURE__ */ jsxs(Fragment, { children: [
10
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "7", width: "18", height: "10", rx: "2" }),
11
+ /* @__PURE__ */ jsx("path", { d: "M9 21h6M12 19v4" })
12
+ ] }),
13
+ "align-center": /* @__PURE__ */ jsx("path", { d: "M4 6h16M7 10h10M4 14h16M7 18h10" }),
14
+ "align-left": /* @__PURE__ */ jsx("path", { d: "M4 6h16M4 10h10M4 14h16M4 18h10" }),
15
+ "align-right": /* @__PURE__ */ jsx("path", { d: "M4 6h16M10 10h10M4 14h16M10 18h10" }),
16
+ check: /* @__PURE__ */ jsx("path", { d: "m5 12 4 4L19 6" }),
17
+ "chevron-down": /* @__PURE__ */ jsx("path", { d: "m7 9 5 5 5-5" }),
18
+ copy: /* @__PURE__ */ jsxs(Fragment, { children: [
19
+ /* @__PURE__ */ jsx("rect", { width: "13", height: "13", x: "9", y: "9", rx: "2" }),
20
+ /* @__PURE__ */ jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
21
+ ] }),
22
+ delete: /* @__PURE__ */ jsxs(Fragment, { children: [
23
+ /* @__PURE__ */ jsx("path", { d: "M4 7h16M9 7V4h6v3M7 7l1 14h8l1-14" }),
24
+ /* @__PURE__ */ jsx("path", { d: "M10 11v6M14 11v6" })
25
+ ] }),
26
+ edit: /* @__PURE__ */ jsxs(Fragment, { children: [
27
+ /* @__PURE__ */ jsx("path", { d: "M12 20h9" }),
28
+ /* @__PURE__ */ jsx("path", { d: "M16.5 3.5a2.1 2.1 0 0 1 3 3L8 18l-4 1 1-4Z" })
29
+ ] }),
30
+ external: /* @__PURE__ */ jsxs(Fragment, { children: [
31
+ /* @__PURE__ */ jsx("path", { d: "M15 3h6v6" }),
32
+ /* @__PURE__ */ jsx("path", { d: "m10 14 11-11" }),
33
+ /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" })
34
+ ] }),
35
+ "insert-column-left": /* @__PURE__ */ jsxs(Fragment, { children: [
36
+ /* @__PURE__ */ jsx("rect", { x: "10", y: "4", width: "10", height: "16", rx: "2" }),
37
+ /* @__PURE__ */ jsx("path", { d: "M5 8v8M1 12h8" })
38
+ ] }),
39
+ "insert-column-right": /* @__PURE__ */ jsxs(Fragment, { children: [
40
+ /* @__PURE__ */ jsx("rect", { x: "4", y: "4", width: "10", height: "16", rx: "2" }),
41
+ /* @__PURE__ */ jsx("path", { d: "M19 8v8M15 12h8" })
42
+ ] }),
43
+ "insert-row-above": /* @__PURE__ */ jsxs(Fragment, { children: [
44
+ /* @__PURE__ */ jsx("rect", { x: "4", y: "10", width: "16", height: "10", rx: "2" }),
45
+ /* @__PURE__ */ jsx("path", { d: "M8 5h8M12 1v8" })
46
+ ] }),
47
+ "insert-row-below": /* @__PURE__ */ jsxs(Fragment, { children: [
48
+ /* @__PURE__ */ jsx("rect", { x: "4", y: "4", width: "16", height: "10", rx: "2" }),
49
+ /* @__PURE__ */ jsx("path", { d: "M8 19h8M12 15v8" })
50
+ ] }),
51
+ more: /* @__PURE__ */ jsxs(Fragment, { children: [
52
+ /* @__PURE__ */ jsx("circle", { cx: "5", cy: "12", r: "1" }),
53
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1" }),
54
+ /* @__PURE__ */ jsx("circle", { cx: "19", cy: "12", r: "1" })
55
+ ] }),
56
+ unlink: /* @__PURE__ */ jsxs(Fragment, { children: [
57
+ /* @__PURE__ */ jsx("path", { d: "m18.8 18.8-3.6-3.6" }),
58
+ /* @__PURE__ */ jsx("path", { d: "m8.8 8.8-3.6-3.6" }),
59
+ /* @__PURE__ */ jsx("path", { d: "M9.9 4.2 11 3.1a5 5 0 0 1 7.1 7.1L17 11.3" }),
60
+ /* @__PURE__ */ jsx("path", { d: "m14.1 19.8-1.1 1.1a5 5 0 0 1-7.1-7.1L7 12.7" })
61
+ ] })
62
+ };
63
+ return /* @__PURE__ */ jsx(
64
+ "svg",
65
+ {
66
+ "aria-hidden": "true",
67
+ className: className ? `${styles.editorIcon} ${className}` : styles.editorIcon,
68
+ viewBox: "0 0 24 24",
69
+ children: paths[name]
70
+ }
71
+ );
72
+ };
73
+ export {
74
+ EditorIcon
75
+ };
@@ -0,0 +1,20 @@
1
+ const DEFAULT_FORMAT = 0;
2
+ const IS_BOLD = 1;
3
+ const IS_ITALIC = 2;
4
+ const IS_STRIKETHROUGH = 4;
5
+ const IS_UNDERLINE = 8;
6
+ const IS_CODE = 16;
7
+ const IS_SUBSCRIPT = 32;
8
+ const IS_SUPERSCRIPT = 64;
9
+ const IS_HIGHLIGHT = 128;
10
+ export {
11
+ DEFAULT_FORMAT,
12
+ IS_BOLD,
13
+ IS_CODE,
14
+ IS_HIGHLIGHT,
15
+ IS_ITALIC,
16
+ IS_STRIKETHROUGH,
17
+ IS_SUBSCRIPT,
18
+ IS_SUPERSCRIPT,
19
+ IS_UNDERLINE
20
+ };
@@ -0,0 +1,189 @@
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
+ import { usePublisher, useCellValue, useCellValues, useRealm } from "@mdxeditor/gurx";
3
+ import React from "react";
4
+ import { corePlugin, editorRootElementRef$, editorWrapperElementRef$, rootEditor$, useTranslation, contentEditableRef$, contentEditableWrapperElement$, contentEditableClassName$, spellCheck$, composerChildren$, topAreaChildren$, editorWrappers$, placeholder$, bottomAreaChildren$, viewMode$, activeEditor$, exportVisitors$, toMarkdownExtensions$, toMarkdownOptions$, jsxComponentDescriptors$, jsxIsAvailable$, insertMarkdown$, setMarkdown$, markdownSourceEditorValue$, markdown$ } from "./plugins/core/index.js";
5
+ import { RealmWithPlugins } from "./RealmWithPlugins.js";
6
+ import { createLexicalComposerContext, LexicalComposerContext } from "@lexical/react/LexicalComposerContext";
7
+ import { ContentEditable } from "@lexical/react/LexicalContentEditable";
8
+ import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary";
9
+ import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
10
+ import classNames from "classnames";
11
+ import { defaultSvgIcons } from "./defaultSvgIcons.js";
12
+ import { lexicalTheme } from "./styles/lexicalTheme.js";
13
+ import styles from "./styles/ui.module.css.js";
14
+ import { noop } from "./utils/fp.js";
15
+ import { getSelectionAsMarkdown } from "./utils/lexicalHelpers.js";
16
+ const LexicalProvider = ({ children }) => {
17
+ const rootEditor = useCellValue(rootEditor$);
18
+ const composerContextValue = React.useMemo(() => {
19
+ return [rootEditor, createLexicalComposerContext(null, lexicalTheme)];
20
+ }, [rootEditor]);
21
+ return /* @__PURE__ */ jsx(LexicalComposerContext.Provider, { value: composerContextValue, children });
22
+ };
23
+ const RichTextEditor = () => {
24
+ const t = useTranslation();
25
+ const setContentEditableRef = usePublisher(contentEditableRef$);
26
+ const setEditorRootWrapperElement = usePublisher(contentEditableWrapperElement$);
27
+ const onRef = (el) => {
28
+ setEditorRootWrapperElement(el);
29
+ setContentEditableRef(el ? { current: el } : null);
30
+ };
31
+ const [contentEditableClassName, spellCheck, composerChildren, topAreaChildren, editorWrappers, placeholder, bottomAreaChildren] = useCellValues(
32
+ contentEditableClassName$,
33
+ spellCheck$,
34
+ composerChildren$,
35
+ topAreaChildren$,
36
+ editorWrappers$,
37
+ placeholder$,
38
+ bottomAreaChildren$
39
+ );
40
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
41
+ topAreaChildren.map((Child, index) => /* @__PURE__ */ jsx(Child, {}, index)),
42
+ /* @__PURE__ */ jsx(RenderRecursiveWrappers, { wrappers: editorWrappers, children: /* @__PURE__ */ jsx("div", { className: classNames(styles.rootContentEditableWrapper, "mdxeditor-root-contenteditable"), children: /* @__PURE__ */ jsx(
43
+ RichTextPlugin,
44
+ {
45
+ contentEditable: /* @__PURE__ */ jsx("div", { ref: onRef, children: /* @__PURE__ */ jsx(
46
+ ContentEditable,
47
+ {
48
+ className: classNames(styles.contentEditable, contentEditableClassName),
49
+ ariaLabel: t("contentArea.editableMarkdown", "editable markdown"),
50
+ spellCheck
51
+ }
52
+ ) }),
53
+ placeholder: /* @__PURE__ */ jsx("div", { className: classNames(styles.contentEditable, styles.placeholder, contentEditableClassName), children: /* @__PURE__ */ jsx("p", { children: placeholder }) }),
54
+ ErrorBoundary: LexicalErrorBoundary
55
+ }
56
+ ) }) }),
57
+ composerChildren.map((Child, index) => /* @__PURE__ */ jsx(Child, {}, index)),
58
+ bottomAreaChildren.map((Child, index) => /* @__PURE__ */ jsx(Child, {}, index))
59
+ ] });
60
+ };
61
+ const DEFAULT_MARKDOWN_OPTIONS = {
62
+ listItemIndent: "one"
63
+ };
64
+ const defaultIconComponentFor = (name) => {
65
+ return defaultSvgIcons[name];
66
+ };
67
+ function defaultTranslation(key, defaultValue, interpolations = {}) {
68
+ let value = defaultValue;
69
+ for (const [k, v] of Object.entries(interpolations)) {
70
+ value = value.replaceAll(`{{${k}}}`, String(v));
71
+ }
72
+ return value;
73
+ }
74
+ const RenderRecursiveWrappers = ({ wrappers, children }) => {
75
+ if (wrappers.length === 0) {
76
+ return /* @__PURE__ */ jsx(Fragment, { children });
77
+ }
78
+ const Wrapper = wrappers[0];
79
+ return /* @__PURE__ */ jsx(Wrapper, { children: /* @__PURE__ */ jsx(RenderRecursiveWrappers, { wrappers: wrappers.slice(1), children }) });
80
+ };
81
+ const EditorRootElement = ({ children, className, overlayContainer }) => {
82
+ const editorRootElementRef = React.useRef(null);
83
+ const wrapperElementRef = React.useRef(null);
84
+ const setEditorRootElementRef = usePublisher(editorRootElementRef$);
85
+ const setEditorWrapperElementRef = usePublisher(editorWrapperElementRef$);
86
+ React.useEffect(() => {
87
+ const popupContainer = document.createElement("div");
88
+ popupContainer.classList.add(
89
+ "mdxeditor-popup-container",
90
+ styles.editorRoot,
91
+ styles.popupContainer,
92
+ ...(className ?? "").trim().split(" ").filter(Boolean)
93
+ );
94
+ const container = overlayContainer ?? document.body;
95
+ container.appendChild(popupContainer);
96
+ editorRootElementRef.current = popupContainer;
97
+ setEditorRootElementRef(editorRootElementRef);
98
+ setEditorWrapperElementRef(wrapperElementRef);
99
+ return () => {
100
+ popupContainer.remove();
101
+ };
102
+ }, [className, editorRootElementRef, overlayContainer, setEditorRootElementRef, setEditorWrapperElementRef]);
103
+ return /* @__PURE__ */ jsx("div", { className: classNames("mdxeditor", styles.editorRoot, styles.editorWrapper, className), ref: wrapperElementRef, children });
104
+ };
105
+ const Methods = ({ mdxRef }) => {
106
+ const realm = useRealm();
107
+ React.useImperativeHandle(
108
+ mdxRef,
109
+ () => {
110
+ return {
111
+ getMarkdown: () => {
112
+ const viewMode = realm.getValue(viewMode$);
113
+ if (viewMode === "source" || viewMode === "diff") {
114
+ return realm.getValue(markdownSourceEditorValue$);
115
+ }
116
+ return realm.getValue(markdown$);
117
+ },
118
+ setMarkdown: (markdown) => {
119
+ realm.pub(setMarkdown$, markdown);
120
+ },
121
+ insertMarkdown: (markdown) => {
122
+ realm.pub(insertMarkdown$, markdown);
123
+ },
124
+ focus: (callbackFn, opts) => {
125
+ realm.getValue(rootEditor$)?.focus(callbackFn, opts);
126
+ },
127
+ getContentEditableHTML: () => {
128
+ return realm.getValue(contentEditableRef$)?.current.innerHTML ?? "";
129
+ },
130
+ getSelectionMarkdown: () => {
131
+ const viewMode = realm.getValue(viewMode$);
132
+ if (viewMode === "source" || viewMode === "diff") {
133
+ return "";
134
+ }
135
+ const activeEditor = realm.getValue(activeEditor$);
136
+ if (!activeEditor) {
137
+ return "";
138
+ }
139
+ realm.getValue(exportVisitors$);
140
+ realm.getValue(toMarkdownExtensions$);
141
+ realm.getValue(toMarkdownOptions$);
142
+ realm.getValue(jsxComponentDescriptors$);
143
+ realm.getValue(jsxIsAvailable$);
144
+ return getSelectionAsMarkdown(activeEditor);
145
+ }
146
+ };
147
+ },
148
+ [realm]
149
+ );
150
+ return null;
151
+ };
152
+ const MDXEditor = React.forwardRef((props, ref) => {
153
+ return /* @__PURE__ */ jsxs(
154
+ RealmWithPlugins,
155
+ {
156
+ plugins: [
157
+ corePlugin({
158
+ contentEditableClassName: props.contentEditableClassName ?? "",
159
+ spellCheck: props.spellCheck ?? true,
160
+ initialMarkdown: props.markdown,
161
+ onChange: props.onChange ?? noop,
162
+ onBlur: props.onBlur ?? noop,
163
+ toMarkdownOptions: props.toMarkdownOptions ?? DEFAULT_MARKDOWN_OPTIONS,
164
+ autoFocus: props.autoFocus ?? false,
165
+ placeholder: props.placeholder ?? "",
166
+ readOnly: Boolean(props.readOnly),
167
+ iconComponentFor: props.iconComponentFor ?? defaultIconComponentFor,
168
+ suppressHtmlProcessing: props.suppressHtmlProcessing ?? false,
169
+ onError: props.onError ?? noop,
170
+ translation: props.translation ?? defaultTranslation,
171
+ trim: props.trim ?? true,
172
+ lexicalTheme: props.lexicalTheme,
173
+ ..."editorState" in props ? { editorState: props.editorState } : {},
174
+ suppressSharedHistory: props.suppressSharedHistory ?? false,
175
+ additionalLexicalNodes: props.additionalLexicalNodes ?? [],
176
+ lexicalEditorNamespace: props.lexicalEditorNamespace ?? "MDXEditor"
177
+ }),
178
+ ...props.plugins ?? []
179
+ ],
180
+ children: [
181
+ /* @__PURE__ */ jsx(EditorRootElement, { className: props.className, overlayContainer: props.overlayContainer, children: /* @__PURE__ */ jsx(LexicalProvider, { children: /* @__PURE__ */ jsx(RichTextEditor, {}) }) }),
182
+ /* @__PURE__ */ jsx(Methods, { mdxRef: ref })
183
+ ]
184
+ }
185
+ );
186
+ });
187
+ export {
188
+ MDXEditor
189
+ };