Skip to content

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

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Rish-it
Copy link
Contributor

@Rish-it Rish-it commented Jun 6, 2025

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

  • 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)

Screen.Recording.2025-06-06.at.9.08.59.PM.mov

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 d989f0b. You can customize this summary. It will automatically update as commits are pushed.

…g - 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 onlook-dev#2065
Copy link

vercel bot commented Jun 6, 2025

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

A member of the Team first needs to authorize it.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed everything up to d989f0b in 2 minutes and 29 seconds. Click for details.
  • Reviewed 933 lines of code in 2 files
  • Skipped 0 files when reviewing.
  • Skipped posting 5 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. apps/web/client/src/components/store/editor/overlay/prosemirror/index.ts:81
  • Draft comment:
    The Enter key handler’s condition only triggers on empty or whitespace-only paragraphs. This may not invoke onEnter for non-empty single‐line text at the end (as manual test scenario 3 requires). Please verify that the intended exit behavior in quick-edit mode is correctly implemented.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
2. apps/web/preload/dist/index.js:13457
  • Draft comment:
    Switching from Number.isNaN to isNaN can lead to unintended coercion. Verify that using isNaN here is intentional and won’t misclassify non-numeric input.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
3. apps/web/preload/dist/index.js:17233
  • Draft comment:
    Typo: The property name oboolan appears to be a typographical error. Please verify if it should be renamed (perhaps to something like optionalBoolean or removed if unintended).
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
4. apps/web/preload/dist/index.js:17234
  • Draft comment:
    Typo: The property name onumber seems off. Please check if this is a misspelling or if it should be renamed appropriately (e.g., optionalNumber).
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 0% vs. threshold = 50% The comment is not about a change made in this diff; it is about a property that is simply being re-exported. There is no evidence that 'onumber' is a typo, and it is a known export in zod. The comment is not actionable and does not require a code change. According to the rules, comments about unchanged code or non-issues should be deleted. I could be missing some context about the naming conventions in this codebase, but based on the diff and knowledge of zod, 'onumber' is intentional. If the codebase has a different convention, that would not be evident from this diff alone. Given the information in the diff and standard zod exports, there is no reason to believe 'onumber' is a typo or needs to be changed. The comment is not relevant to the changes made in this diff. The comment should be deleted because it is not about a change made in this diff and is not a valid issue. 'onumber' is a known export from zod and not a typo.
5. apps/web/preload/dist/index.js:17236
  • Draft comment:
    Typo: The property name ostring looks like it might be a typo. Confirm if this should be corrected (for example, to optionalString).
  • Reason this comment was not posted:
    Comment looked like it was already resolved.

Workflow ID: wflow_BxM8GRb0BYUsi3o4

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@Kitenite
Copy link
Contributor

Kitenite commented Jun 6, 2025

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

@Rish-it
Copy link
Contributor Author

Rish-it commented Jun 7, 2025

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?

@Kitenite
Copy link
Contributor

Kitenite commented Jun 7, 2025

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?

@Rish-it
Copy link
Contributor Author

Rish-it commented Jun 7, 2025

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?

@Kitenite
Copy link
Contributor

Kitenite commented Jun 7, 2025

Sounds great, excited to see it!

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

Successfully merging this pull request may close these issues.

[bug] Cannot insert line break in text element using Enter, Ctrl+Enter, or Command+Enter
2 participants