HubSpot / draft-convert

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

Custom content blocks are being flattened #86

Closed TheMcMurder closed 6 years ago

TheMcMurder commented 7 years ago

I'm really sorry about this. I'm at a total loss here. The closest I've come to finding a resolution to this is here.

I am trying to convert

<div class="signature">
  <p>Emperor Palpatine</p>
  <p>Lord of the Sith</p>
  <p>Totally framed the Jedi</p>
</div>

into a single content block, but when I try to convert it I end up with what is essentially

<div class="signature">Emperor Palpatine</div>
<p>Lord of the Sith</p>
<p>Totally framed the Jedi</p>

I feel like I'm missing something incredibly simple here. I recreated it outside of my application here in this webpackbin

benbriggs commented 7 years ago

Thanks for submitting an issue! I think the issue revolves around how you're hoping to represent the single block. A block has a single string of text for content, so in order to have separate lines within it you'll need to use \n's to separate each line within the string. I think your example is getting caught up because draft-convert hits each separate block level element and doesn't know that you're hoping for those to all be part of the same block, so in order to maintain each element being on its own line it splits it out into a separate block. There might be a way to better handle this in draft-convert while maintaining inline editability (more on this later) but that currently doesn't exist.

Alternatively, if instead the text were separated by <br> tags (which more clearly implies that each line is just a part of the parent block), then I think you'd end up with the result you're looking for.

Draft out of the box doesn't work well with nested block elements that remain natively editable. In fact, in our internal implementation of a signature block like this we make it an atomic block that renders as read-only inline in the editor but can be clicked on to be edited in a separate UI, which then updates the block metadata to include the result.

Hope this makes sense, let me know if you have any more questions!

TheMcMurder commented 7 years ago

That totally makes sense. It sounds like what I'm trying to do isn't normal and slightly against the grain of how Draft is designed to work. I'm still pretty new to Draft so it's been a bit of an adventure trying to figure out how to do this.

To clarify you're suggesting a different flow where instead of having the signature editable inline, make it editable in a separate modal/editor/whatever, and read-only the rest of the time. Is that correct?

With regards to the solution. Because I'm still new to Draft and it's design principles I'm wondering if my original goal would be possible if I instead used an entity. I assumed that blocks could contain blocks but based on your answer that isn't correct. So the question becomes can entities contain blocks without nesting editors?

TheMcMurder commented 7 years ago

Also... I want to add a big thank you for your time. Open source can be a thankless job. Thank you.

benbriggs commented 7 years ago

😄 i appreciate it!

instead of having the signature editable inline, make it editable in a separate modal/editor/whatever, and read-only the rest of the time. Is that correct?

yup!

can entities contain blocks without nesting editors?

not to my knowledge - i believe Draft makes an assumption that any entity decoration in the editor a) does not modify the actual text being rendered within its range and b) that it remains inline.

you might run into these assumptions if you try adding a decorator with a component rendering anything other than this.props.children within it - selection gets messed up. i imagine the same thing would happen with a block-level entity. however i haven't actually tried it myself so it may be worth giving it a shot!

benbriggs commented 6 years ago

going to close this in the name of housekeeping since i hope i pointed you in the right direction and it ended up being more around what the general strategy for representing that type of content rather than a specific draft-convert issue. feel free to reopen if you have any related issues still outstanding