HubSpot / draft-convert

Extensibly serialize & deserialize Draft.js ContentState with HTML.
Apache License 2.0
484 stars 94 forks source link

Single line break should not be converted to paragraph #83

Closed lucadegasperi closed 6 years ago

lucadegasperi commented 7 years ago

Hello, I've just installed this converter and I've found an issue. How do I prevent single line breaks to being turned into new paragraphs?

Right now writing

Example Text\n
Second Line

gets turned into

<p>Example Text</p><p>Second Line</p>

whereas the result I expect should be

<p>Example Text<br>Second Line</p>

Two consecutive line breaks instead should be turned into a new paragraph.

Any ideas on how I could achieve this?

jonzlin95 commented 7 years ago

This should be the default behaviour. However DraftJS out of the box doesn't ship with
handling of newlines like you'd expect. The default is a new paragraph (which mirrors Microsoft Word etc.). Try this in your Editor

  handleReturn(e) {
    const { editorState } = this.state;
    if (e.shiftKey) {
      this.setState({ editorState: RichUtils.insertSoftNewline(editorState) });
      return 'handled';
    }
    return 'not-handled';
  }

<Editor
    handleReturn={this.handleReturn}
/>
bengotow commented 6 years ago

Just stumbled on this myself—I see what you're saying... in the DraftJS editor, the default return behavior inserts a new unstyled block, and DraftJS-convert wraps each unstyled block in a <p> tag when converting to HTML.

I think the root of the problem is that DraftJS blocks have no intrinsic spacing / padding between them, but <p> tags do. It seems to me like wrapping blocks in <div> elements would produce the correct behavior -

Original Problem (<p> Tags):

image

Potential Fix (<div> Tags):

image

I'm sure there are good reasons <p> tags are used in DraftJS-convert, just need to stumble around breaking things a bit more to see why ;-)

jonzlin95 commented 6 years ago

@bengotow spacing can be controlled by CSS, but P tags offer some things that div tags don’t, such as better handling by scrapers, apple’s reader mode, and text to speech etc. I think the default makes sense (since the editor is probably being used for some core text part of the page), but you can set your own defaults to

bengotow commented 6 years ago

Hey — thanks, that makes a lot of sense. I'm using DraftJS-convert in the Mailspring email client so I probably have unusual goals—basically need to get HTML that exactly visually matches what the user typed so the editor seems WYSWIG. Here's the config I ended up using which (at least so far) seems to maintain whitespace reliably and still be read back into DraftJS correctly via convertFromHTML:

    blockToHTML: block => {
      switch (block.type) {
        case 'unstyled':
          if (block.text === ' ' || block.text === '') return <br />;
          return <div />;
        case 'paragraph':
          return <p />;
        case 'header-one':
          return <h1 />;
....
image
benbriggs commented 6 years ago

going to close this as it looks like it's resolved - thank you @jonzlin95 for jumping in!