Prosemirror adapter for React and Vue

Hi there. I just made a toolkit to make it possible to write prosemirror nodeviews with React or Vue components.

Github: prosemirror-adapter

5 Likes

Nice package. You will not ever be able to render marks using React or something though, so if the empty checkbox there indicates a plan to support this in the future, I recommend dropping it.

1 Like

Thanks for the hint! I thought we can do something between dom and contentDOM in mark view. So you mean something like this aren’t possible?

const markView: MarkConstructor = (mark, view, inline) => {
  const dom = document.createElement('a');
  const contentDOM = document.createElement('span');
  const { href, title } = mark.attrs;
  
  const styleDOM = createStyleDOM(href, title);

  dom.appendChild(styleDOM);
  dom.appendChild(contentDOM);
  
  return {
    dom,
    contentDOM,
  }
}

Indeed. Marks can only be rendered by simple wrapping nodes, nothing more complicated.

I just tried this with the prosemirror-basic-schema

  // ...
  markViews: {
            link: (mark) => {
                const dom = document.createElement('a');
                const contentDOM = document.createElement('span');

                const { href, title } = mark.attrs;

                const post = `(${href}${title ? `, "${title}"` : ''})`;

                const preDOM = document.createElement('span');
                preDOM.style.color = 'blue';
                preDOM.appendChild(document.createTextNode('['));
                preDOM.appendChild(contentDOM);
                preDOM.appendChild(document.createTextNode(']'));

                const postDOM = document.createElement('span');
                postDOM.style.color = 'purple';
                postDOM.innerText = post;

                dom.appendChild(preDOM);
                dom.appendChild(postDOM);

                return {
                    dom,
                    contentDOM,
                };
}

And this is what I got:

Do you think it’s legal? Or it’s something anti-pattern that I didn’t realize.

I’m pretty sure that will create a big mess as soon as you try to make something bold inside of the link, and there may be other issues that I don’t know off the top of my head. The expectation of the library is that marks are rendered with simple wrapper elements.

Yeah, I tried and wired things happened. Seems if we want such a complex link, maybe we’d better to make it an inline node?

And, what about decorations. Do you think it’s possible to create some complicated widget decorations?

1 Like

Those are tricky too, because native editing behavior is rather random when you type stuff on element boundaries.

Definitely.

Thanks for the reply. So, what’s the recommended way to do something like an hybrid editing behavior?

For example, for a bold mark, it will display <**this is a bold**> when selection is in it’s content, and will display <this is a bold> when selection is out of the range.

That would be done with decoration widgets that display the asterisks when appropriate.

Interesting, then I think I could add some input box in decorations and bind some events on them to make it possible to modify the mark.attrs.

Nice! Great you bothered to nail it down and not make it coupled with a framework. Tests next :grinning:?

Thanks. Yeah, unit test is in the plan list. So does the plugin view apdater.