@mdxeditor/editor 3.28.0 → 3.29.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/exportMarkdownFromLexical.js +25 -8
- package/dist/importMarkdownToLexical.js +28 -0
- package/dist/index.d.ts +18 -2
- package/dist/plugins/core/LexicalTextVisitor.js +27 -27
- package/dist/plugins/jsx/LexicalJsxNode.js +11 -5
- package/dist/plugins/jsx/LexicalJsxVisitor.js +2 -1
- package/dist/plugins/jsx/MdastMdxJsxElementVisitor.js +5 -3
- package/package.json +1 -1
|
@@ -14,10 +14,14 @@ function exportLexicalTreeToMdast({
|
|
|
14
14
|
}) {
|
|
15
15
|
let unistRoot = null;
|
|
16
16
|
const referredComponents = /* @__PURE__ */ new Set();
|
|
17
|
+
const knownImportSources = /* @__PURE__ */ new Map();
|
|
17
18
|
visitors = visitors.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
18
19
|
visit(root, null);
|
|
19
|
-
function registerReferredComponent(componentName) {
|
|
20
|
+
function registerReferredComponent(componentName, importStatement) {
|
|
20
21
|
referredComponents.add(componentName);
|
|
22
|
+
if (importStatement) {
|
|
23
|
+
knownImportSources.set(componentName, { ...importStatement });
|
|
24
|
+
}
|
|
21
25
|
}
|
|
22
26
|
function appendToParent(parentNode, node) {
|
|
23
27
|
if (unistRoot === null) {
|
|
@@ -87,7 +91,7 @@ function exportLexicalTreeToMdast({
|
|
|
87
91
|
const importsMap = /* @__PURE__ */ new Map();
|
|
88
92
|
const defaultImportsMap = /* @__PURE__ */ new Map();
|
|
89
93
|
for (const componentName of referredComponents) {
|
|
90
|
-
const descriptor = jsxComponentDescriptors.find((descriptor2) => descriptor2.name === componentName) ?? jsxComponentDescriptors.find((descriptor2) => descriptor2.name === "*");
|
|
94
|
+
const descriptor = jsxComponentDescriptors.find((descriptor2) => descriptor2.name === componentName) ?? knownImportSources.get(componentName) ?? jsxComponentDescriptors.find((descriptor2) => descriptor2.name === "*");
|
|
91
95
|
if (!descriptor) {
|
|
92
96
|
throw new Error(`Component ${componentName} is used but not imported`);
|
|
93
97
|
}
|
|
@@ -106,6 +110,21 @@ function exportLexicalTreeToMdast({
|
|
|
106
110
|
}
|
|
107
111
|
}
|
|
108
112
|
}
|
|
113
|
+
if (!addImportStatements) {
|
|
114
|
+
for (const [path, names] of importsMap.entries()) {
|
|
115
|
+
const cleaned = names.filter((n) => knownImportSources.has(n));
|
|
116
|
+
if (cleaned.length > 0) {
|
|
117
|
+
importsMap.set(path, cleaned);
|
|
118
|
+
} else {
|
|
119
|
+
importsMap.delete(path);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const key of defaultImportsMap.keys()) {
|
|
123
|
+
if (!knownImportSources.has(key)) {
|
|
124
|
+
defaultImportsMap.delete(key);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
109
128
|
const imports = Array.from(importsMap).map(([source, componentNames]) => {
|
|
110
129
|
return {
|
|
111
130
|
type: "mdxjsEsm",
|
|
@@ -122,12 +141,10 @@ function exportLexicalTreeToMdast({
|
|
|
122
141
|
);
|
|
123
142
|
const typedRoot = unistRoot;
|
|
124
143
|
const frontmatter = typedRoot.children.find((child) => child.type === "yaml");
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
typedRoot.children.unshift(...imports);
|
|
130
|
-
}
|
|
144
|
+
if (frontmatter) {
|
|
145
|
+
typedRoot.children.splice(typedRoot.children.indexOf(frontmatter) + 1, 0, ...imports);
|
|
146
|
+
} else {
|
|
147
|
+
typedRoot.children.unshift(...imports);
|
|
131
148
|
}
|
|
132
149
|
fixWrappingWhitespace(typedRoot, []);
|
|
133
150
|
collapseNestedHtmlTags(typedRoot);
|
|
@@ -16,6 +16,32 @@ class UnrecognizedMarkdownConstructError extends Error {
|
|
|
16
16
|
this.name = "UnrecognizedMarkdownConstructError";
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
+
function gatherMetadata(mdastNode) {
|
|
20
|
+
const importsMap = /* @__PURE__ */ new Map();
|
|
21
|
+
if (mdastNode.type !== "root") {
|
|
22
|
+
return {
|
|
23
|
+
importDeclarations: {}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const importStatements = mdastNode.children.filter((n) => n.type === "mdxjsEsm").filter((n) => n.value.startsWith("import "));
|
|
27
|
+
importStatements.forEach((imp) => {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
(((_b = (_a = imp.data) == null ? void 0 : _a.estree) == null ? void 0 : _b.body) ?? []).forEach((declaration) => {
|
|
30
|
+
if (declaration.type !== "ImportDeclaration") {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
declaration.specifiers.forEach((specifier) => {
|
|
34
|
+
importsMap.set(specifier.local.name, {
|
|
35
|
+
source: `${declaration.source.value}`,
|
|
36
|
+
defaultExport: specifier.type === "ImportDefaultSpecifier"
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
importDeclarations: Object.fromEntries(importsMap.entries())
|
|
43
|
+
};
|
|
44
|
+
}
|
|
19
45
|
function importMarkdownToLexical({
|
|
20
46
|
root,
|
|
21
47
|
markdown,
|
|
@@ -49,6 +75,7 @@ function importMarkdownToLexical({
|
|
|
49
75
|
function importMdastTreeToLexical({ root, mdastRoot, visitors, ...descriptors }) {
|
|
50
76
|
const formattingMap = /* @__PURE__ */ new WeakMap();
|
|
51
77
|
const styleMap = /* @__PURE__ */ new WeakMap();
|
|
78
|
+
const metaData = gatherMetadata(mdastRoot);
|
|
52
79
|
visitors = visitors.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
53
80
|
function visitChildren(mdastNode, lexicalParent) {
|
|
54
81
|
if (!isParent(mdastNode)) {
|
|
@@ -83,6 +110,7 @@ function importMdastTreeToLexical({ root, mdastRoot, visitors, ...descriptors })
|
|
|
83
110
|
lexicalParent,
|
|
84
111
|
mdastParent,
|
|
85
112
|
descriptors,
|
|
113
|
+
metaData,
|
|
86
114
|
actions: {
|
|
87
115
|
visitChildren,
|
|
88
116
|
addAndStepInto(lexicalNode) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1411,6 +1411,11 @@ export declare interface ImportPoint {
|
|
|
1411
1411
|
getType(): string;
|
|
1412
1412
|
}
|
|
1413
1413
|
|
|
1414
|
+
export declare interface ImportStatement {
|
|
1415
|
+
source: string;
|
|
1416
|
+
defaultExport: boolean;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1414
1419
|
/**
|
|
1415
1420
|
* Contains the currently registered import vistors.
|
|
1416
1421
|
* @group Core
|
|
@@ -1833,7 +1838,7 @@ export declare interface LexicalExportVisitor<LN extends LexicalNode, UN extends
|
|
|
1833
1838
|
* @param componentName - the name of the component that has to be imported.
|
|
1834
1839
|
* @see {@link JsxComponentDescriptor}
|
|
1835
1840
|
*/
|
|
1836
|
-
registerReferredComponent(componentName: string): void;
|
|
1841
|
+
registerReferredComponent(componentName: string, importStatement?: ImportStatement): void;
|
|
1837
1842
|
/**
|
|
1838
1843
|
* visits the specified lexical node
|
|
1839
1844
|
*/
|
|
@@ -2027,6 +2032,10 @@ export declare interface MdastImportVisitor<UN extends Mdast.Nodes> {
|
|
|
2027
2032
|
* The descriptors for composite nodes (jsx, directives, code blocks).
|
|
2028
2033
|
*/
|
|
2029
2034
|
descriptors: Descriptors;
|
|
2035
|
+
/**
|
|
2036
|
+
* metaData: context data provided from the import visitor.
|
|
2037
|
+
*/
|
|
2038
|
+
metaData: MetaData;
|
|
2030
2039
|
/**
|
|
2031
2040
|
* A set of convenience utilities that can be used to add nodes to the lexical tree.
|
|
2032
2041
|
*/
|
|
@@ -2221,6 +2230,13 @@ export declare interface MDXEditorProps {
|
|
|
2221
2230
|
*/
|
|
2222
2231
|
export declare type MdxNodeType = MdastHTMLNode['type'];
|
|
2223
2232
|
|
|
2233
|
+
/**
|
|
2234
|
+
* Metadata that is provided to the visitors
|
|
2235
|
+
*/
|
|
2236
|
+
declare interface MetaData {
|
|
2237
|
+
importDeclarations: Record<string, ImportStatement>;
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2224
2240
|
/**
|
|
2225
2241
|
* A toolbar primitive that allows you to build an UI with multiple non-exclusive toggle groups, like the bold/italic/underline toggle.
|
|
2226
2242
|
* @group Toolbar Primitives
|
|
@@ -2870,7 +2886,7 @@ export declare type Translation = (key: string, defaultValue: string, interpolat
|
|
|
2870
2886
|
export declare const UndoRedo: default_2.FC;
|
|
2871
2887
|
|
|
2872
2888
|
/**
|
|
2873
|
-
* An error that gets thrown when the Markdown parsing encounters
|
|
2889
|
+
* An error that gets thrown when the Markdown parsing encounters a node that has no corresponding {@link MdastImportVisitor}.
|
|
2874
2890
|
* @group Markdown Processing
|
|
2875
2891
|
*/
|
|
2876
2892
|
export declare class UnrecognizedMarkdownConstructError extends Error {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $isTextNode } from "lexical";
|
|
2
|
-
import {
|
|
2
|
+
import { IS_UNDERLINE, IS_SUPERSCRIPT, IS_SUBSCRIPT, IS_ITALIC, IS_BOLD, IS_STRIKETHROUGH, IS_CODE } from "../../FormatConstants.js";
|
|
3
3
|
function isMdastText(mdastNode) {
|
|
4
4
|
return mdastNode.type === "text";
|
|
5
5
|
}
|
|
@@ -45,18 +45,6 @@ const LexicalTextVisitor = {
|
|
|
45
45
|
attributes: [{ type: "mdxJsxAttribute", name: "style", value: style }]
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
-
if (prevFormat & format & IS_ITALIC) {
|
|
49
|
-
localParentNode = actions.appendToParent(localParentNode, {
|
|
50
|
-
type: "emphasis",
|
|
51
|
-
children: []
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
if (prevFormat & format & IS_BOLD) {
|
|
55
|
-
localParentNode = actions.appendToParent(localParentNode, {
|
|
56
|
-
type: "strong",
|
|
57
|
-
children: []
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
48
|
if (prevFormat & format & IS_UNDERLINE) {
|
|
61
49
|
localParentNode = actions.appendToParent(localParentNode, {
|
|
62
50
|
type: "mdxJsxTextElement",
|
|
@@ -65,12 +53,6 @@ const LexicalTextVisitor = {
|
|
|
65
53
|
attributes: []
|
|
66
54
|
});
|
|
67
55
|
}
|
|
68
|
-
if (prevFormat & format & IS_STRIKETHROUGH) {
|
|
69
|
-
localParentNode = actions.appendToParent(localParentNode, {
|
|
70
|
-
type: "delete",
|
|
71
|
-
children: []
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
56
|
if (prevFormat & format & IS_SUPERSCRIPT) {
|
|
75
57
|
localParentNode = actions.appendToParent(localParentNode, {
|
|
76
58
|
type: "mdxJsxTextElement",
|
|
@@ -87,18 +69,24 @@ const LexicalTextVisitor = {
|
|
|
87
69
|
attributes: []
|
|
88
70
|
});
|
|
89
71
|
}
|
|
90
|
-
if (
|
|
72
|
+
if (prevFormat & format & IS_ITALIC) {
|
|
91
73
|
localParentNode = actions.appendToParent(localParentNode, {
|
|
92
74
|
type: "emphasis",
|
|
93
75
|
children: []
|
|
94
76
|
});
|
|
95
77
|
}
|
|
96
|
-
if (
|
|
78
|
+
if (prevFormat & format & IS_BOLD) {
|
|
97
79
|
localParentNode = actions.appendToParent(localParentNode, {
|
|
98
80
|
type: "strong",
|
|
99
81
|
children: []
|
|
100
82
|
});
|
|
101
83
|
}
|
|
84
|
+
if (prevFormat & format & IS_STRIKETHROUGH) {
|
|
85
|
+
localParentNode = actions.appendToParent(localParentNode, {
|
|
86
|
+
type: "delete",
|
|
87
|
+
children: []
|
|
88
|
+
});
|
|
89
|
+
}
|
|
102
90
|
if (format & IS_UNDERLINE && !(prevFormat & IS_UNDERLINE)) {
|
|
103
91
|
localParentNode = actions.appendToParent(localParentNode, {
|
|
104
92
|
type: "mdxJsxTextElement",
|
|
@@ -107,12 +95,6 @@ const LexicalTextVisitor = {
|
|
|
107
95
|
attributes: []
|
|
108
96
|
});
|
|
109
97
|
}
|
|
110
|
-
if (format & IS_STRIKETHROUGH && !(prevFormat & IS_STRIKETHROUGH)) {
|
|
111
|
-
localParentNode = actions.appendToParent(localParentNode, {
|
|
112
|
-
type: "delete",
|
|
113
|
-
children: []
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
98
|
if (format & IS_SUPERSCRIPT && !(prevFormat & IS_SUPERSCRIPT)) {
|
|
117
99
|
localParentNode = actions.appendToParent(localParentNode, {
|
|
118
100
|
type: "mdxJsxTextElement",
|
|
@@ -129,6 +111,24 @@ const LexicalTextVisitor = {
|
|
|
129
111
|
attributes: []
|
|
130
112
|
});
|
|
131
113
|
}
|
|
114
|
+
if (format & IS_ITALIC && !(prevFormat & IS_ITALIC)) {
|
|
115
|
+
localParentNode = actions.appendToParent(localParentNode, {
|
|
116
|
+
type: "emphasis",
|
|
117
|
+
children: []
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
if (format & IS_BOLD && !(prevFormat & IS_BOLD)) {
|
|
121
|
+
localParentNode = actions.appendToParent(localParentNode, {
|
|
122
|
+
type: "strong",
|
|
123
|
+
children: []
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (format & IS_STRIKETHROUGH && !(prevFormat & IS_STRIKETHROUGH)) {
|
|
127
|
+
localParentNode = actions.appendToParent(localParentNode, {
|
|
128
|
+
type: "delete",
|
|
129
|
+
children: []
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
132
|
if (format & IS_CODE) {
|
|
133
133
|
actions.appendToParent(localParentNode, {
|
|
134
134
|
type: "inlineCode",
|
|
@@ -11,30 +11,36 @@ import { voidEmitter } from "../../utils/voidEmitter.js";
|
|
|
11
11
|
import { useCellValue } from "@mdxeditor/gurx";
|
|
12
12
|
import { jsxComponentDescriptors$ } from "../core/index.js";
|
|
13
13
|
class LexicalJsxNode extends DecoratorNode {
|
|
14
|
-
constructor(mdastNode, key) {
|
|
14
|
+
constructor(mdastNode, importStatement, key) {
|
|
15
15
|
super(key);
|
|
16
16
|
__publicField(this, "__mdastNode");
|
|
17
17
|
__publicField(this, "__focusEmitter", voidEmitter());
|
|
18
|
+
__publicField(this, "__importStatement");
|
|
18
19
|
__publicField(this, "select", () => {
|
|
19
20
|
this.__focusEmitter.publish();
|
|
20
21
|
});
|
|
21
22
|
this.__mdastNode = mdastNode;
|
|
23
|
+
this.__importStatement = importStatement;
|
|
22
24
|
}
|
|
23
25
|
static getType() {
|
|
24
26
|
return "jsx";
|
|
25
27
|
}
|
|
26
28
|
static clone(node) {
|
|
27
|
-
return new LexicalJsxNode(structuredClone(node.__mdastNode), node.__key);
|
|
29
|
+
return new LexicalJsxNode(structuredClone(node.__mdastNode), structuredClone(node.__importStatement), node.__key);
|
|
28
30
|
}
|
|
29
31
|
static importJSON(serializedNode) {
|
|
30
|
-
return $createLexicalJsxNode(serializedNode.mdastNode);
|
|
32
|
+
return $createLexicalJsxNode(serializedNode.mdastNode, serializedNode.importStatement);
|
|
31
33
|
}
|
|
32
34
|
getMdastNode() {
|
|
33
35
|
return this.__mdastNode;
|
|
34
36
|
}
|
|
37
|
+
getImportStatement() {
|
|
38
|
+
return this.__importStatement;
|
|
39
|
+
}
|
|
35
40
|
exportJSON() {
|
|
36
41
|
return {
|
|
37
42
|
mdastNode: this.getMdastNode(),
|
|
43
|
+
importStatement: this.getImportStatement(),
|
|
38
44
|
type: "jsx",
|
|
39
45
|
version: 1
|
|
40
46
|
};
|
|
@@ -89,8 +95,8 @@ function JsxEditorContainer(props) {
|
|
|
89
95
|
/* @__PURE__ */ React__default.createElement(Editor, { descriptor, mdastNode })
|
|
90
96
|
);
|
|
91
97
|
}
|
|
92
|
-
function $createLexicalJsxNode(mdastNode) {
|
|
93
|
-
return new LexicalJsxNode(mdastNode);
|
|
98
|
+
function $createLexicalJsxNode(mdastNode, importStatement) {
|
|
99
|
+
return new LexicalJsxNode(mdastNode, importStatement);
|
|
94
100
|
}
|
|
95
101
|
function $isLexicalJsxNode(node) {
|
|
96
102
|
return node instanceof LexicalJsxNode;
|
|
@@ -15,7 +15,8 @@ const LexicalJsxVisitor = {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
const mdastNode = lexicalNode.getMdastNode();
|
|
18
|
-
|
|
18
|
+
const importStatement = lexicalNode.getImportStatement();
|
|
19
|
+
actions.registerReferredComponent(mdastNode.name, importStatement);
|
|
19
20
|
traverseNestedJsxNodes(mdastNode);
|
|
20
21
|
actions.appendToParent(mdastParent, mdastNode);
|
|
21
22
|
},
|
|
@@ -8,15 +8,17 @@ const MdastMdxJsxElementVisitor = {
|
|
|
8
8
|
}
|
|
9
9
|
return false;
|
|
10
10
|
},
|
|
11
|
-
visitNode({ lexicalParent, mdastNode, descriptors: { jsxComponentDescriptors } }) {
|
|
11
|
+
visitNode({ lexicalParent, mdastNode, descriptors: { jsxComponentDescriptors }, metaData }) {
|
|
12
12
|
const descriptor = jsxComponentDescriptors.find((descriptor2) => descriptor2.name === mdastNode.name) ?? jsxComponentDescriptors.find((descriptor2) => descriptor2.name === "*");
|
|
13
13
|
if ((descriptor == null ? void 0 : descriptor.kind) === "text" && mdastNode.type === "mdxJsxFlowElement") {
|
|
14
14
|
const patchedNode = { ...mdastNode, type: "mdxJsxTextElement" };
|
|
15
15
|
const paragraph = $createParagraphNode();
|
|
16
|
-
paragraph.append($createLexicalJsxNode(patchedNode));
|
|
16
|
+
paragraph.append($createLexicalJsxNode(patchedNode, mdastNode.name ? metaData.importDeclarations[mdastNode.name] : void 0));
|
|
17
17
|
lexicalParent.append(paragraph);
|
|
18
18
|
} else {
|
|
19
|
-
lexicalParent.append(
|
|
19
|
+
lexicalParent.append(
|
|
20
|
+
$createLexicalJsxNode(mdastNode, mdastNode.name ? metaData.importDeclarations[mdastNode.name] : void 0)
|
|
21
|
+
);
|
|
20
22
|
}
|
|
21
23
|
},
|
|
22
24
|
priority: -200
|