@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.
- package/LICENSE +21 -0
- package/README.md +86 -0
- package/UPSTREAM.md +21 -0
- package/dist/EditorIcon.js +75 -0
- package/dist/FormatConstants.js +20 -0
- package/dist/MDXEditor.js +189 -0
- package/dist/MarkdownEditor.js +281 -0
- package/dist/PersistentMarkdownEditor.js +358 -0
- package/dist/RealmWithPlugins.js +35 -0
- package/dist/core.d.ts +3232 -0
- package/dist/core.js +354 -0
- package/dist/defaultSvgIcons.js +371 -0
- package/dist/directive-editors/AdmonitionDirectiveDescriptor.js +28 -0
- package/dist/directive-editors/GenericDirectiveEditor.js +37 -0
- package/dist/exportMarkdownFromLexical.js +262 -0
- package/dist/horizontalRuleShortcut.js +37 -0
- package/dist/importMarkdownToLexical.js +172 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +8 -0
- package/dist/jsx-editors/GenericJsxEditor.js +84 -0
- package/dist/mdastUtilHtmlComment.js +125 -0
- package/dist/persistence.d.ts +128 -0
- package/dist/persistence.js +4 -0
- package/dist/plugins/codeblock/CodeBlockNode.js +183 -0
- package/dist/plugins/codeblock/CodeBlockVisitor.js +14 -0
- package/dist/plugins/codeblock/MdastCodeVisitor.js +23 -0
- package/dist/plugins/codeblock/findCodeBlockDescriptor.js +8 -0
- package/dist/plugins/codeblock/index.js +46 -0
- package/dist/plugins/codemirror/CodeMirrorEditor.js +145 -0
- package/dist/plugins/codemirror/index.js +115 -0
- package/dist/plugins/codemirror/useCodeMirrorRef.js +101 -0
- package/dist/plugins/core/GenericHTMLNode.js +118 -0
- package/dist/plugins/core/LexicalGenericHTMLNodeVisitor.js +15 -0
- package/dist/plugins/core/LexicalLinebreakVisitor.js +10 -0
- package/dist/plugins/core/LexicalParagraphVisitor.js +10 -0
- package/dist/plugins/core/LexicalRootVisitor.js +10 -0
- package/dist/plugins/core/LexicalTextVisitor.js +160 -0
- package/dist/plugins/core/MdastBreakVisitor.js +10 -0
- package/dist/plugins/core/MdastFormattingVisitor.js +81 -0
- package/dist/plugins/core/MdastHTMLNode.js +120 -0
- package/dist/plugins/core/MdastHTMLVisitor.js +17 -0
- package/dist/plugins/core/MdastParagraphVisitor.js +23 -0
- package/dist/plugins/core/MdastRootVisitor.js +9 -0
- package/dist/plugins/core/MdastTextVisitor.js +16 -0
- package/dist/plugins/core/NestedLexicalEditor.js +221 -0
- package/dist/plugins/core/PropertyPopover.js +75 -0
- package/dist/plugins/core/SharedHistoryPlugin.js +10 -0
- package/dist/plugins/core/index.js +692 -0
- package/dist/plugins/core/ui/DownshiftAutoComplete.js +89 -0
- package/dist/plugins/core/ui/PopoverUtils.js +22 -0
- package/dist/plugins/diff-source/DiffSourceWrapper.js +24 -0
- package/dist/plugins/diff-source/DiffViewer.js +84 -0
- package/dist/plugins/diff-source/SourceEditor.js +60 -0
- package/dist/plugins/diff-source/index.js +27 -0
- package/dist/plugins/directives/DirectiveNode.js +107 -0
- package/dist/plugins/directives/DirectiveVisitor.js +10 -0
- package/dist/plugins/directives/MdastDirectiveVisitor.js +30 -0
- package/dist/plugins/directives/index.js +45 -0
- package/dist/plugins/frontmatter/FrontmatterEditor.js +137 -0
- package/dist/plugins/frontmatter/FrontmatterNode.js +70 -0
- package/dist/plugins/frontmatter/LexicalFrontmatterVisitor.js +10 -0
- package/dist/plugins/frontmatter/MdastFrontmatterVisitor.js +10 -0
- package/dist/plugins/frontmatter/index.js +113 -0
- package/dist/plugins/headings/LexicalHeadingVisitor.js +11 -0
- package/dist/plugins/headings/MdastHeadingVisitor.js +10 -0
- package/dist/plugins/headings/index.js +63 -0
- package/dist/plugins/image/EditImageToolbar.js +58 -0
- package/dist/plugins/image/ImageDialog.js +132 -0
- package/dist/plugins/image/ImageEditor.js +279 -0
- package/dist/plugins/image/ImageNode.js +187 -0
- package/dist/plugins/image/ImagePlaceholder.js +9 -0
- package/dist/plugins/image/ImageResizer.js +223 -0
- package/dist/plugins/image/LexicalImageVisitor.js +42 -0
- package/dist/plugins/image/MdastImageVisitor.js +91 -0
- package/dist/plugins/image/index.js +364 -0
- package/dist/plugins/jsx/LexicalJsxNode.js +103 -0
- package/dist/plugins/jsx/LexicalJsxVisitor.js +27 -0
- package/dist/plugins/jsx/LexicalMdxExpressionNode.js +130 -0
- package/dist/plugins/jsx/LexicalMdxExpressionVisitor.js +14 -0
- package/dist/plugins/jsx/MdastMdxExpressionVisitor.js +11 -0
- package/dist/plugins/jsx/MdastMdxJsEsmVisitor.js +8 -0
- package/dist/plugins/jsx/MdastMdxJsxElementVisitor.js +28 -0
- package/dist/plugins/jsx/index.js +97 -0
- package/dist/plugins/jsx/jsxTagName.js +7 -0
- package/dist/plugins/link/AutoLinkPlugin.js +18 -0
- package/dist/plugins/link/LexicalLinkVisitor.js +10 -0
- package/dist/plugins/link/MdastLinkVisitor.js +14 -0
- package/dist/plugins/link/index.js +34 -0
- package/dist/plugins/link-dialog/LinkDialog.js +262 -0
- package/dist/plugins/link-dialog/index.js +304 -0
- package/dist/plugins/lists/CheckListPlugin.js +270 -0
- package/dist/plugins/lists/LexicalListItemVisitor.js +41 -0
- package/dist/plugins/lists/LexicalListVisitor.js +13 -0
- package/dist/plugins/lists/MdastListItemVisitor.js +11 -0
- package/dist/plugins/lists/MdastListVisitor.js +19 -0
- package/dist/plugins/lists/NotesListItemNode.js +22 -0
- package/dist/plugins/lists/index.js +111 -0
- package/dist/plugins/markdown-shortcut/index.js +114 -0
- package/dist/plugins/maxlength/index.js +36 -0
- package/dist/plugins/quote/LexicalQuoteVisitor.js +10 -0
- package/dist/plugins/quote/MdastBlockQuoteVisitor.js +10 -0
- package/dist/plugins/quote/index.js +18 -0
- package/dist/plugins/remote/index.js +52 -0
- package/dist/plugins/search/index.js +360 -0
- package/dist/plugins/table/LexicalTableVisitor.js +10 -0
- package/dist/plugins/table/MdastTableVisitor.js +10 -0
- package/dist/plugins/table/TableEditor.js +527 -0
- package/dist/plugins/table/TableNode.js +208 -0
- package/dist/plugins/table/index.js +66 -0
- package/dist/plugins/thematic-break/LexicalThematicBreakVisitor.js +10 -0
- package/dist/plugins/thematic-break/MdastThematicBreakVisitor.js +10 -0
- package/dist/plugins/thematic-break/index.js +27 -0
- package/dist/plugins/toolbar/components/BlockTypeSelect.js +62 -0
- package/dist/plugins/toolbar/components/BoldItalicUnderlineToggles.js +98 -0
- package/dist/plugins/toolbar/components/ChangeAdmonitionType.js +43 -0
- package/dist/plugins/toolbar/components/ChangeCodeMirrorLanguage.js +42 -0
- package/dist/plugins/toolbar/components/CodeToggle.js +21 -0
- package/dist/plugins/toolbar/components/CreateLink.js +24 -0
- package/dist/plugins/toolbar/components/DiffSourceToggleWrapper.js +42 -0
- package/dist/plugins/toolbar/components/HighlightToggle.js +28 -0
- package/dist/plugins/toolbar/components/InsertAdmonition.js +34 -0
- package/dist/plugins/toolbar/components/InsertCodeBlock.js +23 -0
- package/dist/plugins/toolbar/components/InsertFrontmatter.js +28 -0
- package/dist/plugins/toolbar/components/InsertImage.js +29 -0
- package/dist/plugins/toolbar/components/InsertTable.js +25 -0
- package/dist/plugins/toolbar/components/InsertThematicBreak.js +23 -0
- package/dist/plugins/toolbar/components/KitchenSinkToolbar.js +82 -0
- package/dist/plugins/toolbar/components/ListsToggle.js +29 -0
- package/dist/plugins/toolbar/components/UndoRedo.js +60 -0
- package/dist/plugins/toolbar/index.js +32 -0
- package/dist/plugins/toolbar/primitives/DialogButton.js +130 -0
- package/dist/plugins/toolbar/primitives/TooltipWrap.js +17 -0
- package/dist/plugins/toolbar/primitives/select.js +76 -0
- package/dist/plugins/toolbar/primitives/toolbar.js +144 -0
- package/dist/registerCodeBoundaryEscape.js +40 -0
- package/dist/styles/lexical-theme.module.css.js +62 -0
- package/dist/styles/lexicalTheme.js +32 -0
- package/dist/styles/ui.module.css.js +296 -0
- package/dist/styles.css +2838 -0
- package/dist/utils/detectMac.js +16 -0
- package/dist/utils/fp.js +44 -0
- package/dist/utils/isPartOftheEditorUI.js +12 -0
- package/dist/utils/lexicalHelpers.js +185 -0
- package/dist/utils/makeHslTransparent.js +6 -0
- package/dist/utils/mergeStyleAttributes.js +22 -0
- package/dist/utils/uuid4.js +10 -0
- package/dist/utils/voidEmitter.js +15 -0
- package/package.json +133 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { activeEditor$, currentSelection$, rootEditor$, addNestedEditorChild$, addComposerChild$, addToMarkdownExtension$, addExportVisitor$, addLexicalNode$, addImportVisitor$, addSyntaxExtension$, addMdastExtension$, addActivePlugin$ } from "../core/index.js";
|
|
2
|
+
import { MdastListVisitor } from "./MdastListVisitor.js";
|
|
3
|
+
import { MdastListItemVisitor } from "./MdastListItemVisitor.js";
|
|
4
|
+
import { LexicalListVisitor } from "./LexicalListVisitor.js";
|
|
5
|
+
import { LexicalListItemVisitor } from "./LexicalListItemVisitor.js";
|
|
6
|
+
import { $isListNode, ListNode, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND, REMOVE_LIST_COMMAND, ListItemNode, $getListDepth, $isListItemNode } from "@lexical/list";
|
|
7
|
+
import { $isRootOrShadowRoot, INDENT_CONTENT_COMMAND, COMMAND_PRIORITY_CRITICAL, $getSelection, $isRangeSelection, $isElementNode } from "lexical";
|
|
8
|
+
import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin.js";
|
|
9
|
+
import { ListPlugin } from "@lexical/react/LexicalListPlugin.js";
|
|
10
|
+
import { $findMatchingParent, $getNearestNodeOfType } from "@lexical/utils";
|
|
11
|
+
import { gfmTaskListItem } from "micromark-extension-gfm-task-list-item";
|
|
12
|
+
import { gfmTaskListItemToMarkdown, gfmTaskListItemFromMarkdown } from "mdast-util-gfm-task-list-item";
|
|
13
|
+
import { Signal, withLatestFrom, Cell } from "@mdxeditor/gurx";
|
|
14
|
+
import { realmPlugin } from "../../RealmWithPlugins.js";
|
|
15
|
+
import { NotesListItemNode } from "./NotesListItemNode.js";
|
|
16
|
+
import { CheckListPlugin } from "./CheckListPlugin.js";
|
|
17
|
+
const listItemNodeReplacement = {
|
|
18
|
+
replace: ListItemNode,
|
|
19
|
+
with: (node) => new NotesListItemNode(node.getValue(), node.getChecked()),
|
|
20
|
+
withKlass: NotesListItemNode
|
|
21
|
+
};
|
|
22
|
+
const ListTypeCommandMap = /* @__PURE__ */ new Map([
|
|
23
|
+
["number", INSERT_ORDERED_LIST_COMMAND],
|
|
24
|
+
["bullet", INSERT_UNORDERED_LIST_COMMAND],
|
|
25
|
+
["check", INSERT_CHECK_LIST_COMMAND],
|
|
26
|
+
["", REMOVE_LIST_COMMAND]
|
|
27
|
+
]);
|
|
28
|
+
const currentListType$ = Cell("", (r) => {
|
|
29
|
+
r.sub(r.pipe(currentSelection$, withLatestFrom(activeEditor$)), ([selection, theEditor]) => {
|
|
30
|
+
if (!selection || !theEditor) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const anchorNode = selection.anchor.getNode();
|
|
34
|
+
let element = anchorNode.getKey() === "root" ? anchorNode : $findMatchingParent(anchorNode, (e) => {
|
|
35
|
+
const parent = e.getParent();
|
|
36
|
+
return parent !== null && $isRootOrShadowRoot(parent);
|
|
37
|
+
});
|
|
38
|
+
element ??= anchorNode.getTopLevelElementOrThrow();
|
|
39
|
+
const elementKey = element.getKey();
|
|
40
|
+
const elementDOM = theEditor.getElementByKey(elementKey);
|
|
41
|
+
if (elementDOM !== null) {
|
|
42
|
+
if ($isListNode(element)) {
|
|
43
|
+
const parentList = $getNearestNodeOfType(anchorNode, ListNode);
|
|
44
|
+
const type = parentList ? parentList.getListType() : element.getListType();
|
|
45
|
+
r.pub(currentListType$, type);
|
|
46
|
+
} else {
|
|
47
|
+
r.pub(currentListType$, "");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
const applyListType$ = Signal((r) => {
|
|
53
|
+
r.sub(r.pipe(applyListType$, withLatestFrom(activeEditor$)), ([listType, theEditor]) => {
|
|
54
|
+
theEditor?.dispatchCommand(ListTypeCommandMap.get(listType), void 0);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
const listsPlugin = realmPlugin({
|
|
58
|
+
init(realm) {
|
|
59
|
+
realm.getValue(rootEditor$)?.registerCommand(INDENT_CONTENT_COMMAND, () => !isIndentPermitted(7), COMMAND_PRIORITY_CRITICAL);
|
|
60
|
+
realm.pubIn({
|
|
61
|
+
[addActivePlugin$]: "lists",
|
|
62
|
+
[addMdastExtension$]: gfmTaskListItemFromMarkdown(),
|
|
63
|
+
[addSyntaxExtension$]: gfmTaskListItem(),
|
|
64
|
+
[addImportVisitor$]: [MdastListVisitor, MdastListItemVisitor],
|
|
65
|
+
[addLexicalNode$]: [NotesListItemNode, listItemNodeReplacement, ListNode],
|
|
66
|
+
[addExportVisitor$]: [LexicalListVisitor, LexicalListItemVisitor],
|
|
67
|
+
[addToMarkdownExtension$]: gfmTaskListItemToMarkdown(),
|
|
68
|
+
[addComposerChild$]: [TabIndentationPlugin, ListPlugin, CheckListPlugin],
|
|
69
|
+
[addNestedEditorChild$]: [TabIndentationPlugin, ListPlugin, CheckListPlugin]
|
|
70
|
+
// Note: intentionally not registered to addTableCellEditorChild$ — lists are not supported in table cells
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
function getElementNodesInSelection(selection) {
|
|
75
|
+
const nodesInSelection = selection.getNodes();
|
|
76
|
+
if (nodesInSelection.length === 0) {
|
|
77
|
+
return /* @__PURE__ */ new Set([selection.anchor.getNode().getParentOrThrow(), selection.focus.getNode().getParentOrThrow()]);
|
|
78
|
+
}
|
|
79
|
+
return new Set(nodesInSelection.map((n) => $isElementNode(n) ? n : n.getParentOrThrow()));
|
|
80
|
+
}
|
|
81
|
+
function isIndentPermitted(maxDepth) {
|
|
82
|
+
const selection = $getSelection();
|
|
83
|
+
if (!$isRangeSelection(selection)) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const elementNodesInSelection = getElementNodesInSelection(selection);
|
|
87
|
+
let totalDepth = 0;
|
|
88
|
+
for (const elementNode of elementNodesInSelection) {
|
|
89
|
+
if ($isListNode(elementNode)) {
|
|
90
|
+
totalDepth = Math.max($getListDepth(elementNode) + 1, totalDepth);
|
|
91
|
+
} else if ($isListItemNode(elementNode)) {
|
|
92
|
+
const parent = elementNode.getParent();
|
|
93
|
+
if (parent?.getChildren().length === 1) {
|
|
94
|
+
const grandParentListItem = parent.getParent();
|
|
95
|
+
if ($isListItemNode(grandParentListItem) && grandParentListItem.getChildren().length === 1) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (!$isListNode(parent)) {
|
|
100
|
+
throw new Error("ListMaxIndentLevelPlugin: A ListItemNode must have a ListNode for a parent.");
|
|
101
|
+
}
|
|
102
|
+
totalDepth = Math.max($getListDepth(parent) + 1, totalDepth);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return totalDepth <= maxDepth;
|
|
106
|
+
}
|
|
107
|
+
export {
|
|
108
|
+
applyListType$,
|
|
109
|
+
currentListType$,
|
|
110
|
+
listsPlugin
|
|
111
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ORDERED_LIST, UNORDERED_LIST, CHECK_LIST, BOLD_ITALIC_STAR, BOLD_ITALIC_UNDERSCORE, BOLD_STAR, BOLD_UNDERSCORE, INLINE_CODE, ITALIC_STAR, ITALIC_UNDERSCORE, QUOTE, LINK, CODE } from "@lexical/markdown";
|
|
3
|
+
import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
|
|
4
|
+
import { HeadingNode, $isHeadingNode, $createHeadingNode } from "@lexical/rich-text";
|
|
5
|
+
import { realmPlugin } from "../../RealmWithPlugins.js";
|
|
6
|
+
import { CodeBlockNode, $createCodeBlockNode } from "../codeblock/CodeBlockNode.js";
|
|
7
|
+
import { activePlugins$, addTableCellEditorChild$, addNestedEditorChild$, addComposerChild$ } from "../core/index.js";
|
|
8
|
+
import { allowedHeadingLevels$ } from "../headings/index.js";
|
|
9
|
+
import { HorizontalRuleNode, $createHorizontalRuleNode, $isHorizontalRuleNode } from "@lexical/react/LexicalHorizontalRuleNode";
|
|
10
|
+
const markdownShortcutPlugin = realmPlugin({
|
|
11
|
+
init(realm) {
|
|
12
|
+
const pluginIds = realm.getValue(activePlugins$);
|
|
13
|
+
const allowedHeadingLevels = pluginIds.includes("headings") ? realm.getValue(allowedHeadingLevels$) : [];
|
|
14
|
+
const transformers = pickTransformersForActivePlugins(pluginIds, allowedHeadingLevels);
|
|
15
|
+
const tableCellTransformers = transformers.filter((t) => !LIST_TRANSFORMERS.has(t));
|
|
16
|
+
realm.pubIn({
|
|
17
|
+
[addComposerChild$]: () => /* @__PURE__ */ jsx(MarkdownShortcutPlugin, { transformers }),
|
|
18
|
+
[addNestedEditorChild$]: () => /* @__PURE__ */ jsx(MarkdownShortcutPlugin, { transformers }),
|
|
19
|
+
[addTableCellEditorChild$]: () => /* @__PURE__ */ jsx(MarkdownShortcutPlugin, { transformers: tableCellTransformers })
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
const createBlockNode = (createNode) => {
|
|
24
|
+
return (parentNode, children, match) => {
|
|
25
|
+
const node = createNode(match);
|
|
26
|
+
node.append(...children);
|
|
27
|
+
parentNode.replace(node);
|
|
28
|
+
node.select(0, 0);
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
const THEMATIC_BREAK = {
|
|
32
|
+
dependencies: [HorizontalRuleNode],
|
|
33
|
+
export: (node) => {
|
|
34
|
+
return $isHorizontalRuleNode(node) ? "***" : null;
|
|
35
|
+
},
|
|
36
|
+
regExp: /^(---|\*\*\*|___)\s?$/,
|
|
37
|
+
replace: (parentNode, _1, _2, isImport) => {
|
|
38
|
+
const line = $createHorizontalRuleNode();
|
|
39
|
+
if (isImport || parentNode.getNextSibling() != null) {
|
|
40
|
+
parentNode.replace(line);
|
|
41
|
+
} else {
|
|
42
|
+
parentNode.insertBefore(line);
|
|
43
|
+
}
|
|
44
|
+
line.selectNext();
|
|
45
|
+
},
|
|
46
|
+
type: "element"
|
|
47
|
+
};
|
|
48
|
+
const LIST_TRANSFORMERS = /* @__PURE__ */ new Set([ORDERED_LIST, UNORDERED_LIST, CHECK_LIST]);
|
|
49
|
+
function pickTransformersForActivePlugins(pluginIds, allowedHeadingLevels) {
|
|
50
|
+
const transformers = [
|
|
51
|
+
BOLD_ITALIC_STAR,
|
|
52
|
+
BOLD_ITALIC_UNDERSCORE,
|
|
53
|
+
BOLD_STAR,
|
|
54
|
+
BOLD_UNDERSCORE,
|
|
55
|
+
INLINE_CODE,
|
|
56
|
+
ITALIC_STAR,
|
|
57
|
+
ITALIC_UNDERSCORE
|
|
58
|
+
// HIGHLIGHT,
|
|
59
|
+
// STRIKETHROUGH
|
|
60
|
+
];
|
|
61
|
+
if (pluginIds.includes("headings")) {
|
|
62
|
+
const minHeadingLevel = Math.min(...allowedHeadingLevels);
|
|
63
|
+
const maxHeadingLevel = Math.max(...allowedHeadingLevels);
|
|
64
|
+
const headingRegExp = new RegExp(`^(#{${minHeadingLevel},${maxHeadingLevel}})\\s`);
|
|
65
|
+
const HEADING = {
|
|
66
|
+
dependencies: [HeadingNode],
|
|
67
|
+
export: (node, exportChildren) => {
|
|
68
|
+
if (!$isHeadingNode(node)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const level = Number(node.getTag().slice(1));
|
|
72
|
+
return "#".repeat(level) + " " + exportChildren(node);
|
|
73
|
+
},
|
|
74
|
+
regExp: headingRegExp,
|
|
75
|
+
replace: createBlockNode((match) => {
|
|
76
|
+
const tag = `h${match[1].length}`;
|
|
77
|
+
return $createHeadingNode(tag);
|
|
78
|
+
}),
|
|
79
|
+
type: "element"
|
|
80
|
+
};
|
|
81
|
+
transformers.push(HEADING);
|
|
82
|
+
}
|
|
83
|
+
if (pluginIds.includes("thematicBreak")) {
|
|
84
|
+
transformers.push(THEMATIC_BREAK);
|
|
85
|
+
}
|
|
86
|
+
if (pluginIds.includes("quote")) {
|
|
87
|
+
transformers.push(QUOTE);
|
|
88
|
+
}
|
|
89
|
+
if (pluginIds.includes("link")) {
|
|
90
|
+
transformers.push(LINK);
|
|
91
|
+
}
|
|
92
|
+
if (pluginIds.includes("lists")) {
|
|
93
|
+
transformers.push(ORDERED_LIST, UNORDERED_LIST, CHECK_LIST);
|
|
94
|
+
}
|
|
95
|
+
if (pluginIds.includes("codeblock")) {
|
|
96
|
+
const codeTransformerCopy = {
|
|
97
|
+
...CODE,
|
|
98
|
+
dependencies: [CodeBlockNode],
|
|
99
|
+
replace: (parentNode, _children, match) => {
|
|
100
|
+
const codeBlockNode = $createCodeBlockNode({ code: "", language: match[1] ?? "", meta: "" });
|
|
101
|
+
parentNode.selectPrevious();
|
|
102
|
+
parentNode.replace(codeBlockNode);
|
|
103
|
+
setTimeout(() => {
|
|
104
|
+
codeBlockNode.select();
|
|
105
|
+
}, 80);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
transformers.push(codeTransformerCopy);
|
|
109
|
+
}
|
|
110
|
+
return transformers;
|
|
111
|
+
}
|
|
112
|
+
export {
|
|
113
|
+
markdownShortcutPlugin
|
|
114
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { QuoteNode } from "@lexical/rich-text";
|
|
2
|
+
import { MdastBlockQuoteVisitor } from "./MdastBlockQuoteVisitor.js";
|
|
3
|
+
import { LexicalQuoteVisitor } from "./LexicalQuoteVisitor.js";
|
|
4
|
+
import { realmPlugin } from "../../RealmWithPlugins.js";
|
|
5
|
+
import { addExportVisitor$, addLexicalNode$, addImportVisitor$, addActivePlugin$ } from "../core/index.js";
|
|
6
|
+
const quotePlugin = realmPlugin({
|
|
7
|
+
init(realm) {
|
|
8
|
+
realm.pubIn({
|
|
9
|
+
[addActivePlugin$]: "quote",
|
|
10
|
+
[addImportVisitor$]: MdastBlockQuoteVisitor,
|
|
11
|
+
[addLexicalNode$]: QuoteNode,
|
|
12
|
+
[addExportVisitor$]: LexicalQuoteVisitor
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
export {
|
|
17
|
+
quotePlugin
|
|
18
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { useEffect, useCallback, useMemo, createContext } from "react";
|
|
3
|
+
import { realmPlugin } from "../../RealmWithPlugins.js";
|
|
4
|
+
import { addComposerChild$ } from "../core/index.js";
|
|
5
|
+
const RemoteMDXEditorRealmContextValueStub = {
|
|
6
|
+
editorMap: /* @__PURE__ */ new Map(),
|
|
7
|
+
registerEditor: (_id, _realm) => void 0
|
|
8
|
+
};
|
|
9
|
+
const RemoteMDXEditorRealmContext = createContext(RemoteMDXEditorRealmContextValueStub);
|
|
10
|
+
const RemoteMDXEditorRealmProvider = ({ children }) => {
|
|
11
|
+
const [editorMap, setEditorMap] = React.useState(/* @__PURE__ */ new Map());
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
return () => {
|
|
14
|
+
setEditorMap(/* @__PURE__ */ new Map());
|
|
15
|
+
};
|
|
16
|
+
}, []);
|
|
17
|
+
const registerEditor = useCallback((id, realm) => {
|
|
18
|
+
setEditorMap((prev) => {
|
|
19
|
+
return new Map(prev).set(id, realm);
|
|
20
|
+
});
|
|
21
|
+
}, []);
|
|
22
|
+
const contextValue = useMemo(
|
|
23
|
+
() => ({
|
|
24
|
+
editorMap,
|
|
25
|
+
registerEditor
|
|
26
|
+
}),
|
|
27
|
+
[editorMap, registerEditor]
|
|
28
|
+
);
|
|
29
|
+
return /* @__PURE__ */ jsx(RemoteMDXEditorRealmContext.Provider, { value: contextValue, children });
|
|
30
|
+
};
|
|
31
|
+
const RemotePluginRegister = ({ realm, editorId }) => {
|
|
32
|
+
const { registerEditor } = React.useContext(RemoteMDXEditorRealmContext);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
registerEditor(editorId, realm);
|
|
35
|
+
}, [realm, editorId, registerEditor]);
|
|
36
|
+
return null;
|
|
37
|
+
};
|
|
38
|
+
const remoteRealmPlugin = realmPlugin({
|
|
39
|
+
init: (realm, params) => {
|
|
40
|
+
if (params?.editorId) {
|
|
41
|
+
realm.pub(addComposerChild$, () => /* @__PURE__ */ jsx(RemotePluginRegister, { realm, editorId: params.editorId }));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
function useRemoteMDXEditorRealm(editorId) {
|
|
46
|
+
return React.useContext(RemoteMDXEditorRealmContext).editorMap.get(editorId);
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
RemoteMDXEditorRealmProvider,
|
|
50
|
+
remoteRealmPlugin,
|
|
51
|
+
useRemoteMDXEditorRealm
|
|
52
|
+
};
|