@mdxeditor/editor 1.11.1 → 1.11.3

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.
@@ -91,11 +91,12 @@ export interface ExportLexicalTreeOptions {
91
91
  visitors: LexicalVisitor[];
92
92
  jsxComponentDescriptors: JsxComponentDescriptor[];
93
93
  jsxIsAvailable: boolean;
94
+ addImportStatements?: boolean;
94
95
  }
95
96
  /**
96
97
  * @internal
97
98
  */
98
- export declare function exportLexicalTreeToMdast({ root, visitors, jsxComponentDescriptors, jsxIsAvailable }: ExportLexicalTreeOptions): Mdast.Root;
99
+ export declare function exportLexicalTreeToMdast({ root, visitors, jsxComponentDescriptors, jsxIsAvailable, addImportStatements }: ExportLexicalTreeOptions): Mdast.Root;
99
100
  /**
100
101
  * @internal
101
102
  */
@@ -9,7 +9,8 @@ function exportLexicalTreeToMdast({
9
9
  root,
10
10
  visitors,
11
11
  jsxComponentDescriptors,
12
- jsxIsAvailable
12
+ jsxIsAvailable,
13
+ addImportStatements = true
13
14
  }) {
14
15
  let unistRoot = null;
15
16
  const referredComponents = /* @__PURE__ */ new Set();
@@ -120,10 +121,12 @@ function exportLexicalTreeToMdast({
120
121
  );
121
122
  const typedRoot = unistRoot;
122
123
  const frontmatter = typedRoot.children.find((child) => child.type === "yaml");
123
- if (frontmatter) {
124
- typedRoot.children.splice(typedRoot.children.indexOf(frontmatter) + 1, 0, ...imports);
125
- } else {
126
- typedRoot.children.unshift(...imports);
124
+ if (addImportStatements) {
125
+ if (frontmatter) {
126
+ typedRoot.children.splice(typedRoot.children.indexOf(frontmatter) + 1, 0, ...imports);
127
+ } else {
128
+ typedRoot.children.unshift(...imports);
129
+ }
127
130
  }
128
131
  fixWrappingWhitespace(typedRoot, []);
129
132
  collapseNestedHtmlTags(typedRoot);
@@ -133,7 +136,7 @@ function exportLexicalTreeToMdast({
133
136
  return typedRoot;
134
137
  }
135
138
  function collapseNestedHtmlTags(node) {
136
- if ("children" in node) {
139
+ if ("children" in node && node.children) {
137
140
  if (isMdastHTMLNode(node) && node.children.length === 1) {
138
141
  const onlyChild = node.children[0];
139
142
  if (onlyChild.type === "mdxJsxTextElement" && onlyChild.name === "span") {
@@ -212,7 +215,7 @@ function fixWrappingWhitespace(node, parentChain) {
212
215
  }
213
216
  }
214
217
  }
215
- if (Object.hasOwn(node, "children")) {
218
+ if ("children" in node && node.children) {
216
219
  const nodeAsParent = node;
217
220
  nodeAsParent.children.forEach((child) => fixWrappingWhitespace(child, [...parentChain, nodeAsParent]));
218
221
  }
package/dist/index.d.ts CHANGED
@@ -51,4 +51,12 @@ export * from './plugins/toolbar/primitives/TooltipWrap';
51
51
  export * from './plugins/toolbar/primitives/select';
52
52
  export * from './plugins/core/NestedLexicalEditor';
53
53
  export * from './plugins/core/PropertyPopover';
54
+ export * from './utils/detectMac';
55
+ export * from './utils/fp';
56
+ export * from './utils/isPartOftheEditorUI';
57
+ export * from './utils/lexicalHelpers';
58
+ export * from './utils/makeHslTransparent';
59
+ export * from './utils/uuid4';
60
+ export * from './utils/voidEmitter';
61
+ export * from './utils/whitespaceConversion';
54
62
  export * from './gurx';
package/dist/index.js CHANGED
@@ -48,6 +48,14 @@ import { TooltipWrap } from "./plugins/toolbar/primitives/TooltipWrap.js";
48
48
  import { Select, SelectButtonTrigger, SelectContent, SelectItem, SelectTrigger } from "./plugins/toolbar/primitives/select.js";
49
49
  import { NestedEditorsContext, NestedLexicalEditor, useLexicalNodeRemove, useMdastNodeUpdater, useNestedEditorContext } from "./plugins/core/NestedLexicalEditor.js";
50
50
  import { PropertyPopover } from "./plugins/core/PropertyPopover.js";
51
+ import { CAN_USE_DOM, IS_APPLE, controlOrMeta } from "./utils/detectMac.js";
52
+ import { always, call, compose, curry1to0, curry2to1, joinProc, noop, prop, tap, thrush } from "./utils/fp.js";
53
+ import { isPartOftheEditorUI } from "./utils/isPartOftheEditorUI.js";
54
+ import { fromWithinEditorRead, getSelectedNode, getSelectionRectangle, getStateAsMarkdown } from "./utils/lexicalHelpers.js";
55
+ import { makeHslTransparent } from "./utils/makeHslTransparent.js";
56
+ import { uuidv4 } from "./utils/uuid4.js";
57
+ import { voidEmitter } from "./utils/voidEmitter.js";
58
+ import { WHITESPACE_MARKER, replaceWhitespace } from "./utils/whitespaceConversion.js";
51
59
  import { $createGenericHTMLNode, $isGenericHTMLNode, GenericHTMLNode } from "./plugins/core/GenericHTMLNode.js";
52
60
  import { $createImageNode, $isImageNode, ImageNode } from "./plugins/image/ImageNode.js";
53
61
  import { useCodeBlockEditorContext } from "./plugins/codeblock/CodeBlockNode.js";
@@ -66,6 +74,7 @@ export {
66
74
  Button,
67
75
  ButtonOrDropdownButton,
68
76
  ButtonWithTooltip,
77
+ CAN_USE_DOM,
69
78
  ChangeAdmonitionType,
70
79
  ChangeCodeMirrorLanguage,
71
80
  CodeMirrorEditor,
@@ -78,6 +87,7 @@ export {
78
87
  GenericHTMLNode,
79
88
  GenericJsxEditor,
80
89
  INSERT_IMAGE_COMMAND,
90
+ IS_APPLE,
81
91
  ImageNode,
82
92
  InsertAdmonition,
83
93
  InsertCodeBlock,
@@ -111,15 +121,22 @@ export {
111
121
  ToolbarToggleItem,
112
122
  TooltipWrap,
113
123
  UndoRedo,
124
+ WHITESPACE_MARKER,
125
+ always,
126
+ call,
114
127
  codeBlockPlugin,
115
128
  codeBlockPluginHooks,
116
129
  codeBlockSystem,
117
130
  codeMirrorHooks,
118
131
  codeMirrorPlugin,
119
132
  codeMirrorSystem,
133
+ compose,
134
+ controlOrMeta,
120
135
  corePlugin,
121
136
  corePluginHooks,
122
137
  coreSystem,
138
+ curry1to0,
139
+ curry2to1,
123
140
  defaultComparator,
124
141
  diffSourcePlugin,
125
142
  diffSourcePluginHooks,
@@ -129,10 +146,14 @@ export {
129
146
  directivesSystem,
130
147
  exportLexicalTreeToMdast,
131
148
  exportMarkdownFromLexical,
149
+ fromWithinEditorRead,
132
150
  frontmatterPlugin,
133
151
  frontmatterPluginHooks,
134
152
  frontmatterSystem,
135
153
  getRealmFactory,
154
+ getSelectedNode,
155
+ getSelectionRectangle,
156
+ getStateAsMarkdown,
136
157
  headingsPlugin,
137
158
  headingsPluginHooks,
138
159
  headingsSystem,
@@ -141,6 +162,8 @@ export {
141
162
  imageSystem,
142
163
  importMarkdownToLexical,
143
164
  importMdastTreeToLexical,
165
+ isPartOftheEditorUI,
166
+ joinProc,
144
167
  jsxPlugin,
145
168
  jsxPluginHooks,
146
169
  jsxSystem,
@@ -150,13 +173,17 @@ export {
150
173
  listsPlugin,
151
174
  listsPluginHooks,
152
175
  listsSystem,
176
+ makeHslTransparent,
153
177
  markdownShortcutPlugin,
178
+ noop,
179
+ prop,
154
180
  quotePlugin,
155
181
  quotePluginHooks,
156
182
  realm,
157
183
  realmFactory,
158
184
  realmFactoryToComponent,
159
185
  realmPlugin,
186
+ replaceWhitespace,
160
187
  sandpackPlugin,
161
188
  sandpackPluginHooks,
162
189
  sandpackSystem,
@@ -165,9 +192,11 @@ export {
165
192
  tablePlugin,
166
193
  tablePluginHooks,
167
194
  tableSystem,
195
+ tap,
168
196
  thematicBreakPlugin,
169
197
  thematicBreakPluginHooks,
170
198
  thematicBreakSystem,
199
+ thrush,
171
200
  toolbarPlugin,
172
201
  toolbarPluginHooks,
173
202
  toolbarSystem,
@@ -175,5 +204,7 @@ export {
175
204
  useHasPlugin,
176
205
  useLexicalNodeRemove,
177
206
  useMdastNodeUpdater,
178
- useNestedEditorContext
207
+ useNestedEditorContext,
208
+ uuidv4,
209
+ voidEmitter
179
210
  };
@@ -3,12 +3,13 @@ import { IS_CODE, IS_ITALIC, IS_BOLD, IS_UNDERLINE } from "../../FormatConstants
3
3
  function isMdastText(mdastNode) {
4
4
  return mdastNode.type === "text";
5
5
  }
6
+ const JOINABLE_TAGS = ["u", "span"];
6
7
  const LexicalTextVisitor = {
7
8
  shouldJoin: (prevNode, currentNode) => {
8
9
  if (["text", "emphasis", "strong"].includes(prevNode.type)) {
9
10
  return prevNode.type === currentNode.type;
10
11
  }
11
- if (prevNode.type === "mdxJsxTextElement" && currentNode.type === "mdxJsxTextElement") {
12
+ if (prevNode.type === "mdxJsxTextElement" && currentNode.type === "mdxJsxTextElement" && JOINABLE_TAGS.includes(currentNode.name)) {
12
13
  const currentMdxNode = currentNode;
13
14
  return prevNode.name === currentMdxNode.name && JSON.stringify(prevNode.attributes) === JSON.stringify(currentMdxNode.attributes);
14
15
  }
@@ -1,6 +1,6 @@
1
1
  import { $addUpdateTag, $getNodeByKey, createEditor, $getRoot, BLUR_COMMAND, COMMAND_PRIORITY_EDITOR, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_HIGH, KEY_BACKSPACE_COMMAND, COMMAND_PRIORITY_CRITICAL } from "lexical";
2
2
  import React__default from "react";
3
- import { corePluginHooks, NESTED_EDITOR_UPDATED_COMMAND } from "./index.js";
3
+ import { NESTED_EDITOR_UPDATED_COMMAND, corePluginHooks } from "./index.js";
4
4
  import { ContentEditable } from "@lexical/react/LexicalContentEditable.js";
5
5
  import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary.js";
6
6
  import { LexicalNestedComposer } from "@lexical/react/LexicalNestedComposer.js";
@@ -23,13 +23,17 @@ function useNestedEditorContext() {
23
23
  function useMdastNodeUpdater() {
24
24
  const { parentEditor, mdastNode, lexicalNode } = useNestedEditorContext();
25
25
  return function updateMdastNode(node) {
26
- parentEditor.update(() => {
27
- $addUpdateTag("history-push");
28
- const currentNode = $getNodeByKey(lexicalNode.getKey());
29
- if (currentNode) {
30
- currentNode.setMdastNode({ ...mdastNode, ...node });
31
- }
32
- });
26
+ parentEditor.update(
27
+ () => {
28
+ $addUpdateTag("history-push");
29
+ const currentNode = $getNodeByKey(lexicalNode.getKey());
30
+ if (currentNode) {
31
+ currentNode.setMdastNode({ ...mdastNode, ...node });
32
+ }
33
+ },
34
+ { discrete: true }
35
+ );
36
+ parentEditor.dispatchCommand(NESTED_EDITOR_UPDATED_COMMAND, void 0);
33
37
  };
34
38
  }
35
39
  function useLexicalNodeRemove() {
@@ -98,7 +102,8 @@ const NestedLexicalEditor = function(props) {
98
102
  root: $getRoot(),
99
103
  visitors: exportVisitors,
100
104
  jsxComponentDescriptors,
101
- jsxIsAvailable
105
+ jsxIsAvailable,
106
+ addImportStatements: false
102
107
  });
103
108
  const content2 = block ? mdast.children : mdast.children[0].children;
104
109
  updateMdastNode(getUpdatedMdastNode(structuredClone(mdastNode), content2));
@@ -330,6 +330,9 @@ const coreSystem = system((r) => {
330
330
  setTimeout(() => node.select());
331
331
  }
332
332
  });
333
+ setTimeout(() => {
334
+ theEditor.dispatchCommand(NESTED_EDITOR_UPDATED_COMMAND, void 0);
335
+ });
333
336
  }
334
337
  }
335
338
  });
package/dist/utils/fp.js CHANGED
@@ -1,14 +1,44 @@
1
+ function compose(a, b) {
2
+ return (arg) => a(b(arg));
3
+ }
4
+ function thrush(arg, proc) {
5
+ return proc(arg);
6
+ }
7
+ function curry2to1(proc, arg1) {
8
+ return (arg2) => proc(arg1, arg2);
9
+ }
10
+ function curry1to0(proc, arg) {
11
+ return () => proc(arg);
12
+ }
13
+ function prop(property) {
14
+ return (object) => object[property];
15
+ }
1
16
  function tap(arg, proc) {
2
17
  proc(arg);
3
18
  return arg;
4
19
  }
20
+ function call(proc) {
21
+ proc();
22
+ }
5
23
  function always(value) {
6
24
  return () => value;
7
25
  }
26
+ function joinProc(...procs) {
27
+ return () => {
28
+ procs.map(call);
29
+ };
30
+ }
8
31
  function noop() {
9
32
  }
10
33
  export {
11
34
  always,
35
+ call,
36
+ compose,
37
+ curry1to0,
38
+ curry2to1,
39
+ joinProc,
12
40
  noop,
13
- tap
41
+ prop,
42
+ tap,
43
+ thrush
14
44
  };
@@ -1,5 +1,14 @@
1
- import { $getSelection } from "lexical";
1
+ import { $getSelection, $getRoot } from "lexical";
2
2
  import { $isAtNodeEnd } from "@lexical/selection";
3
+ import { tap } from "./fp.js";
4
+ import { exportMarkdownFromLexical } from "../exportMarkdownFromLexical.js";
5
+ function fromWithinEditorRead(editor, fn) {
6
+ let result = null;
7
+ editor.getEditorState().read(() => {
8
+ result = fn();
9
+ });
10
+ return result;
11
+ }
3
12
  function getSelectedNode(selection) {
4
13
  try {
5
14
  const anchor = selection.anchor;
@@ -56,7 +65,16 @@ function getSelectionRectangle(editor) {
56
65
  }
57
66
  return null;
58
67
  }
68
+ function getStateAsMarkdown(editor, exportParams) {
69
+ return tap({ markdown: "" }, (result) => {
70
+ editor.getEditorState().read(() => {
71
+ result.markdown = exportMarkdownFromLexical({ root: $getRoot(), ...exportParams });
72
+ });
73
+ }).markdown;
74
+ }
59
75
  export {
76
+ fromWithinEditorRead,
60
77
  getSelectedNode,
61
- getSelectionRectangle
78
+ getSelectionRectangle,
79
+ getStateAsMarkdown
62
80
  };
@@ -0,0 +1 @@
1
+ export declare function makeHslTransparent(hsl: string, alpha: number): string;
@@ -0,0 +1,6 @@
1
+ function makeHslTransparent(hsl, alpha) {
2
+ return hsl.replace("hsl", "hsla").replace(")", `, ${alpha})`);
3
+ }
4
+ export {
5
+ makeHslTransparent
6
+ };
@@ -0,0 +1,2 @@
1
+ export declare const WHITESPACE_MARKER = "\u00A0";
2
+ export declare function replaceWhitespace(str: string): string;
@@ -0,0 +1,9 @@
1
+ const WHITESPACE_MARKER = " ";
2
+ const WHITESPACE_REGEX = /^\s+|\s+$/g;
3
+ function replaceWhitespace(str) {
4
+ return str.replace(WHITESPACE_REGEX, (spaces) => WHITESPACE_MARKER.repeat(spaces.length));
5
+ }
6
+ export {
7
+ WHITESPACE_MARKER,
8
+ replaceWhitespace
9
+ };
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "private": false,
10
10
  "sideEffects": false,
11
11
  "type": "module",
12
- "version": "1.11.1",
12
+ "version": "1.11.3",
13
13
  "description": "React component for rich text markdown editing",
14
14
  "scripts": {
15
15
  "build": "vite build",
@@ -232,6 +232,11 @@
232
232
  "import": "./dist/plugins/core/NestedLexicalEditor.js",
233
233
  "default": "./dist/plugins/core/NestedLexicalEditor.js"
234
234
  },
235
+ "./utils": {
236
+ "types": "./dist/utils.d.ts",
237
+ "import": "./dist/utils.js",
238
+ "default": "./dist/utils.js"
239
+ },
235
240
  "./plugins/codeblock": {
236
241
  "types": "./dist/plugins/codeblock/index.d.ts",
237
242
  "import": "./dist/plugins/codeblock/index.js",