@mdxeditor/editor 2.0.0 → 2.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.
- package/dist/RealmWithPlugins.js +8 -6
- package/dist/index.d.ts +13 -11
- package/dist/plugins/core/index.js +23 -15
- package/dist/plugins/image/ImageEditor.js +5 -3
- package/dist/plugins/image/index.js +2 -2
- package/dist/plugins/lists/LexicalListItemVisitor.js +2 -1
- package/dist/plugins/table/TableEditor.js +9 -1
- package/package.json +2 -1
package/dist/RealmWithPlugins.js
CHANGED
|
@@ -16,18 +16,20 @@ function realmPlugin(plugin) {
|
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
function RealmWithPlugins({ children, plugins }) {
|
|
19
|
-
var _a;
|
|
20
19
|
const theRealm = React__default.useMemo(() => {
|
|
21
20
|
return tap(new Realm(), (r) => {
|
|
22
|
-
var
|
|
21
|
+
var _a;
|
|
23
22
|
for (const plugin of plugins) {
|
|
24
|
-
(
|
|
23
|
+
(_a = plugin.init) == null ? void 0 : _a.call(plugin, r);
|
|
25
24
|
}
|
|
26
25
|
});
|
|
27
26
|
}, []);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
React__default.useEffect(() => {
|
|
28
|
+
var _a;
|
|
29
|
+
for (const plugin of plugins) {
|
|
30
|
+
(_a = plugin.update) == null ? void 0 : _a.call(plugin, theRealm);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
31
33
|
return /* @__PURE__ */ React__default.createElement(RealmContext.Provider, { value: theRealm }, children);
|
|
32
34
|
}
|
|
33
35
|
export {
|
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ import { EditorConfig } from 'lexical';
|
|
|
40
40
|
import { ElementNode } from 'lexical';
|
|
41
41
|
import { Extension } from 'micromark-util-types';
|
|
42
42
|
import { Extension as Extension_2 } from '@codemirror/state';
|
|
43
|
+
import { FC } from 'react';
|
|
43
44
|
import { HeadingTagType } from '@lexical/rich-text';
|
|
44
45
|
import { HistoryState } from '@lexical/history';
|
|
45
46
|
import { InitialEditorStateType } from '@lexical/react/LexicalComposer.js';
|
|
@@ -182,7 +183,7 @@ export declare const addExportVisitor$: NodeRef<LexicalVisitor | LexicalVisitor[
|
|
|
182
183
|
* Registers a visitor to be used when importing markdown.
|
|
183
184
|
* @group Markdown Processing
|
|
184
185
|
*/
|
|
185
|
-
export declare const addImportVisitor$: NodeRef<MdastImportVisitor<Mdast.
|
|
186
|
+
export declare const addImportVisitor$: NodeRef<MdastImportVisitor<Mdast.Nodes> | MdastImportVisitor<Mdast.Nodes>[]>;
|
|
186
187
|
|
|
187
188
|
/**
|
|
188
189
|
* Registers a lexical node to be used in the editor.
|
|
@@ -1191,6 +1192,7 @@ export declare const imagePlugin: (params?: {
|
|
|
1191
1192
|
imageAutocompleteSuggestions?: string[] | undefined;
|
|
1192
1193
|
disableImageResize?: boolean | undefined;
|
|
1193
1194
|
imagePreviewHandler?: ImagePreviewHandler | undefined;
|
|
1195
|
+
ImageDialog?: FC<{}> | (() => JSX.Element) | undefined;
|
|
1194
1196
|
} | undefined) => RealmPlugin;
|
|
1195
1197
|
|
|
1196
1198
|
/**
|
|
@@ -1427,13 +1429,13 @@ declare const IS_UNDERLINE: 8;
|
|
|
1427
1429
|
* Determines if the given node is a HTML MDAST node.
|
|
1428
1430
|
* @group HTML
|
|
1429
1431
|
*/
|
|
1430
|
-
export declare function isMdastHTMLNode(node: Mdast.
|
|
1432
|
+
export declare function isMdastHTMLNode(node: Mdast.Nodes): node is MdastHTMLNode;
|
|
1431
1433
|
|
|
1432
1434
|
/**
|
|
1433
1435
|
* Determines wether the given node is a JSX node.
|
|
1434
1436
|
* @group JSX
|
|
1435
1437
|
*/
|
|
1436
|
-
export declare function isMdastJsxNode(node: Mdast.
|
|
1438
|
+
export declare function isMdastJsxNode(node: Mdast.Nodes): node is MdastJsx;
|
|
1437
1439
|
|
|
1438
1440
|
/* Excluded from this release type: isPartOftheEditorUI */
|
|
1439
1441
|
|
|
@@ -1563,7 +1565,7 @@ export declare interface LexicalConvertOptions {
|
|
|
1563
1565
|
* This is part of the process that converts the editor contents to markdown.
|
|
1564
1566
|
* @group Markdown Processing
|
|
1565
1567
|
*/
|
|
1566
|
-
export declare interface LexicalExportVisitor<LN extends LexicalNode, UN extends Mdast.
|
|
1568
|
+
export declare interface LexicalExportVisitor<LN extends LexicalNode, UN extends Mdast.Nodes> {
|
|
1567
1569
|
/**
|
|
1568
1570
|
* Return true if the given node is of the type that this visitor can process.
|
|
1569
1571
|
* You can safely use the node type guard functions (as in $isParagraphNode, $isLinkNode, etc.) here.
|
|
@@ -1614,12 +1616,12 @@ export declare interface LexicalExportVisitor<LN extends LexicalNode, UN extends
|
|
|
1614
1616
|
* Return true if the current node should be joined with the previous node.
|
|
1615
1617
|
* This is necessary due to some inconsistencies between the lexical tree and the mdast tree when it comes to formatting.
|
|
1616
1618
|
*/
|
|
1617
|
-
shouldJoin?(prevNode: Mdast.
|
|
1619
|
+
shouldJoin?(prevNode: Mdast.RootContent, currentNode: UN): boolean;
|
|
1618
1620
|
/**
|
|
1619
1621
|
* Join the current node with the previous node, returning the resulting new node
|
|
1620
1622
|
* For this to be called by the tree walk, shouldJoin must return true.
|
|
1621
1623
|
*/
|
|
1622
|
-
join?<T extends Mdast.
|
|
1624
|
+
join?<T extends Mdast.RootContent>(prevNode: T, currentNode: T): T;
|
|
1623
1625
|
/**
|
|
1624
1626
|
* Default 0, optional, sets the priority of the visitor. The higher the number, the earlier it will be called.
|
|
1625
1627
|
*/
|
|
@@ -1630,7 +1632,7 @@ export declare interface LexicalExportVisitor<LN extends LexicalNode, UN extends
|
|
|
1630
1632
|
* A generic visitor that can be used to process any lexical node.
|
|
1631
1633
|
* @group Markdown Processing
|
|
1632
1634
|
*/
|
|
1633
|
-
export declare type LexicalVisitor = LexicalExportVisitor<LexicalNode, Mdast.
|
|
1635
|
+
export declare type LexicalVisitor = LexicalExportVisitor<LexicalNode, Mdast.RootContent>;
|
|
1634
1636
|
|
|
1635
1637
|
/* Excluded from this release type: linkAutocompleteSuggestions$ */
|
|
1636
1638
|
|
|
@@ -1741,12 +1743,12 @@ export declare type MdastHTMLNode = MdastBlockHTMLNode | MdastInlineHTMLNode;
|
|
|
1741
1743
|
* @typeParam UN - The type of the mdast node that is being visited.
|
|
1742
1744
|
* @group Markdown Processing
|
|
1743
1745
|
*/
|
|
1744
|
-
export declare interface MdastImportVisitor<UN extends Mdast.
|
|
1746
|
+
export declare interface MdastImportVisitor<UN extends Mdast.Nodes> {
|
|
1745
1747
|
/**
|
|
1746
1748
|
* The test function that determines if this visitor should be used for the given node.
|
|
1747
1749
|
* As a convenience, you can also pass a string here, which will be compared to the node's type.
|
|
1748
1750
|
*/
|
|
1749
|
-
testNode: ((mdastNode: Mdast.
|
|
1751
|
+
testNode: ((mdastNode: Mdast.Nodes) => boolean) | string;
|
|
1750
1752
|
visitNode(params: {
|
|
1751
1753
|
/**
|
|
1752
1754
|
* The node that is currently being visited.
|
|
@@ -1776,12 +1778,12 @@ export declare interface MdastImportVisitor<UN extends Mdast.Content> {
|
|
|
1776
1778
|
* Adds formatting as a context for the current node and its children.
|
|
1777
1779
|
* This is necessary due to mdast treating formatting as a node, while lexical considering it an attribute of a node.
|
|
1778
1780
|
*/
|
|
1779
|
-
addFormatting(format: typeof IS_BOLD | typeof IS_ITALIC | typeof IS_UNDERLINE | typeof IS_CODE, node?: Mdast.
|
|
1781
|
+
addFormatting(format: typeof IS_BOLD | typeof IS_ITALIC | typeof IS_UNDERLINE | typeof IS_CODE, node?: Mdast.RootContent): void;
|
|
1780
1782
|
/**
|
|
1781
1783
|
* Removes formatting as a context for the current node and its children.
|
|
1782
1784
|
* This is necessary due to mdast treating formatting as a node, while lexical considering it an attribute of a node.
|
|
1783
1785
|
*/
|
|
1784
|
-
removeFormatting(format: typeof IS_BOLD | typeof IS_ITALIC | typeof IS_UNDERLINE | typeof IS_CODE, node?: Mdast.
|
|
1786
|
+
removeFormatting(format: typeof IS_BOLD | typeof IS_ITALIC | typeof IS_UNDERLINE | typeof IS_CODE, node?: Mdast.RootContent): void;
|
|
1785
1787
|
/**
|
|
1786
1788
|
* Access the current formatting context.
|
|
1787
1789
|
*/
|
|
@@ -7,6 +7,7 @@ import { Cell, withLatestFrom, Signal, filter, scan } from "@mdxeditor/gurx";
|
|
|
7
7
|
import { createCommand, FORMAT_TEXT_COMMAND, $isRootOrShadowRoot, $getRoot, $setSelection, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_CRITICAL, FOCUS_COMMAND, KEY_DOWN_COMMAND, $isDecoratorNode, BLUR_COMMAND, $getSelection, $isRangeSelection, $insertNodes, $createParagraphNode, ParagraphNode, TextNode } from "lexical";
|
|
8
8
|
import { mdxJsxFromMarkdown, mdxJsxToMarkdown } from "mdast-util-mdx-jsx";
|
|
9
9
|
import { mdxJsx } from "micromark-extension-mdx-jsx";
|
|
10
|
+
import { mdxMd } from "micromark-extension-mdx-md";
|
|
10
11
|
import { exportMarkdownFromLexical } from "../../exportMarkdownFromLexical.js";
|
|
11
12
|
import { importMarkdownToLexical, MarkdownParseError, UnrecognizedMarkdownConstructError } from "../../importMarkdownToLexical.js";
|
|
12
13
|
import { controlOrMeta } from "../../utils/detectMac.js";
|
|
@@ -390,24 +391,31 @@ const insertDecoratorNode$ = Signal((r) => {
|
|
|
390
391
|
});
|
|
391
392
|
});
|
|
392
393
|
const viewMode$ = Cell("rich-text", (r) => {
|
|
394
|
+
function currentNextViewMode() {
|
|
395
|
+
return scan(
|
|
396
|
+
(prev, next) => {
|
|
397
|
+
return {
|
|
398
|
+
current: prev.next,
|
|
399
|
+
next
|
|
400
|
+
};
|
|
401
|
+
},
|
|
402
|
+
{ current: "rich-text", next: "rich-text" }
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
r.sub(r.pipe(viewMode$, currentNextViewMode(), withLatestFrom(markdownSourceEditorValue$)), ([{ current }, markdownSourceFromEditor]) => {
|
|
406
|
+
if (current === "source" || current === "diff") {
|
|
407
|
+
r.pub(setMarkdown$, markdownSourceFromEditor);
|
|
408
|
+
}
|
|
409
|
+
});
|
|
393
410
|
r.sub(
|
|
394
411
|
r.pipe(
|
|
395
412
|
viewMode$,
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
current: prev.next,
|
|
400
|
-
next
|
|
401
|
-
};
|
|
402
|
-
},
|
|
403
|
-
{ current: "rich-text", next: "rich-text" }
|
|
404
|
-
),
|
|
405
|
-
withLatestFrom(markdownSourceEditorValue$)
|
|
413
|
+
currentNextViewMode(),
|
|
414
|
+
filter((mode) => mode.current === "rich-text"),
|
|
415
|
+
withLatestFrom(activeEditor$)
|
|
406
416
|
),
|
|
407
|
-
([
|
|
408
|
-
|
|
409
|
-
r.pub(setMarkdown$, markdownSourceFromEditor);
|
|
410
|
-
}
|
|
417
|
+
([, editor]) => {
|
|
418
|
+
editor == null ? void 0 : editor.dispatchCommand(NESTED_EDITOR_UPDATED_COMMAND, void 0);
|
|
411
419
|
}
|
|
412
420
|
);
|
|
413
421
|
});
|
|
@@ -445,7 +453,7 @@ const corePlugin = realmPlugin({
|
|
|
445
453
|
if (!(params == null ? void 0 : params.suppressHtmlProcessing)) {
|
|
446
454
|
r.pubIn({
|
|
447
455
|
[addMdastExtension$]: mdxJsxFromMarkdown(),
|
|
448
|
-
[addSyntaxExtension$]: mdxJsx(),
|
|
456
|
+
[addSyntaxExtension$]: [mdxJsx(), mdxMd()],
|
|
449
457
|
[addToMarkdownExtension$]: mdxJsxToMarkdown(),
|
|
450
458
|
[addImportVisitor$]: MdastHTMLVisitor
|
|
451
459
|
});
|
|
@@ -6,7 +6,7 @@ import classNames from "classnames";
|
|
|
6
6
|
import { $isNodeSelection, $getSelection, $getNodeByKey, $setSelection, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_LOW, CLICK_COMMAND, DRAGSTART_COMMAND, KEY_DELETE_COMMAND, KEY_BACKSPACE_COMMAND, KEY_ENTER_COMMAND, KEY_ESCAPE_COMMAND } from "lexical";
|
|
7
7
|
import { disableImageResize$, imagePreviewHandler$, openEditImageDialog$ } from "./index.js";
|
|
8
8
|
import styles from "../../styles/ui.module.css.js";
|
|
9
|
-
import { iconComponentFor$ } from "../core/index.js";
|
|
9
|
+
import { iconComponentFor$, readOnly$ } from "../core/index.js";
|
|
10
10
|
import { $isImageNode } from "./ImageNode.js";
|
|
11
11
|
import ImageResizer from "./ImageResizer.js";
|
|
12
12
|
import { useCellValues, usePublisher } from "@mdxeditor/gurx";
|
|
@@ -48,10 +48,11 @@ function LazyImage({
|
|
|
48
48
|
);
|
|
49
49
|
}
|
|
50
50
|
function ImageEditor({ src, title, alt, nodeKey, width, height }) {
|
|
51
|
-
const [disableImageResize, imagePreviewHandler, iconComponentFor] = useCellValues(
|
|
51
|
+
const [disableImageResize, imagePreviewHandler, iconComponentFor, readOnly] = useCellValues(
|
|
52
52
|
disableImageResize$,
|
|
53
53
|
imagePreviewHandler$,
|
|
54
|
-
iconComponentFor
|
|
54
|
+
iconComponentFor$,
|
|
55
|
+
readOnly$
|
|
55
56
|
);
|
|
56
57
|
const openEditImageDialog = usePublisher(openEditImageDialog$);
|
|
57
58
|
const imageRef = React__default.useRef(null);
|
|
@@ -214,6 +215,7 @@ function ImageEditor({ src, title, alt, nodeKey, width, height }) {
|
|
|
214
215
|
type: "button",
|
|
215
216
|
className: classNames(styles.iconButton, styles.editImageButton),
|
|
216
217
|
title: "Edit image",
|
|
218
|
+
disabled: readOnly,
|
|
217
219
|
onClick: () => {
|
|
218
220
|
openEditImageDialog({
|
|
219
221
|
nodeKey,
|
|
@@ -129,12 +129,12 @@ const closeImageDialog$ = Action((r) => {
|
|
|
129
129
|
});
|
|
130
130
|
const saveImage$ = Signal();
|
|
131
131
|
const imagePlugin = realmPlugin({
|
|
132
|
-
init(realm) {
|
|
132
|
+
init(realm, params) {
|
|
133
133
|
realm.pubIn({
|
|
134
134
|
[addImportVisitor$]: [MdastImageVisitor, MdastHtmlImageVisitor, MdastJsxImageVisitor],
|
|
135
135
|
[addLexicalNode$]: ImageNode,
|
|
136
136
|
[addExportVisitor$]: LexicalImageVisitor,
|
|
137
|
-
[addComposerChild$]: ImageDialog
|
|
137
|
+
[addComposerChild$]: (params == null ? void 0 : params.ImageDialog) || ImageDialog
|
|
138
138
|
});
|
|
139
139
|
},
|
|
140
140
|
update(realm, params) {
|
|
@@ -8,9 +8,10 @@ const LexicalListItemVisitor = {
|
|
|
8
8
|
const prevListItemNode = mdastParent.children.at(-1);
|
|
9
9
|
actions.visitChildren(lexicalNode, prevListItemNode);
|
|
10
10
|
} else {
|
|
11
|
+
const parentList = lexicalNode.getParent();
|
|
11
12
|
const listItem = actions.appendToParent(mdastParent, {
|
|
12
13
|
type: "listItem",
|
|
13
|
-
checked: lexicalNode.getChecked(),
|
|
14
|
+
checked: parentList.getListType() === "check" ? Boolean(lexicalNode.getChecked()) : void 0,
|
|
14
15
|
spread: false,
|
|
15
16
|
children: [{ type: "paragraph", children: [] }]
|
|
16
17
|
});
|
|
@@ -15,7 +15,7 @@ import classNames from "classnames";
|
|
|
15
15
|
import styles from "../../styles/ui.module.css.js";
|
|
16
16
|
import { isPartOftheEditorUI } from "../../utils/isPartOftheEditorUI.js";
|
|
17
17
|
import { uuidv4 } from "../../utils/uuid4.js";
|
|
18
|
-
import { iconComponentFor$, readOnly$, importVisitors$, exportVisitors$, usedLexicalNodes$, jsxComponentDescriptors$, jsxIsAvailable$, rootEditor$, editorRootElementRef$ } from "../core/index.js";
|
|
18
|
+
import { iconComponentFor$, readOnly$, importVisitors$, exportVisitors$, usedLexicalNodes$, jsxComponentDescriptors$, jsxIsAvailable$, rootEditor$, NESTED_EDITOR_UPDATED_COMMAND, editorRootElementRef$ } from "../core/index.js";
|
|
19
19
|
import { useCellValues } from "@mdxeditor/gurx";
|
|
20
20
|
const AlignToTailwindClassMap = {
|
|
21
21
|
center: styles.centeredCell,
|
|
@@ -268,6 +268,14 @@ const CellEditor = ({ focus, setActiveCell, parentEditor, lexicalTable, contents
|
|
|
268
268
|
return true;
|
|
269
269
|
},
|
|
270
270
|
COMMAND_PRIORITY_CRITICAL
|
|
271
|
+
),
|
|
272
|
+
editor.registerCommand(
|
|
273
|
+
NESTED_EDITOR_UPDATED_COMMAND,
|
|
274
|
+
() => {
|
|
275
|
+
saveAndFocus(null);
|
|
276
|
+
return true;
|
|
277
|
+
},
|
|
278
|
+
COMMAND_PRIORITY_CRITICAL
|
|
271
279
|
)
|
|
272
280
|
);
|
|
273
281
|
}, [colIndex, editor, rootEditor, rowIndex, saveAndFocus, setActiveCell]);
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"*.css"
|
|
12
12
|
],
|
|
13
13
|
"type": "module",
|
|
14
|
-
"version": "2.
|
|
14
|
+
"version": "2.1.0",
|
|
15
15
|
"description": "React component for rich text markdown editing",
|
|
16
16
|
"scripts": {
|
|
17
17
|
"build": "vite build",
|
|
@@ -78,6 +78,7 @@
|
|
|
78
78
|
"micromark-extension-gfm-table": "^2.0.0",
|
|
79
79
|
"micromark-extension-gfm-task-list-item": "^2.0.1",
|
|
80
80
|
"micromark-extension-mdx-jsx": "^3.0.0",
|
|
81
|
+
"micromark-extension-mdx-md": "^2.0.0",
|
|
81
82
|
"micromark-extension-mdxjs": "^3.0.0",
|
|
82
83
|
"react-hook-form": "^7.44.2",
|
|
83
84
|
"unidiff": "^1.0.2"
|