TypeCellOS / BlockNote

A React Rich Text Editor that's block-based (Notion style) and extensible. Built on top of Prosemirror and Tiptap.
https://www.blocknotejs.org/
Mozilla Public License 2.0
6.46k stars 440 forks source link

Custom inline component exported value #781

Closed galer7 closed 4 months ago

galer7 commented 4 months ago

Is your feature request related to a problem? Please describe. The docs don't provide an example for a custom inline component's exported value: https://www.blocknotejs.org/examples/custom-schema/suggestion-menus-mentions

Describe the solution you'd like Trying to create a custom inline component using createReactInlineContentSpec, but I want to render something e.g. @steve, but when I export to markdown I want to get something else e.g. <steve>.

Describe alternatives you've considered render's method params, namely inlineContent and contentRef

Additional context Code I went over:

Bonus [ ] I'm a sponsor and would appreciate if you could look into this sooner than later 💖

galer7 commented 4 months ago

Actually what I wanted was a function similar to blocksToMarkdownLossy that treats the custom elements properly:

  const editorContent = blocks.reduce((acc, block) => {
    let currentBlockContent = "";

    if (block.type === "heading") {
      currentBlockContent = "#".repeat(block.props.level);
    }

    // TODO: implement edge cases e.g. bullet list
    currentBlockContent += block.content!.reduce((acc, inline) => {
      if (inline.type === "text") {
        return acc + inline.text;
      }

      if (inline.type === "mention") {
        return acc + inline.props.data;
      }
    }, "");

    return acc + currentBlockContent;
  }, "");
  onChange(editorContent);

where Mention has an extra data prop:

export const Mention = createReactInlineContentSpec(
  {
    type: "mention",
    propSchema: {
      path: {
        default: "No path",
      },
      data: {
        default: "No data",
      },
    },
    content: "none",
  },
  {
    render: ({ inlineContent }) => {
      return (
        <span style={{ backgroundColor: "#8400ff33" }}>
          @{inlineContent.props.path}
        </span>
      );
    },
  }
);