Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enter handling as Extension #1165

Closed
onhate opened this issue Jan 11, 2021 · 6 comments
Closed

Enter handling as Extension #1165

onhate opened this issue Jan 11, 2021 · 6 comments
Assignees

Comments

@onhate
Copy link

onhate commented Jan 11, 2021

First: The new rewrite looks awesome, so clean and easy (almost intuitive), congrats! I'm actually 'stealling' the design pattern on the .extend and .configure to use on other stuff, just loved how it can easly modify existing pluins without the need to copy the code and modify.

Thinking about that, I came to realize that Enter is a very important key to not be properly managed in a centralized way, the concern came when I added the task-list and list-item extensions on the same editor and pressing enter on task-item did not add a new item, and when I thought I fixed that for task-item it started happening on list-item...

In the end I had to create a extension that control the enter key for both and register it before all other extensions, then I came across this commit ueberdosis/tiptap-next@43dc14b and noticed that more scenarios needs to be covered.

I don't actually have a solution for that, but what I suggest is something like this but with possibility to extend and add more commands so you can register it first before other extensions take control over Enter key.

export const Enter = Extension.create({
  name: 'enter',

  addKeyboardShortcuts() {
    return {
      Enter: () => {
        return [
          (this.editor.commands as any).splitListItem('taskItem'), //
          (this.editor.commands as any).splitListItem('listItem')
        ].find(Boolean);
      }
    };
  }
});
@philippkuehn
Copy link
Contributor

Hey, I think we should better explain in the docs how keyboard events work under the hood. So I'll give it a try here:

This is the default enter handler defined in @tiptap/core

addKeyboardShortcuts() {
  return {
    Enter: () => this.editor.commands.first(({ commands }) => [
      () => commands.newlineInCode(),
      () => commands.createParagraphNear(),
      () => commands.liftEmptyBlock(),
      () => commands.splitBlock(),
    ]),
  }
}

If you press enter, one command after the other will be tried. This is what the first command is for (https://next.tiptap.dev/api/commands#try-commands).
In this case newlineInCode -> createParagraphNear -> liftEmptyBlock -> splitBlock. It will stop at the first command that returns true. If one of these commands returns true, the first command returns also true.

If you want to extend the enter handler, you can do this in an extension. Take a look at the list-item extension:

addKeyboardShortcuts() {
  return {
    Enter: () => this.editor.commands.splitListItem('listItem'),
  }
}

This registers a new keymap plugin. Extension order matters. The last enter handler is called first. So in this case:
splitListItem -> newlineInCode -> createParagraphNear -> liftEmptyBlock -> splitBlock.

Your command should check if it can be applied. Otherwise it should return false. In this case splitListItem checks if the current selection is within a list. If not, it returns false and the default enter handler will be called.

That being said, I’m not sure what you're trying to achieve here:

return [
  (this.editor.commands as any).splitListItem('taskItem'),
  (this.editor.commands as any).splitListItem('listItem'),
].find(Boolean);

Is splitListItem not working as expected for you?

And why are you writing (this.editor.commands as any)? Is TypeScript autocomplete not working for you? It should know the commands at this point:

2HKq4v6qpC

@hanspagel hanspagel assigned hanspagel and unassigned philippkuehn Jan 12, 2021
@onhate
Copy link
Author

onhate commented Jan 12, 2021

Thanks for the quick response.

Without adding the Enter extensions I shared as first item in the extensions lists containing TextAlign extension when I press enter on the task list item it does not adds a new item, instead it adds a new paragraph inside the li

image

The same happens to list item

image

But if I remove the TextAlign extension it works fine

image

regarding the cast to any, this is what I get
image

I think it's because createCommands on command manager returns a different type than Commands

@onhate
Copy link
Author

onhate commented Jan 12, 2021

Now that you mentioned The last enter handler is called first when I move TextAlign to the end of the list of extensions it works fine, it needs to be

...
ListItem
TaskItem
...
TextAlign
...

@philippkuehn
Copy link
Contributor

Ah, you are using the TextAlign extension! So this is basically a duplicate of https://github.com/ueberdosis/tiptap-next/issues/72.

@onhate
Copy link
Author

onhate commented Jan 12, 2021

hmm, right. thanks

@onhate onhate closed this as completed Jan 12, 2021
@philippkuehn
Copy link
Contributor

This should working as expected now. see https://github.com/ueberdosis/tiptap-next/issues/72#issuecomment-769673194 and https://github.com/ueberdosis/tiptap-next/issues/115#issuecomment-769194708

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants