onlook icon indicating copy to clipboard operation
onlook copied to clipboard

fix: Enable line breaks in text editor with conditional Enter handlin…

Open Rish-it opened this issue 6 months ago • 8 comments

Fix: Enable line breaks in text editor with conditional Enter handling - Import splitBlock from prosemirror-commands for line break functionality - Modify Enter key handler to use conditional logic: Exit editor on empty paragraph or at end of single-line text, Create new paragraph/line break for normal text editing - Resolves issue where users couldn't insert line breaks in text elements - Fixes #2065

Description

This PR fixes a critical UX issue where users cannot insert line breaks in text elements. Previously, pressing Enter (or any variant like Ctrl+Enter, Command+Enter) would always exit the text editor, preventing multi-line text editing.

Changes Made:

  • Import splitBlock from prosemirror-commands for proper line break functionality
  • Implement conditional Enter key handling logic:
    • Exit editor: When Enter is pressed on empty paragraph or at end of single-line text
    • Create line break: When Enter is pressed in normal text editing scenarios
  • Preserve existing quick-edit workflow while enabling multi-line text support

Before: Enter key always exited the editor After: Enter key intelligently creates line breaks or exits based on context

Related Issues

Fixes #2065

Type of Change

  • [x] Bug fix
  • [ ] New feature
  • [ ] Documentation update
  • [ ] Release
  • [ ] Refactor
  • [ ] Other (please describe):

Testing

Manual Testing Performed:

  • Verified Enter creates new paragraphs in multi-line text
  • Verified Enter exits editor when pressed on empty paragraphs
  • Verified Escape always exits text editor
  • Verified text wraps naturally at container boundaries
  • Confirmed existing single-line editing workflow is preserved

Test Scenarios:

  1. Multi-line text editing: Type text, press Enter, continue typing → Creates line break
  2. Quick exit: Click text, press Enter immediately → Exits editor
  3. End-of-text exit: Type text, position cursor at end, press Enter → Exits editor
  4. Mid-text line break: Position cursor in middle of text, press Enter → Creates line break

Screenshots (if applicable)

https://github.com/user-attachments/assets/24fb35cf-3c6d-44cc-b81d-74d2dae5407f

Additional Notes

  • UX consideration: Maintains existing workflow for power users while enabling expected text editing behavior
  • No breaking changes: Existing functionality is preserved

[!IMPORTANT] Fixes Enter key behavior in text editor to allow line breaks using splitBlock from prosemirror-commands.

  • Behavior:
    • Import splitBlock from prosemirror-commands in index.ts for line break functionality.
    • Modify Enter key handler in index.ts to:
      • Exit editor on empty paragraph or end of single-line text.
      • Create line break in normal text editing.
  • Testing:
    • Verified Enter creates new paragraphs in multi-line text.
    • Verified Enter exits editor on empty paragraphs.
    • Verified Escape always exits text editor.
    • Confirmed text wraps naturally at container boundaries.

This description was created by Ellipsis for d989f0b0fa36039a7fc0140b892fe2cb8a411167. You can customize this summary. It will automatically update as commits are pushed.

Rish-it avatar Jun 06 '25 15:06 Rish-it

@Rish-it is attempting to deploy a commit to the Onlook Team on Vercel.

A member of the Team first needs to authorize it.

vercel[bot] avatar Jun 06 '25 15:06 vercel[bot]

Hey @Rish-it , This is great stuff, I didn't know about splitBlock. The more challenging part is how that would play into how that gets written into code. There are a few options:

  1. Add a newline character <br/> in the content
  2. Refactor the text block into or something similar.

I think there are patterns in existing WYSIWYG editors but wondering what your thoughts are?

My thinking is wrapping the existing text in

tag and new lines in

https://github.com/onlook-dev/onlook/blob/main/apps/web/client/src/components/store/editor/text/index.ts#L107

Kitenite avatar Jun 06 '25 18:06 Kitenite

Hey @Rish-it , This is great stuff, I didn't know about splitBlock. The more challenging part is how that would play into how that gets written into code. There are a few options:

  1. Add a newline character <br/> in the content
  2. Refactor the text block into or something similar.

I think there are patterns in existing WYSIWYG editors but wondering what your thoughts are?

My thinking is wrapping the existing text in

tag and new lines in

https://github.com/onlook-dev/onlook/blob/main/apps/web/client/src/components/store/editor/text/index.ts#L107

Hey, thanks for the feedback! Just wanted to share a bit of my thinking around the splitBlock change. It’s the typical way ProseMirror handles multi-line editing, and I felt it sets us up for a smoother editing experience going forward. I’ve been considering two directions.

  1. One is to keep it simple and use <br/> tags between paragraphs, which would fit easily into our existing setup.
  2. Go with proper <p> tags for each paragraph, which you suggested.

I’m leaning toward the semantic route with <p> tags. It’s a bit more upfront work, but it feels like the right long-term move. I can update the serialization logic to detect multi-paragraph content and wrap things in <p> tags where it makes sense.

I did opened a discussion for this if you wanna take a look https://github.com/orgs/onlook-dev/discussions/2082 Curious to hear your thoughts does that direction make sense to you?

Rish-it avatar Jun 07 '25 07:06 Rish-it

The trade offs are that we'd assume the user wants to continually edit the same code block after.

Say we go with p tag, if you double click to edit again, would you get the exact p tag instead of the entire 2 lines? This would seem like unexpected behavior.

For examples starting with

<div>hello world</div>

Into

<div>
<p>hello</p>
<p>world</p>
</div>

When double clicking, we'd edit either hello or world with the current setup. I think we'd want to treat hello world as one editable block. (Least unexpected)

Not saying it's bad just something to think about. Unless we can someone detect and group the p tags back at edit time. What're your thoughts?

Kitenite avatar Jun 07 '25 08:06 Kitenite

Agreed! The semantic HTML benefit of splitBlock isn't worth the complexity trade-off for most use cases. And for spiltBlock to work properly which I intended to, I need to have certain logic to handle both use cases

 // Handle original/exisiting
    if (hasSimpleTextContent(element)) {
        return editNormally(element);
    }
// Handle new paragraph structure  
    if (hasParagraphChildren(element)) {
        return editWithParagraphLogic(element);
    }
}

Apart from significant changes in editor and canvas I need to take care of

  • Update DOM handling for <br/> content
  • Test paragraph group editing behavior I do have one more Approach to workaround, I will be happy to drop and discuss over it?

Rish-it avatar Jun 07 '25 13:06 Rish-it

Sounds great, excited to see it!

Kitenite avatar Jun 07 '25 16:06 Kitenite

@Rish-it , just wanna circle on this. Would you rather I merged this in first? I hesitate to do so since it'll cause unexpected behavior for our user (new line doesn't add real new line).

Kitenite avatar Jun 08 '25 18:06 Kitenite

Thanks for checking in @Kitenite I completely understand the concern I'd recommend holding off on merging for now. I'm actively working on an improved approach that addresses the new line behavior more reliably. Should have an update for you shortly!

I had considered the hotkey approach earlier, but felt it might introduce unnecessary complexity for a simple operation. Since we're building design-centric software, I think it’s important to minimize such overhead and keep the UX as intuitive as possible. And we can always go back it what do you think?

Rish-it avatar Jun 09 '25 03:06 Rish-it

Closing since there's a newer PR

Kitenite avatar Jun 11 '25 16:06 Kitenite