Settings

Theme

React Draft Wysiwyg

jpuri.github.io

168 points by jyotipuri 9 years ago · 44 comments

Reader

ianstormtaylor 9 years ago

This is great! I agree that I think this kind of editor composing is the way forward for most content editing on the web.

I was deep into Draft a while back, and there are some downsides to it though. It's document model is flat, which makes it hard to model nested structures like tables, captions, etc. It also treats a lot of the built-in logic in privileged ways which makes it hard to override and add custom logic. And generally the API and docs are fairly convoluted to use and understand.

If anyone is interested in composing complex editors in React/Immutable, you might be interested in a library I've been working on called Slate:

https://github.com/ianstormtaylor/slate

Unlike most of the other editors, its goal is to not have opinions out of the box. If you're going for just basic WYSIWYG then it's probably not for you, but if you're trying for more advanced editing experiences I think that flexibility is critical.

Anyways, awesome work! I just wanted to add another perspective.

  • thatswrong0 9 years ago

    Slate looks awesome. I wish I had seen it when I was looking for a replacement for our core rich text editor library.. although I probably would still have gone with Draft merely because of the Facebook support. Should they stop updating it, I know what ship I'll be jumping to. It looks like the concepts are similar enough that porting wouldn't be too painful.

    I've built and am maintaining a rich text editor that is a lot like Gmail's except it also supports dynamic variables, snippet insertion, and a few other things like that. Nested content hasn't been a concern for me, so DraftJS has been pleasant for the most part. Using Immutable for core state makes my life so much easier.

    But I do agree with your assessment that Draft's API and docs are lacking, and some of the design decisions are a bit odd. Doing relatively simple operations can require quite a few more steps than you would expect, meaning I had to implement a lot of helpers (that you think would be included) myself. Slate's Transform API looks a lot more capable and straightforward out of the box.

    HTML serialization, something you would expect to be part of the core library, only has a half-assed implementation that isn't customizable and that doesn't handle anything more than anchor tags.. so you have to install a third-party library to do it.

    Just one question: if you can have nested blocks, do you really even need marks? Are they just there for convenience?

    • ianstormtaylor 9 years ago

      Thanks! I totally agree with you, those were some of the other limitations I ran into and tried to solve for.

      > If you can have nested blocks, do you really even need marks? Are they just there for convenience?

      Interesting question!

      It depends slightly on your use case, but I think for most of the "rich text editing" use cases, you'll probably want them.

      They're beneficial in that they have separate semantics to inline nodes in the tree, since they aren't nested. Such that you can apply them in any order, and the JSON data structure is the same. This is useful because you don't have to worry about ordering when doing things like bold(italic(strikethrough(comment(TEXT)))). Which is usually simpler for users to understand, and simpler to work with in code anyways.

      The inline nodes are only really useful for what you'd model in HTML as `display: inline-block`, for things that aren't really running "text" but can appear in the middle of the document, like inline images, latex, etc.

      But if you're able to avoid inline nodes altogether, it's easiest to model things as blocks and marks.

      This has me thinking about whether it's possible to get rid of "inline" nodes though, that's interesting.

  • jmfurlott 9 years ago

    How does Slate compare to draft in package size? I find that including Draft for simple simple simple WYSIWYG editing to be enormous. I don't have the exact size on me, but it made my bundle huuge

    • ianstormtaylor 9 years ago

      Honestly right now it's probably worse. It's still in beta, so I've been working on the core architecture and logic, before diving into things like package size. So I'm not sure. It also hugely depends on whether you were already using React and Immutable.js as dependencies inside your app, or whether you have to add them just for the editor.

      For super simple WYSIWYG editing, like I mentioned, you're not going to want to use Slate. (Or maybe Draft either.)

      Slate is designed for much more advanced use cases. Things like building wiki tools, or chat tools, or anything where the editing experience itself is a significant enough portion of your product that you want total control over it, and don't want to be constrained by the opinions that most editing frameworks bake into their core libraries.

  • jyotipuriOP 9 years ago

    Thanks, Slate looks good - great work. Thanks for useful feedbacks. I will check slate more deeply soon.

