Are there any complex custom element examples?

Hi,

I was using 0.6.x with my own custom nodes. As update to 0.10/0.12 is basically a rewrite of ProseMirror-related components I’m looking for an example of custom components with attributes. Are there any or deep dive into other projects using ProseMirror is the only option?

Cheers!

This is something that I definitely want to document, but haven’t gotten around to. What kind of custom nodes are you building? We could use this thread as a first sketch for such docs.

My use case is building document template with certain fields editable. I need to provide inline node which attribute allows for passing default text (it’s content editable after render). We store JSON in the database and paring source to produce react components. Other components are just block elements with couple text attributes which are used only during the render.

I can’t make very much of your description. Could you be a little more concrete, and include examples?

Ok, I’ve figured it out mostly based on what I’ve found in https://github.com/ProseMirror/prosemirror-example-setup.

export const contractEditable = {
  attrs: {
    name: { default: "" },
    placeholder: { default: "" },
  },

  toDOM: node => ["input", {
    "data-contract-editable": true,
    name: node.attrs.name,
    placeholder: node.attrs.placeholder,
  }],

  parseDOM: [{
    tag: "input[data-contract-editable]",
    getAttrs: dom => {
      const name = dom.getAttribute("name");
      const placeholder = dom.getAttribute("placeholder");
      return { name, placeholder };
    },
  }],

  inline: true,
  group: "inline",
};

menu.insertMenu.content = [new MenuItem({
  title: "Insert contract editable",
  label: "Contract editable",
  select(state) {
    return insertPoint(state.doc, state.selection.from, contractEditableType) != null;
  },
  run(state, onAction) {
    const { name, placeholder } = contractEditableType.attrs;

    openPrompt({
      title: "Insert contract editable",
      fields: {
        name: new TextField({ label: "Name", required: true, value: name.default }),
        placeholder: new TextField({ label: "Placeholder", value: placeholder.default }),
      },
      callback(attrs) {
        onAction(state.tr.replaceSelection(contractEditableType.createAndFill(attrs)).action());
      },
    });
  },
}), ...menu.insertMenu.content];