Is it possible to prevent new paragraph node with enter in editor?
Asked Answered
P

5

6

I´m trying to create a "one line" message component based on Lexical, but i´m unable to prevent the enter key to create a new paragraph.

Any ideas how to accomplish this?

I´ve added styling with

white-space: nowrap!important; 
      resize: none;

and i´ve tried to MaxLengthPlugin ( which works but if enter in there it creates two lines)

also tried to add

<EditorWrapper ref={onRef} data-testid="editor" 
        onKeyDown={event => {
            if (event.key === 'Enter') {
              event.preventDefault();
            } 
          }}>

I was expecting this to prevent the new paragraph with enter, but still adds a new paragraph in the editor.

Perspire answered 25/11, 2022 at 14:54 Comment(0)
Q
11

I was able to create a single line editor by using registerNodeTransform to remove the LineBreakNode as soon as it's created. It doesn't feel like the best solution, but it works.

editor.registerNodeTransform(LineBreakNode, (node) => {
  node.remove();
});

I also explored listening to the KEY_ENTER_COMMAND command, but that didn't prevent newlines from being pasted into the editor.

Quartern answered 9/12, 2022 at 22:29 Comment(2)
Thanks for the solution! The LineBreakNode helped to stop the users from adding </br> but I also had to register to the RootNode to prevent new paragraphs. mergeRegister( editor.registerNodeTransform(RootNode, (rootNode: RootNode) => { if (rootNode.getChildrenSize() <= 1) return; rootNode.getLastChild()?.remove(); }), editor.registerNodeTransform(LineBreakNode, (node) => { node.remove(); }), ) Erbil
By the way, the following comment by Dominic Gannaway gives a good explanation of why editor.registerNodeTransform is a good approach: The simplest way is to use a node transform on your heading node and check its children for a line break and remove it. This will scale well for when someone might copy and paste a linebreak in too (vs the naive approach of blocking the keyboard shortcut). Source`Erbil
S
5

You can register the command INSERT_PARAGRAPH_COMMAND and then return true. By returning true you tell lexical that you have handled the paragraph insert and the default lexical code will not execute.

Example:

useEffect(() => {
   return editor.registerCommand(
      INSERT_PARAGRAPH_COMMAND, 
      () => {
          return true;
      },
      COMMAND_PRIORITY_EDITOR
);}, [editor]);
Shade answered 19/1, 2023 at 18:5 Comment(1)
this is a good solution, though i needed to use COMMAND_PRIORITY_LOW to get my command handler to run. also, if you want to create a “submit on enter” UX (like with native HTML text inputs in forms), you can update the command handler here to: () => { editor.blur(); return true },Irreducible
S
0

If I understand correctly you only want to edit in one line and not allow multiple lines.

For this you can try to use INSERT_LINE_BREAK_COMMAND and prevent line breaks from being added by returning true for the command.

editor.registerCommand(INSERT_LINE_BREAK_COMMAND, () => true, COMMAND_PRIORITY_LOW)
Staunch answered 11/7, 2023 at 16:36 Comment(0)
R
0

I could achieve this by listening on the contenteditable element and use e.preventDefault() like so:

<LexicalComposer
  <PlainTextPlugin
    contentEditable={
      <ContentEditable
        onKeyDown={(e) => {
            e.preventDefault();
        }}
      />
    }
  />
</LexicalComposer>
Rhamnaceous answered 24/7, 2023 at 8:57 Comment(1)
In this way no para will be inserted, but even normal characters are blocked as well?Puggree
S
0

Commands are one way to handle Enter Key.

    useEffect(() => {
    return editor.registerCommand(
      KEY_ENTER_COMMAND,
      (payload: KeyboardEvent) => {
        if (
          payload.key === 'Enter'
        ) {
          // Your logic here
          return true;
        }
        return false;
      },
      COMMAND_PRIORITY_CRITICAL
    );
  }, [editor, onEnterKeyPressed]);

Returning true would indicate that you have handled the command.

More Info: https://lexical.dev/docs/concepts/commands

Santinasantini answered 9/1 at 10:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.