From b303a99341997d47eeb300913ed9f04daf816d79 Mon Sep 17 00:00:00 2001 From: Petyo Ivanov Date: Thu, 2 Nov 2023 11:03:49 +0200 Subject: [PATCH] feat: support inserting JSX nodes with children --- src/examples/jsx.tsx | 37 ++++++++++++++++------- src/plugins/jsx/index.ts | 50 +++++++++++++++++++++++++------- src/plugins/link-dialog/index.ts | 2 +- 3 files changed, 67 insertions(+), 22 deletions(-) diff --git a/src/examples/jsx.tsx b/src/examples/jsx.tsx index 1397d2de..50676ee5 100644 --- a/src/examples/jsx.tsx +++ b/src/examples/jsx.tsx @@ -53,17 +53,32 @@ const jsxComponentDescriptors: JsxComponentDescriptor[] = [ const InsertMyLeaf = () => { const insertJsx = jsxPluginHooks.usePublisher('insertJsx') return ( - + <> + + + + ) } export const Example = () => { diff --git a/src/plugins/jsx/index.ts b/src/plugins/jsx/index.ts index c54ae51e..9555c9eb 100644 --- a/src/plugins/jsx/index.ts +++ b/src/plugins/jsx/index.ts @@ -77,10 +77,28 @@ export interface JsxEditorProps { descriptor: JsxComponentDescriptor } -interface InsertJsxPayload { +type JsxTextPayload = { + kind: 'text' + name: string + props: Record + children?: MdxJsxTextElement['children'] +} + +type JsxFlowPayload = { + kind: 'flow' name: string - kind: 'flow' | 'text' props: Record + children?: MdxJsxFlowElement['children'] +} + +type InsertJsxPayload = JsxTextPayload | JsxFlowPayload + +function toMdastJsxAttributes(attributes: Record): MdastJsx['attributes'] { + return Object.entries(attributes).map(([name, value]) => ({ + type: 'mdxJsxAttribute', + name, + value + })) } /** @internal */ @@ -91,14 +109,26 @@ export const jsxSystem = system( r.link( r.pipe( insertJsx, - r.o.map(({ name, kind, props }) => { - return () => - $createLexicalJsxNode({ - name, - type: kind === 'flow' ? 'mdxJsxFlowElement' : 'mdxJsxTextElement', - attributes: Object.entries(props).map(([name, value]) => ({ type: 'mdxJsxAttribute', name, value })), - children: [] - }) + r.o.map(({ kind, name, children, props }) => { + return () => { + const attributes = toMdastJsxAttributes(props) + + if (kind === 'flow') { + return $createLexicalJsxNode({ + type: 'mdxJsxFlowElement', + name, + children: children ?? [], + attributes + }) + } else { + return $createLexicalJsxNode({ + type: 'mdxJsxTextElement', + name, + children: children ?? [], + attributes + }) + } + } }) ), insertDecoratorNode diff --git a/src/plugins/link-dialog/index.ts b/src/plugins/link-dialog/index.ts index aab0c849..7a67bd8e 100644 --- a/src/plugins/link-dialog/index.ts +++ b/src/plugins/link-dialog/index.ts @@ -178,7 +178,7 @@ const linkDialogSystem = system( if (url.trim() !== '') { editor?.dispatchCommand(TOGGLE_LINK_COMMAND, { url, title }) - // the dispatch command implementation fails to set the link for a fresh link creation. + // the dispatch command implementation fails to set the title for a fresh link creation. // Work around with the code below. setTimeout(() => { editor?.update(() => {