Rezo 9 years ago

I don't think the toolbar actions work as one would usually expect. That is, hit Bold, type, text should be bold but isn't. The tools only seem to apply if there's already a selection, but that's not how vanilla Draft or any editor I can think of works.

anilgulecha 9 years ago

[EDIT: Just for reference, the title originally was 'the right way to content manage..']

I'd maybe call this "an" approach, rather than the 'right' approach :)

Already, prosemirror has provided a solid alternative, with things like custom-schemas, which ensure we're no longer in contenteditable-copy/paste hell. There's substance.io and quilljs as well.

Any of these could be the right approach for a particular CMS problem.

  • ingenter 9 years ago

    I just came here to write that I think this is THE right approach for wysiwyg editor. Having a full model of the document tree rather and working from that rather than sanitizing `contenteditable`. I expect this approach to automatically solve many problems that other wysiwyg editors have.

    • benbriggs 9 years ago

      I like and use Draft, but the separation of a document model from contenteditable is a feature of the editor frameworks mentioned above (as well as others like slate) and is not unique to Draft, or this implementation of an editor around Draft.

    • amelius 9 years ago

      Prosemirror still uses contenteditable under the hood though. I actually wonder why that is the case.

      • grayrest 9 years ago

        It handles the more complex (e.g. CJK) input methods. The alternative is a hidden text field and you have to put more effort into emulating the cursor (e.g. up arrow/down arrow). Regularly re-generating the underlying markup removes a large class of edge cases and cross-browser incompatibilities in exchange for not being able to use the browser's native undo. It's still a lot harder than you'd expect but it seems to be working for draft and prosemirror better than my attempt to normalize the cross browser differences and rely on the browser.

        P.S. I also came into this thread to endorse Prosemirror.

      • ingenter 9 years ago

        To be fair "React Draft Wysiwyg" is using contenteditable too, but it also builds a full model of the document.

    • jyotipuriOP 9 years ago

      Thanks your your insightful feedback.

  • tluyben2 9 years ago

    Mostly the 'right approach' depends a lot on the scale of the site(s) you are managing with it when it comes to a CMS. You really start missing forced structure even with a few content managers, let alone 100s of content managers copy/pasting stuff all over the place.

  • jyotipuriOP 9 years ago

    Hi Anil,

    I did not said only right approach :)

jackreichert 9 years ago

I love these initiatives. It does, though, need thorough testing in an office environment. Things that users, not developers, will come out. For example, I tried cutting and pasting from Word. Forget about formatting, none of the line breaks carried over. That's not to discount this. It'll be great in certain settings, but it has far to mature if it's goal is to compete with tinyMCE.

galacticpony 9 years ago

No offense, but it feels junky, just like most web stuff that's trying to do "real" application UI.

Here's some of the problems:

- You can accidentally "select" the text of the buttons

- changing the style of the text causes selection to flicker

- clicking outside a paragraph area causes the selection to flicker (instead of moving the cursor)

- many of the menus don't collapse automatically and they overlap each other

- the site layout just breaks when the page width is too narrow (may be more of a website problem)

All of these are very common problems with web technology, working around them makes the difference between "good" and "acceptable".

  • dismantlethesun 9 years ago

    In case anyone is reading this. You can solve #1 with CSS3, using "user-select: none;".

    It's something I don't often see added to buttons, but it is a huge benefit for any app-like layout.

theweatherman 9 years ago

I've done a some investigation into this, and I can tell you while this looks cool. It'd be difficult to use on other devices (tablets, phones). The best I've seen is https://www.froala.com/wysiwyg-editor Killer feature is the fact that I can use it on the iPad, Android tablet, IE, and Chrome. Also, its supports tables, which was one of the requirements for our clients. Licensing is pretty affordable, and it's easy to integrate because there are plugins available for different frameworks (angular, django, ...)

