Tiptap how to create a paragraph (p) on Shift-Enter, instead of a br?

Viewed 1204

Using TipTap, I'm trying to avoid adding a <br />, but create a <p></p> instead, with the focus inside that <p>|</p> when the user hit shift-Enter but I can't make it work.

Here's what I did so far:

new (class extends Extension {
    keys () {
        return {
            'Shift-Enter' (state, dispatch, view) {
                const { schema, tr } = view.state
                const paragraph = schema.nodes.paragraph

                console.log(tr.storedMarks)
                const transaction = tr.deleteSelection().replaceSelectionWith(paragraph.create(), true).scrollIntoView()
                view.dispatch(transaction)
                return true
            }
        }
    }
})()

How can I do this?

2 Answers

I don't know if this is still relevant but as I was looking for the same thing, I found two ways to make this work.

NOTE: I'm using tiptap v2, if that's not a problem, then:

I overrode the HardBreak extension, since it's the one that use the Shift-Enter keybinding. It looks something like;

const CustomHardBreak = HardBreak.extend({
  addKeyboardShortcuts() {
    return {
      "Mod-Enter": () => this.editor.commands.setHardBreak(),
      "Shift-Enter": () => this.editor.commands.addNewline(),
    };
  },
});

And used it like so;

editor = new Editor({
  extensions: [
    customNewline,
    CustomHardBreak,
  ]
});
  1. Use the default editor command createParagraphNear. E.g this.editor.commands.createParagraphNear()

  2. I tried creating a custom extension from your code and ended up with something similar to the command above, i.e;

export const customNewline = Extension.create({
  name: "newline",
  priority: 1000, // Optional
  addCommands() {
    return {
      addNewline:
        () =>
        ({ state, dispatch }) => {
          const { schema, tr } = state;
          const paragraph = schema.nodes.paragraph;

          const transaction = tr
            .deleteSelection()
            .replaceSelectionWith(paragraph.create(), true)
            .scrollIntoView();
          if (dispatch) dispatch(transaction);
          return true;
        },
    };
  },
  addKeyboardShortcuts() {
    return {
      "Shift-Enter": () => this.editor.commands.addNewline(),
    };
  },
});

And added this as an extension in my editor instance.

PS: They both work, almost exactly the same, I haven't found a difference yet. But there's somewhat of a 'catch' if you would call it that; Both these methods don't work on empty lines/nodes, a character has to be added before the cursor for it to work, any character, even a space.

In TipTap 2.0 I am able to use this custom extension:

const ShiftEnterCreateExtension = Extension.create({
  addKeyboardShortcuts() {
    return {
      "Shift-Enter": ({ editor }) => {
        editor.commands.enter();
        return true;
      },
    };
  },
});

To make shift + enter behave like enter.

In my case I actually wanted enter to do something different. So I use prosemirror events to set a ref flag on whether shift was pressed. Than I check that flag under the "Enter" keyboard event -- which could be triggered normally or through the shift + enter extension.

Related