diff --git a/src/examples/nested-jsx-elements.tsx b/src/examples/nested-jsx-elements.tsx
new file mode 100644
index 00000000..8836173c
--- /dev/null
+++ b/src/examples/nested-jsx-elements.tsx
@@ -0,0 +1,116 @@
+import React from 'react'
+import { MdxJsxTextElement } from 'mdast-util-mdx'
+import {
+ Button,
+ DiffSourceToggleWrapper,
+ JsxComponentDescriptor,
+ MDXEditor,
+ NestedLexicalEditor,
+ UndoRedo,
+ diffSourcePlugin,
+ jsxPlugin,
+ jsxPluginHooks,
+ toolbarPlugin
+} from '../'
+const jsxMarkdown = `
+ Content *foo*more Content
+ `
+const jsxComponentDescriptors: JsxComponentDescriptor[] = [
+ {
+ name: 'Card',
+ kind: 'text',
+ source: './external',
+ props: [],
+ hasChildren: true,
+ Editor: () => {
+ return
+ }
+ },
+ {
+ name: 'Grid',
+ kind: 'flow',
+ source: './external',
+ props: [],
+ hasChildren: true,
+ Editor: () => {
+ return (
+
+
+ block
+ getContent={(node) => node.children}
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ getUpdatedMdastNode={(mdastNode, children: any) => {
+ return {
+ ...mdastNode,
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+ children
+ }
+ }}
+ />
+
+ )
+ }
+ }
+]
+
+const InsertCard = () => {
+ const insertJsx = jsxPluginHooks.usePublisher('insertJsx')
+ return (
+ <>
+
+ >
+ )
+}
+
+const InsertGrid = () => {
+ const insertJsx = jsxPluginHooks.usePublisher('insertJsx')
+ return (
+ <>
+
+ >
+ )
+}
+
+export const Example = () => {
+ return (
+ (
+ <>
+
+
+
+
+
+ >
+ )
+ })
+ ]}
+ />
+ )
+}
diff --git a/src/exportMarkdownFromLexical.ts b/src/exportMarkdownFromLexical.ts
index d8517dce..b4ba555b 100644
--- a/src/exportMarkdownFromLexical.ts
+++ b/src/exportMarkdownFromLexical.ts
@@ -103,6 +103,7 @@ export interface ExportLexicalTreeOptions {
visitors: LexicalVisitor[]
jsxComponentDescriptors: JsxComponentDescriptor[]
jsxIsAvailable: boolean
+ addImportStatements?: boolean
}
function isParent(node: unknown): node is Mdast.Parent {
@@ -116,7 +117,8 @@ export function exportLexicalTreeToMdast({
root,
visitors,
jsxComponentDescriptors,
- jsxIsAvailable
+ jsxIsAvailable,
+ addImportStatements = true
}: ExportLexicalTreeOptions): Mdast.Root {
let unistRoot: Mdast.Root | null = null
const referredComponents = new Set()
@@ -240,10 +242,12 @@ export function exportLexicalTreeToMdast({
const frontmatter = typedRoot.children.find((child) => child.type === 'yaml')
- if (frontmatter) {
- typedRoot.children.splice(typedRoot.children.indexOf(frontmatter) + 1, 0, ...imports)
- } else {
- typedRoot.children.unshift(...imports)
+ if (addImportStatements) {
+ if (frontmatter) {
+ typedRoot.children.splice(typedRoot.children.indexOf(frontmatter) + 1, 0, ...imports)
+ } else {
+ typedRoot.children.unshift(...imports)
+ }
}
fixWrappingWhitespace(typedRoot, [])
@@ -257,7 +261,7 @@ export function exportLexicalTreeToMdast({
}
function collapseNestedHtmlTags(node: Mdast.Parent | Mdast.Content) {
- if ('children' in node) {
+ if ('children' in node && node.children) {
if (isMdastHTMLNode(node) && node.children.length === 1) {
const onlyChild = node.children[0]
if (onlyChild.type === 'mdxJsxTextElement' && onlyChild.name === 'span') {
@@ -339,7 +343,7 @@ function fixWrappingWhitespace(node: Mdast.Parent | Mdast.Content, parentChain:
}
}
}
- if (Object.hasOwn(node, 'children')) {
+ if ('children' in node && node.children) {
const nodeAsParent = node as Mdast.Parent
nodeAsParent.children.forEach((child) => fixWrappingWhitespace(child, [...parentChain, nodeAsParent]))
}
diff --git a/src/plugins/core/LexicalTextVisitor.ts b/src/plugins/core/LexicalTextVisitor.ts
index c01b00d3..2dcba76d 100644
--- a/src/plugins/core/LexicalTextVisitor.ts
+++ b/src/plugins/core/LexicalTextVisitor.ts
@@ -8,13 +8,19 @@ export function isMdastText(mdastNode: Mdast.Content): mdastNode is Mdast.Text {
return mdastNode.type === 'text'
}
+const JOINABLE_TAGS = ['u', 'span']
+
export const LexicalTextVisitor: LexicalExportVisitor = {
shouldJoin: (prevNode, currentNode) => {
if (['text', 'emphasis', 'strong'].includes(prevNode.type)) {
return prevNode.type === currentNode.type
}
- if (prevNode.type === 'mdxJsxTextElement' && (currentNode as unknown as MdxJsxTextElement).type === 'mdxJsxTextElement') {
+ if (
+ prevNode.type === 'mdxJsxTextElement' &&
+ (currentNode as unknown as MdxJsxTextElement).type === 'mdxJsxTextElement' &&
+ JOINABLE_TAGS.includes((currentNode as unknown as MdxJsxTextElement).name as string)
+ ) {
const currentMdxNode: MdxJsxTextElement = currentNode as unknown as MdxJsxTextElement
return prevNode.name === currentMdxNode.name && JSON.stringify(prevNode.attributes) === JSON.stringify(currentMdxNode.attributes)
}
diff --git a/src/plugins/core/NestedLexicalEditor.tsx b/src/plugins/core/NestedLexicalEditor.tsx
index 089f170f..9b7eb573 100644
--- a/src/plugins/core/NestedLexicalEditor.tsx
+++ b/src/plugins/core/NestedLexicalEditor.tsx
@@ -86,14 +86,18 @@ export function useMdastNodeUpdater() {
const { parentEditor, mdastNode, lexicalNode } = useNestedEditorContext()
return function updateMdastNode(node: Partial) {
- parentEditor.update(() => {
- $addUpdateTag('history-push')
- const currentNode = $getNodeByKey(lexicalNode.getKey())
- if (currentNode) {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
- currentNode.setMdastNode({ ...mdastNode, ...node })
- }
- })
+ parentEditor.update(
+ () => {
+ $addUpdateTag('history-push')
+ const currentNode = $getNodeByKey(lexicalNode.getKey())
+ if (currentNode) {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
+ currentNode.setMdastNode({ ...mdastNode, ...node })
+ }
+ },
+ { discrete: true }
+ )
+ parentEditor.dispatchCommand(NESTED_EDITOR_UPDATED_COMMAND, undefined)
}
}
@@ -219,7 +223,8 @@ export const NestedLexicalEditor = function (props: Nes
root: $getRoot(),
visitors: exportVisitors,
jsxComponentDescriptors,
- jsxIsAvailable
+ jsxIsAvailable,
+ addImportStatements: false
})
const content: Mdast.Content[] = block ? mdast.children : (mdast.children[0] as Mdast.Paragraph)!.children
updateMdastNode(getUpdatedMdastNode(structuredClone(mdastNode) as any, content as any))
diff --git a/src/plugins/core/index.ts b/src/plugins/core/index.ts
index e06b8cac..5fd162f4 100644
--- a/src/plugins/core/index.ts
+++ b/src/plugins/core/index.ts
@@ -452,6 +452,10 @@ export const coreSystem = system((r) => {
setTimeout(() => node.select())
}
})
+
+ setTimeout(() => {
+ theEditor.dispatchCommand(NESTED_EDITOR_UPDATED_COMMAND, undefined)
+ })
}
}
})