wahnfrieden 9 years ago

Please note that Draft.js lacks "inline blocks": there's no way to, for example, have an image rendered inline rather than as its own block. I lost hours to this non-obvious omission so maybe this will save someone else time :)

I've been using https://github.com/ianstormtaylor/slate instead, which uses a similar architecture but has inline blocks. It's not quite as fully-baked as Draft.js yet though.

kilburn 9 years ago

I tried it in firefox mobile. After inputting the first letter the cursor jumped behind it.

I tried to reposition the cursor to no avail (the whole edit area loses and regains focus on each tap).

Also, I can't delete stuff (backspace does nothing).

Edit: at this point I just quit trying.

dawnerd 9 years ago

Doesn't seem to be working on mobile. iOS 10

Ronsenshi 9 years ago

Looks very nice, thanks for the work.

I've been tinkering with Draft off and on for quite some time and I love how powerful it is, however documentation was rather lacking in some areas and this project would definitely help me understand some of the things about Draft.

Too bad there's still only a workaround for block styles (as in setting "style" prop on a whole block instead of using setBlockData method).

  • ianstormtaylor 9 years ago

    Just in case you're interested, I ran into the same issues with Draft when using it myself—having to do lots of strange workarounds for what felt like normal levels of customization. I've been working on an alternative that aims to be much less opinionated and with a much cleaner API, called Slate:

    https://github.com/ianstormtaylor/slate

  • jyotipuriOP 9 years ago

    I hope I would find more time, I wanna do more on DraftJS and its approach for content editing. Its very powerful approach.

tyingq 9 years ago

Looks nice.

Not sure if this is a bug, but if I set a specific font size, it doesn't attach any kind of unit. For example, if I select 18, it doesn't convert that to 18px or 18em...just "18":

<span style="font-size: 18;">This is some text.</span>

I believe that's not valid css.

xmattx 9 years ago

Just a few random observations: I can't seem to toggle off bold/italic/...? Neither can it be toggled on before typing it seems. Also, setting text alignment removes bullets.

Nice idea, but functionally not quite there yet.

pugio 9 years ago

Does anyone else notice a tiny typing lag? I can't point to it, but whenever I type with a delayed response it feels as though I'm slogging through muddy ground, an almost subliminal sensation.

  • Touche 9 years ago

    Yeah, I do, slightly.

    A more noticeable thing is that if you select some text and then Bold / Italics / Underscore, etc. there is a flash where the text appears to be no selected and then becomes selected again.

    Given this is React, my guess of what is going on is that the rich text is redrawn when these buttons are pressed (and perhaps even on each keystroke) and the selection has to be re-applied in code.

    Perhaps they can improve this, but this is why I think it's important to stay away from high level frameworks for doing low-level things like text editing. Use your high level framework for application architecture and all that good stuff, but when something has to be fast, drop down to the lowest level you have.

  • Ronsenshi 9 years ago

    Can't say I notice it.

rekshaw 9 years ago

Nice! p.s. indent buttons don't work (on Firefox)

Robin_f 9 years ago

This looks really good. I'm only missing an option to put in formatted code or something.

rkuykendall-com 9 years ago

Anyone know a modern editor that can handle editing HTML implemented using an iframe so there's no CSS leak?

I want to be able to render email templates and let clients tweak them before they gets sent. Currently trying to get Froala to work with webpack.

manigandham 9 years ago

Running list of html/wysiwyg editors: https://gist.github.com/manigandham/65543a0bc2bf7006a487

MWil 9 years ago

Since you can't tab or you lose focus of the editor box, I am pressing the "add indent" button but to no avail

Edit: Someone beat me to it, but being 2/6 of the early comments shows that they are important!

amelius 9 years ago

One important thing seems to be missing though: collaborative editing.

(A requirement on the modern web, since you don't want to edit a file only to find out that your version was overwritten by another person who happened to be editing at the same time).

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection